itclocks
Version:
An implementation of Interval Tree Clocks in TypeScript
105 lines (104 loc) • 4.08 kB
JavaScript
"use strict";
/**
* 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 Occurrence_1 = require("./Occurrence");
const Occurrences_1 = require("./Occurrences");
class NonLeafOccurrence extends Occurrence_1.Occurrence {
constructor(value, left, right) {
super();
this.value = value;
this.left = left;
this.right = right;
}
max() {
let max = Math.max(this.left.max(), this.right.max());
return this.value + max;
}
min() {
let min = Math.min(this.left.min(), this.right.min());
return this.value + min;
}
maxDepth(depth) {
let leftDepth = this.left.maxDepth(depth + 1);
let rightDepth = this.right.maxDepth(depth + 1);
return Math.max(leftDepth, rightDepth);
}
isLeaf() {
return false;
}
lift(m) {
return Occurrences_1.Occurrences.with(this.value + m, this.left, this.right);
}
sink(m) {
return Occurrences_1.Occurrences.with(this.value - m, this.left, this.right);
}
normalize() {
if (this.left.isLeaf() && this.right.isLeaf() && this.left.value == this.right.value)
return Occurrences_1.Occurrences.with(this.value + this.left.value);
let min = Math.min(this.left.min(), this.right.min());
return Occurrences_1.Occurrences.with(this.value + min, this.left.sink(min), this.right.sink(min));
}
leq(other) {
if (other.isLeaf())
return this.leqLeaf(other);
return this.leqNonLeafs(other);
}
leqLeaf(other) {
return this.value <= other.value && this.liftedLeft(this).leq(other) && this.liftedRight(this).leq(other);
}
liftedLeft(occurrence) {
return occurrence.left.lift(occurrence.value);
}
liftedRight(occurrence) {
return occurrence.right.lift(occurrence.value);
}
leqNonLeafs(other) {
return this.value <= other.value && this.liftedLeft(this).leq(this.liftedLeft(other)) && this.liftedRight(this).leq(this.liftedRight(other));
}
join(other) {
if (other.isLeaf())
return this.join(Occurrences_1.Occurrences.with(other.value, Occurrences_1.Occurrences.zero(), Occurrences_1.Occurrences.zero()));
return this.joinNonLeaf(other);
}
joinNonLeaf(other) {
if (this.value > other.value)
return other.join(this);
let join = Occurrences_1.Occurrences.with(this.value, this.leftJoin(other), this.rightJoin(other));
return join.normalize();
}
leftJoin(other) {
let otherLiftedLeft = other.left.lift(other.value - this.value);
return this.left.join(otherLiftedLeft);
}
rightJoin(other) {
let otherLiftedRight = other.right.lift(other.value - this.value);
return this.right.join(otherLiftedRight);
}
equals(object) {
if (!(object instanceof NonLeafOccurrence))
return false;
let other = object;
return this.value == other.value &&
this.left.equals(other.left) &&
this.right.equals(other.right);
}
toString() {
return "(" + this.value + ", " + this.left + ", " + this.right + ")";
}
}
exports.NonLeafOccurrence = NonLeafOccurrence;