itclocks
Version:
An implementation of Interval Tree Clocks in TypeScript
80 lines (79 loc) • 3.54 kB
JavaScript
/**
* Copyright (C) 2017 Gabriel Batista Galli
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const GrowResult_1 = require("./GrowResult");
const Occurrences_1 = require("./Occurrences");
class Grower {
static grow(id, occurrence) {
return Grower.innerGrow(id, occurrence).occurrence;
}
static innerGrow(id, occurrence) {
if (id.isLeaf())
return Grower.growLeafID(id, occurrence);
return Grower.growNonLeafID(id, occurrence);
}
static growLeafID(id, occurrence) {
if (id.isOne() && occurrence.isLeaf())
return new GrowResult_1.GrowResult(Occurrences_1.Occurrences.with(occurrence.value + 1), 0);
throw new TypeError("Illegal arguments: " + id + " and " + occurrence);
}
static growNonLeafID(id, occurrence) {
if (occurrence.isLeaf())
return Grower.growLeafEvent(id, occurrence);
if (id.left.isZero())
return Grower.growOnRight(id, occurrence);
if (id.right.isZero())
return Grower.growOnLeft(id, occurrence);
return Grower.growOnBothSides(id, occurrence);
}
static growLeafEvent(id, occurrence) {
let er = Grower.innerGrow(id, Occurrences_1.Occurrences.with(occurrence.value, Occurrences_1.Occurrences.zero(), Occurrences_1.Occurrences.zero()));
er.cost = er.cost + occurrence.depth + 1;
return er;
}
static growOnRight(id, occurrence) {
let rightGrowth = Grower.growRight(id, occurrence);
return Grower.rightGrowth(occurrence, rightGrowth);
}
static growRight(id, occurrence) {
return Grower.innerGrow(id.right, occurrence.right);
}
static rightGrowth(occurrence, growth) {
let result = Occurrences_1.Occurrences.with(occurrence.value, occurrence.left, growth.occurrence);
return new GrowResult_1.GrowResult(result, growth.cost + 1);
}
static growOnLeft(id, occurrence) {
let leftGrowth = Grower.growLeft(id, occurrence);
return Grower.leftGrowth(occurrence, leftGrowth);
}
static growLeft(id, occurrence) {
return Grower.innerGrow(id.left, occurrence.left);
}
static leftGrowth(occurrence, growth) {
let result = Occurrences_1.Occurrences.with(occurrence.value, growth.occurrence, occurrence.right);
return new GrowResult_1.GrowResult(result, growth.cost + 1);
}
static growOnBothSides(id, occurrence) {
let leftGrowth = Grower.growLeft(id, occurrence);
let rightGrowth = Grower.growRight(id, occurrence);
if (leftGrowth.cost < rightGrowth.cost)
return Grower.leftGrowth(occurrence, leftGrowth);
return Grower.rightGrowth(occurrence, rightGrowth);
}
}
exports.Grower = Grower;
;