diff --git a/.eslintrc b/.eslintrc index 0f0dfcec..f1f99bd4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -36,6 +36,7 @@ "applyRandomTransactions": true, "CustomType": true, "window": true, - "document": true + "document": true, + "smaller": true } } diff --git a/src/Connector.js b/src/Connector.js index 2a7489ee..b42f1123 100644 --- a/src/Connector.js +++ b/src/Connector.js @@ -149,8 +149,8 @@ class AbstractConnector { //eslint-disable-line no-unused-vars let conn = this; this.y.db.requestTransaction(function*(){ var ops = yield* this.getOperations(m.stateVector); + conn.broadcastedHB = true; if (ops.length > 0) { - conn.broadcastedHB = true; conn.broadcast({ type: "update", ops: ops diff --git a/src/OperationStores/RedBlackTree.js b/src/OperationStores/RedBlackTree.js index c3f01292..5f60db17 100644 --- a/src/OperationStores/RedBlackTree.js +++ b/src/OperationStores/RedBlackTree.js @@ -113,6 +113,9 @@ class RBTree { //eslint-disable-line no-unused-vars this.length = 0; } findNodeWithLowerBound (from) { + if (from === void 0) { + throw new Error("You must define from!"); + } var o = this.root; if (o === null) { return false; @@ -122,7 +125,7 @@ class RBTree { //eslint-disable-line no-unused-vars // o is included in the bound // try to find an element that is closer to the bound o = o.left; - } else if (smaller(o.val.id, from)) { + } else if (from !== null && smaller(o.val.id, from)) { // o is not within the bound, maybe one of the right elements is.. if (o.right !== null) { o = o.right; @@ -149,6 +152,9 @@ class RBTree { //eslint-disable-line no-unused-vars return this.findNode(id).val; } findNode (id) { + if (id == null || id.constructor !== Array) { + throw new Error("Expect id to be an array!"); + } var o = this.root; if (o === null) { return false; @@ -168,6 +174,9 @@ class RBTree { //eslint-disable-line no-unused-vars } } delete (id) { + if (id == null || id.constructor !== Array) { + throw new Error("id is expected to be an Array!"); + } var d = this.findNode(id); if (d == null) { throw new Error("Element does not exist!"); @@ -307,6 +316,9 @@ class RBTree { //eslint-disable-line no-unused-vars } } add (v) { + if (v == null || v.id == null || v.id.constructor !== Array) { + throw new Error("v is expected to have an id property which is an Array!"); + } var node = new N(v); if (this.root !== null) { var p = this.root; // p abbrev. parent diff --git a/src/OperationStores/RedBlackTree.spec.js b/src/OperationStores/RedBlackTree.spec.js index 750d1ed6..6183b3af 100644 --- a/src/OperationStores/RedBlackTree.spec.js +++ b/src/OperationStores/RedBlackTree.spec.js @@ -54,56 +54,56 @@ describe("RedBlack Tree", function(){ this.tree = new RBTree(); }); it("can add&retrieve 5 elements", function(){ - this.tree.add({val: "four", id: 4}); - this.tree.add({val: "one", id: 1}); - this.tree.add({val: "three", id: 3}); - this.tree.add({val: "two", id: 2}); - this.tree.add({val: "five", id: 5}); - expect(this.tree.find(1).val).toEqual("one"); - expect(this.tree.find(2).val).toEqual("two"); - expect(this.tree.find(3).val).toEqual("three"); - expect(this.tree.find(4).val).toEqual("four"); - expect(this.tree.find(5).val).toEqual("five"); + this.tree.add({val: "four", id: [4]}); + this.tree.add({val: "one", id: [1]}); + this.tree.add({val: "three", id: [3]}); + this.tree.add({val: "two", id: [2]}); + this.tree.add({val: "five", id: [5]}); + expect(this.tree.find([1]).val).toEqual("one"); + expect(this.tree.find([2]).val).toEqual("two"); + expect(this.tree.find([3]).val).toEqual("three"); + expect(this.tree.find([4]).val).toEqual("four"); + expect(this.tree.find([5]).val).toEqual("five"); }); it("5 elements do not exist anymore after deleting them", function(){ - this.tree.add({val: "four", id: 4}); - this.tree.add({val: "one", id: 1}); - this.tree.add({val: "three", id: 3}); - this.tree.add({val: "two", id: 2}); - this.tree.add({val: "five", id: 5}); - this.tree.delete(4); - expect(this.tree.find(4)).not.toBeTruthy(); - this.tree.delete(3); - expect(this.tree.find(3)).not.toBeTruthy(); - this.tree.delete(2); - expect(this.tree.find(2)).not.toBeTruthy(); - this.tree.delete(1); - expect(this.tree.find(1)).not.toBeTruthy(); - this.tree.delete(5); - expect(this.tree.find(5)).not.toBeTruthy(); + this.tree.add({val: "four", id: [4]}); + this.tree.add({val: "one", id: [1]}); + this.tree.add({val: "three", id: [3]}); + this.tree.add({val: "two", id: [2]}); + this.tree.add({val: "five", id: [5]}); + this.tree.delete([4]); + expect(this.tree.find([4])).not.toBeTruthy(); + this.tree.delete([3]); + expect(this.tree.find([3])).not.toBeTruthy(); + this.tree.delete([2]); + expect(this.tree.find([2])).not.toBeTruthy(); + this.tree.delete([1]); + expect(this.tree.find([1])).not.toBeTruthy(); + this.tree.delete([5]); + expect(this.tree.find([5])).not.toBeTruthy(); }); it("debug #1", function(){ - this.tree.add({id: 2}); - this.tree.add({id: 0}); - this.tree.delete(2); - this.tree.add({id: 1}); - expect(this.tree.find(0)).not.toBeUndefined(); - expect(this.tree.find(1)).not.toBeUndefined(); - expect(this.tree.find(2)).toBeUndefined(); + this.tree.add({id: [2]}); + this.tree.add({id: [0]}); + this.tree.delete([2]); + this.tree.add({id: [1]}); + expect(this.tree.find([0])).not.toBeUndefined(); + expect(this.tree.find([1])).not.toBeUndefined(); + expect(this.tree.find([2])).toBeUndefined(); }); describe("debug #2", function(){ var tree = new RBTree(); - tree.add({id: 8433}); - tree.add({id: 12844}); - tree.add({id: 1795}); - tree.add({id: 30302}); - tree.add({id: 64287}); - tree.delete(8433); - tree.add({id: 28996}); - tree.delete(64287); - tree.add({id: 22721}); + tree.add({id: [8433]}); + tree.add({id: [12844]}); + tree.add({id: [1795]}); + tree.add({id: [30302]}); + tree.add({id: [64287]}); + tree.delete([8433]); + tree.add({id: [28996]}); + tree.delete([64287]); + tree.add({id: [22721]}); itRootNodeIsBlack(tree, []); itBlackHeightOfSubTreesAreEqual(tree, []); @@ -115,13 +115,13 @@ describe("RedBlack Tree", function(){ for(var i = 0; i < numberOfRBTreeTests; i++) { var r = Math.random(); if (r < 0.8) { - var obj = Math.floor(Math.random() * numberOfRBTreeTests * 10000); + var obj = [Math.floor(Math.random() * numberOfRBTreeTests * 10000)]; elements.push(obj); tree.add({id: obj}); } else if (elements.length > 0) { var elemid = Math.floor(Math.random() * elements.length); var elem = elements[elemid]; - elements = elements.filter(function(e){return e != elem; }); //eslint-disable-line + elements = elements.filter(function(e){return !compareIds(e,elem); }); //eslint-disable-line tree.delete(elem); } } @@ -145,7 +145,7 @@ describe("RedBlack Tree", function(){ it("iterating over a tree with lower bound yields the right amount of results", function(){ var lowerBound = elements[Math.floor(Math.random() * elements.length)]; var expectedResults = elements.filter(function(e, pos){ - return e >= lowerBound && elements.indexOf(e) === pos; + return (smaller(lowerBound, e) || compareIds(e, lowerBound)) && elements.indexOf(e) === pos; }).length; var actualResults = 0; @@ -172,7 +172,7 @@ describe("RedBlack Tree", function(){ it("iterating over a tree with upper bound yields the right amount of results", function(){ var upperBound = elements[Math.floor(Math.random() * elements.length)]; var expectedResults = elements.filter(function(e, pos){ - return e <= upperBound && elements.indexOf(e) === pos; + return (smaller(e, upperBound) || compareIds(e, upperBound)) && elements.indexOf(e) === pos; }).length; var actualResults = 0; @@ -187,7 +187,7 @@ describe("RedBlack Tree", function(){ var b1 = elements[Math.floor(Math.random() * elements.length)]; var b2 = elements[Math.floor(Math.random() * elements.length)]; var upperBound, lowerBound; - if (b1 < b2) { + if (smaller(b1, b2)) { lowerBound = b1; upperBound = b2; } else { @@ -195,7 +195,8 @@ describe("RedBlack Tree", function(){ upperBound = b1; } var expectedResults = elements.filter(function(e, pos){ - return e >= lowerBound && e <= upperBound && elements.indexOf(e) === pos; + return (smaller(lowerBound, e) || compareIds(e, lowerBound)) + && (smaller(e, upperBound) || compareIds(e, upperBound)) && elements.indexOf(e) === pos; }).length; var actualResults = 0; tree.iterate(lowerBound, upperBound, function(val){