diff --git a/src/list/List.js b/src/list/List.js new file mode 100644 index 0000000..fbf8736 --- /dev/null +++ b/src/list/List.js @@ -0,0 +1,88 @@ +'use strict'; + +const _ = require('lodash'); +const Node = require('./Node'); + +class List { + constructor(id) { + this.id = id; + this.seq = 0; + this.ver = 0; + this._items = []; + this._currentBatch = []; + } + + get items() { + return this._items.concat(this._currentBatch); + } + + add(data) { + const heads = this._findHeads(this.items); + const node = new Node(this.id, this.seq, this.ver, data, heads); + this._currentBatch.push(node); + this.ver ++; + } + + join(other) { + if(other.seq && other.seq > this.seq) { + this.seq = other.seq + 1; + this.ver = 0; + } else { + this.seq = this.seq + 1; + this.ver = 0; + } + const current = _.differenceWith(this._currentBatch, this._items, this._equals); + const others = _.differenceWith(other.items, this._items, this._equals); + const final = _.unionWith(current, others, this._equals); + this._items = this._items.concat(final); + this._currentBatch = []; + } + + _findHeads(list) { + const grouped = _.groupBy(list, 'id'); + const heads = Object.keys(grouped).map((g) => _.last(grouped[g])); + const cleaned = heads.filter((e) => !this._isReferencedInChain(list, e)); + return cleaned; + } + + _isReferencedInChain(all, item) { + let isReferenced = _.findLast(all, (e) => this._references(e, item)) !== undefined; + return isReferenced; + } + + _equals(a, b) { + return a.id == b.id && a.seq == b.seq && a.ver == b.ver; + } + + _references(a, b) { + for(let i = 0; i < a.next.length; i ++) { + if(b.compactId === a.next[i]) + return true; + } + return false; + } + + static fromJson(json) { + let list = new List(json.id); + list.seq = json.seq; + list.ver = json.ver; + list._items = _.uniqWith(json.items.map((f) => new Node(f.id, f.seq, f.ver, f.data, f.next)), _.isEqual); + return list; + } + + toJson() { + return { + id: this.id, + seq: this.seq, + ver: this.ver, + items: this._currentBatch.map((f) => f.compact()) + } + } + + toString() { + const items = this.items.map((f) => JSON.stringify(f.compact())).join("\n"); + return `id: ${this.id}, seq: ${this.seq}, ver: ${this.ver}, items:\n${items}`; + } +} + +module.exports = List; diff --git a/src/list/Node.js b/src/list/Node.js new file mode 100644 index 0000000..aa0544f --- /dev/null +++ b/src/list/Node.js @@ -0,0 +1,21 @@ +'use strict'; + +class Node { + constructor(id, seq, ver, data, next) { + this.id = id; + this.seq = seq; + this.ver = ver; + this.data = data || null; + this.next = next ? next.map((f) => f.compactId ? f.compactId : f) : []; + } + + get compactId() { + return "" + this.id + "." + this.seq + "." + this.ver; + } + + compact() { + return { id: this.id, seq: this.seq, ver: this.ver, data: this.data, next: this.next } + } +} + +module.exports = Node; diff --git a/test/list-node-tests.js b/test/list-node-tests.js new file mode 100644 index 0000000..f0ad641 --- /dev/null +++ b/test/list-node-tests.js @@ -0,0 +1,61 @@ +'use strict'; + +const assert = require('assert'); +const List = require('../src/list/List'); +const Node = require('../src/list/Node'); + +describe('Node', () => { + describe('Constructor', () => { + it('initializes member variables', (done) => { + const node = new Node('A', 0, 0, 'hello', []); + assert.equal(node.id, 'A'); + assert.equal(node.seq, 0); + assert.equal(node.ver, 0); + assert.equal(node.data, 'hello'); + assert.equal(node.next instanceof Array, true); + done(); + }); + + it('initializes member variables without specified data and next', (done) => { + const node = new Node('A', 0, 0); + assert.equal(node.id, 'A'); + assert.equal(node.seq, 0); + assert.equal(node.ver, 0); + assert.equal(node.data, null); + assert.equal(node.next instanceof Array, true); + done(); + }); + }); + + describe('compactId', () => { + it('presents the node as a string with id, sequence and version', (done) => { + const node1 = new Node('A', 0, 0); + const node2 = new Node('B', 123, 456); + assert.equal(node1.compactId, 'A.0.0'); + assert.equal(node2.compactId, 'B.123.456'); + done(); + }); + }); + + describe('compact', () => { + it('presents the node as a compacted object', (done) => { + const node1 = new Node('A', 0, 0, 'hello'); + const node2 = new Node('B', 0, 0, 'hello', [node1]); + const compacted1 = node1.compact(); + const compacted2 = node2.compact(); + + assert.notEqual(compacted1, null); + assert.equal(compacted1.id, 'A'); + assert.equal(compacted1.seq, 0); + assert.equal(compacted1.ver, 0); + assert.equal(compacted1.data, 'hello'); + assert.equal(compacted1.next instanceof Array, true); + assert.equal(compacted1.next.length, 0); + + assert.equal(compacted2.id, 'B'); + assert.equal(compacted2.next.length, 1); + assert.equal(compacted2.next[0], 'A.0.0'); + done(); + }); + }); +}); diff --git a/test/list-perf-tests.js b/test/list-perf-tests.js index 50431a8..43e97bc 100644 --- a/test/list-perf-tests.js +++ b/test/list-perf-tests.js @@ -3,8 +3,7 @@ // var assert = require('assert'); // var async = require('asyncawait/async'); // var await = require('asyncawait/await'); -// var List = require('../test1').List; -// var Node = require('../test1').Node; +// var List = require('../src/list/List'); // var Timer = require('../examples/Timer'); // describe('List - Performance Measurement', function() { @@ -23,8 +22,6 @@ // ms = timer.stop(true); // console.log(` > ${t} took ${ms} ms`) - -// // assert.equal(ms < t, true); // } // assert.equal(true, true); diff --git a/test/list-tests.js b/test/list-tests.js index bdbe3b3..46bfc46 100644 --- a/test/list-tests.js +++ b/test/list-tests.js @@ -1,66 +1,8 @@ 'use strict'; +const _ = require('lodash'); var assert = require('assert'); -var async = require('asyncawait/async'); -var await = require('asyncawait/await'); -var List = require('../test1').List; -var Node = require('../test1').Node; - -describe('Node', () => { - describe('Constructor', () => { - it('initializes member variables', (done) => { - const node = new Node('A', 0, 0, 'hello', []); - assert.equal(node.id, 'A'); - assert.equal(node.seq, 0); - assert.equal(node.ver, 0); - assert.equal(node.data, 'hello'); - assert.equal(node.next instanceof Array, true); - done(); - }); - - it('initializes member variables without data and next', (done) => { - const node = new Node('A', 0, 0); - assert.equal(node.id, 'A'); - assert.equal(node.seq, 0); - assert.equal(node.ver, 0); - assert.equal(node.data, null); - assert.equal(node.next instanceof Array, true); - done(); - }); - }); - - describe('compactId', () => { - it('presents the node as a string with id, sequence and version', (done) => { - const node1 = new Node('A', 0, 0); - const node2 = new Node('B', 123, 456); - assert.equal(node1.compactId, 'A.0.0'); - assert.equal(node2.compactId, 'B.123.456'); - done(); - }); - }); - - describe('compact', () => { - it('presents the node as a compacted object', (done) => { - const node1 = new Node('A', 0, 0, 'hello'); - const node2 = new Node('B', 0, 0, 'hello', [node1]); - const compacted1 = node1.compact(); - const compacted2 = node2.compact(); - - assert.notEqual(compacted1, null); - assert.equal(compacted1.id, 'A'); - assert.equal(compacted1.seq, 0); - assert.equal(compacted1.ver, 0); - assert.equal(compacted1.data, 'hello'); - assert.equal(compacted1.next instanceof Array, true); - assert.equal(compacted1.next.length, 0); - - assert.equal(compacted2.id, 'B'); - assert.equal(compacted2.next.length, 1); - assert.equal(compacted2.next[0], 'A.0.0'); - done(); - }); - }); -}); +var List = require('../src/list/List'); describe('List', () => { describe('Constructor', () => { @@ -77,6 +19,60 @@ describe('List', () => { }); }); + describe('fromJson', () => { + it('creates a list from parsed json', (done) => { + const list = new List('A'); + list.add("hello1") + list.add("hello2") + list.add("hello3") + const str = JSON.stringify(list.toJson()) + const res = List.fromJson(JSON.parse(str)); + assert.equal(res.id, 'A'); + assert.equal(res.seq, 0); + assert.equal(res.ver, 3); + assert.equal(res.items.length, 3); + assert.equal(res.items[0].compactId, 'A.0.0'); + assert.equal(res.items[1].compactId, 'A.0.1'); + assert.equal(res.items[2].compactId, 'A.0.2'); + done(); + }); + }); + + describe('toJson', () => { + it('presents the list as json', (done) => { + const list = new List('A'); + list.add("hello1") + list.add("hello2") + list.add("hello3") + const json = list.toJson(); + const expected = { + id: 'A', + seq: 0, + ver: 3, + items: [ + { id: 'A', seq: 0, ver: 0, data: 'hello1', next: [] }, + { id: 'A', seq: 0, ver: 1, data: 'hello2', next: ['A.0.0'] }, + { id: 'A', seq: 0, ver: 2, data: 'hello3', next: ['A.0.1'] } + ] + }; + assert.equal(_.isEqual(json, expected), true); + done(); + }); + }); + + describe('toString', () => { + it('presents the list as a string', (done) => { + const list = new List('A'); + list.add("hello1") + list.add("hello2") + list.add("hello3") + const str = list.toString(); + const expected = `id: A, seq: 0, ver: 3, items:\n{"id":"A","seq":0,"ver":0,"data":"hello1","next":[]}\n{"id":"A","seq":0,"ver":1,"data":"hello2","next":["A.0.0"]}\n{"id":"A","seq":0,"ver":2,"data":"hello3","next":["A.0.1"]}`; + assert.equal(str, expected); + done(); + }); + }); + describe('items', () => { it('returns items', (done) => { const list = new List('A'); @@ -99,10 +95,8 @@ describe('List', () => { list.add("hello1") list.add("hello2") list.add("hello3") - // list.add("hello4") - // list.add("hello5") + let compacted = list.toJson(); - // console.log(compacted) assert.equal(compacted.id, 'A'); assert.equal(compacted.seq, 0); assert.equal(compacted.ver, 3); @@ -210,14 +204,13 @@ describe('List', () => { list1.add("helloA2") list1.add("helloA3") - // console.log(list1.toString()) assert.equal(list1._currentBatch.length, 3); assert.equal(list1._currentBatch[2].next.length, 1); assert.equal(list1._currentBatch[2].next[0], 'A.0.1'); done(); }); - it('finds the next heads after joining a list with another', (done) => { + it('finds the next heads (two) after a join', (done) => { const list1 = new List('A'); const list2 = new List('B'); list1.add("helloA1") @@ -233,7 +226,7 @@ describe('List', () => { done(); }); - it('finds the next head after a two-way join', (done) => { + it('finds the next head (one) after a join', (done) => { const list1 = new List('A'); const list2 = new List('B'); list1.add("helloA1") @@ -250,7 +243,7 @@ describe('List', () => { done(); }); - it('find sthe next heads after join two-way join', (done) => { + it('finds the next heads after two joins', (done) => { const list1 = new List('A'); const list2 = new List('B'); list1.add("helloA1") @@ -267,13 +260,49 @@ describe('List', () => { list1.add("helloA5") const lastItem = list1.items[list1.items.length - 1]; - // console.log(list1.toString()) + assert.equal(list1.items.length, 7); assert.equal(lastItem.next.length, 1); assert.equal(lastItem.next[0], 'A.2.0'); done(); }); + it('finds the next heads after multiple joins', (done) => { + const list1 = new List('A'); + const list2 = new List('B'); + const list3 = new List('C'); + const list4 = new List('D'); + list1.add("helloA1") + list1.add("helloA2") + list2.add("helloB1") + list2.add("helloB2") + list1.join(list2); + + list3.add("helloC1") + list4.add("helloD1") + list1.join(list3); + + list1.add("helloA3") + list2.join(list1); + list1.join(list2); + list2.join(list4); + + list4.add("helloD2") + list4.add("helloD3") + list1.add("helloA4") + list1.join(list4); + + list1.add("helloA5") + + const lastItem = list1.items[list1.items.length - 1]; + + assert.equal(list1.items.length, 11); + assert.equal(lastItem.next.length, 2); + assert.equal(lastItem.next[0], 'A.4.0'); + assert.equal(lastItem.next[1], 'D.0.2'); + done(); + }); + it('joins list of one item with list of two items', (done) => { const list1 = new List('A'); const list2 = new List('B'); @@ -282,18 +311,17 @@ describe('List', () => { list2.add("helloB2") list1.join(list2); - // console.log(list1) - // console.log(list2) + const lastItem = list1.items[list1.items.length - 1]; assert.equal(list1.id, 'A'); assert.equal(list1.seq, 1); assert.equal(list1.ver, 0); assert.equal(list1._currentBatch.length, 0); assert.equal(list1._items.length, 3); - assert.equal(list1._items[list1._items.length - 1].id, 'B'); - assert.equal(list1._items[list1._items.length - 1].seq, 0); - assert.equal(list1._items[list1._items.length - 1].ver, 1); - assert.equal(list1._items[list1._items.length - 1].data, 'helloB2'); + assert.equal(lastItem.id, 'B'); + assert.equal(lastItem.seq, 0); + assert.equal(lastItem.ver, 1); + assert.equal(lastItem.data, 'helloB2'); done(); }); @@ -307,25 +335,29 @@ describe('List', () => { list1.join(list2); list2.join(list1); + const lastItem1 = list1.items[list1.items.length - 1]; + assert.equal(list1.id, 'A'); assert.equal(list1.seq, 1); assert.equal(list1.ver, 0); assert.equal(list1._currentBatch.length, 0); assert.equal(list1._items.length, 4); - assert.equal(list1._items[list1._items.length - 1].id, 'B'); - assert.equal(list1._items[list1._items.length - 1].seq, 0); - assert.equal(list1._items[list1._items.length - 1].ver, 1); - assert.equal(list1._items[list1._items.length - 1].data, 'helloB2'); + assert.equal(lastItem1.id, 'B'); + assert.equal(lastItem1.seq, 0); + assert.equal(lastItem1.ver, 1); + assert.equal(lastItem1.data, 'helloB2'); + + const lastItem2 = list2.items[list2.items.length - 1]; assert.equal(list2.id, 'B'); assert.equal(list2.seq, 2); assert.equal(list2.ver, 0); assert.equal(list2._currentBatch.length, 0); assert.equal(list2._items.length, 4); - assert.equal(list2._items[list2._items.length - 1].id, 'A'); - assert.equal(list2._items[list2._items.length - 1].seq, 0); - assert.equal(list2._items[list2._items.length - 1].ver, 1); - assert.equal(list2._items[list2._items.length - 1].data, 'helloA2'); + assert.equal(lastItem2.id, 'A'); + assert.equal(lastItem2.seq, 0); + assert.equal(lastItem2.ver, 1); + assert.equal(lastItem2.data, 'helloA2'); done(); }); @@ -341,23 +373,26 @@ describe('List', () => { list2.add("helloB2") list2.join(list1); + const secondItem = list2.items[1]; + const lastItem = list2.items[list2.items.length - 1]; + assert.equal(list2.id, 'B'); assert.equal(list2.seq, 2); assert.equal(list2.ver, 0); assert.equal(list2._currentBatch.length, 0); assert.equal(list2._items.length, 4); - assert.equal(list2._items[1].id, 'A'); - assert.equal(list2._items[1].seq, 0); - assert.equal(list2._items[1].ver, 0); - assert.equal(list2._items[1].data, 'helloA1'); - assert.equal(list2._items[list2._items.length - 1].id, 'A'); - assert.equal(list2._items[list2._items.length - 1].seq, 0); - assert.equal(list2._items[list2._items.length - 1].ver, 1); - assert.equal(list2._items[list2._items.length - 1].data, 'helloA2'); + assert.equal(secondItem.id, 'A'); + assert.equal(secondItem.seq, 0); + assert.equal(secondItem.ver, 0); + assert.equal(secondItem.data, 'helloA1'); + assert.equal(lastItem.id, 'A'); + assert.equal(lastItem.seq, 0); + assert.equal(lastItem.ver, 1); + assert.equal(lastItem.data, 'helloA2'); done(); }); - it('joins 4 lists', (done) => { + it('joins 4 lists to one', (done) => { const list1 = new List('A'); const list2 = new List('B'); const list3 = new List('C'); @@ -365,39 +400,36 @@ describe('List', () => { list1.add("helloA1") list2.add("helloB1") - // list2.join(list1); - list1.add("helloA2") list2.add("helloB2") - // list2.join(list1); - list3.add("helloC1") list4.add("helloD1") - // list2.join(list1); - list3.add("helloC2") list4.add("helloD2") list1.join(list2); list1.join(list3); list1.join(list4); + const secondItem = list1.items[1]; + const lastItem = list1.items[list1.items.length - 1]; + assert.equal(list1.id, 'A'); - // assert.equal(list1.seq, 1); - // assert.equal(list1.ver, 1); + assert.equal(list1.seq, 3); + assert.equal(list1.ver, 0); assert.equal(list1._currentBatch.length, 0); assert.equal(list1._items.length, 8); - assert.equal(list1._items[1].id, 'A'); - assert.equal(list1._items[1].seq, 0); - assert.equal(list1._items[1].ver, 1); - assert.equal(list1._items[1].data, 'helloA2'); - assert.equal(list1._items[list1._items.length - 1].id, 'D'); - assert.equal(list1._items[list1._items.length - 1].seq, 0); - assert.equal(list1._items[list1._items.length - 1].ver, 1); - assert.equal(list1._items[list1._items.length - 1].data, 'helloD2'); + assert.equal(secondItem.id, 'A'); + assert.equal(secondItem.seq, 0); + assert.equal(secondItem.ver, 1); + assert.equal(secondItem.data, 'helloA2'); + assert.equal(lastItem.id, 'D'); + assert.equal(lastItem.seq, 0); + assert.equal(lastItem.ver, 1); + assert.equal(lastItem.data, 'helloD2'); done(); }); - it('joins 4 lists sequentally', (done) => { + it('joins lists from 4 lists', (done) => { const list1 = new List('A'); const list2 = new List('B'); const list3 = new List('C'); @@ -428,31 +460,42 @@ describe('List', () => { list4.add("helloD3") list4.add("helloD4") - // console.log(list4.toString()); + const secondItem = list4.items[1]; + const lastItem1 = list4._items[list4._items.length - 1]; + const lastItem2 = list4.items[list4.items.length - 1]; + assert.equal(list4.id, 'D'); assert.equal(list4.seq, 7); assert.equal(list4.ver, 2); assert.equal(list4._currentBatch.length, 2); assert.equal(list4._items.length, 8); - assert.equal(list4._items[1].id, 'D'); - assert.equal(list4._items[1].seq, 0); - assert.equal(list4._items[1].ver, 1); - assert.equal(list4._items[1].data, 'helloD2'); - assert.equal(list4._items[list1._items.length - 1].id, 'A'); - assert.equal(list4._items[list1._items.length - 1].seq, 1); - assert.equal(list4._items[list1._items.length - 1].ver, 0); - assert.equal(list4._items[list1._items.length - 1].data, 'helloA2'); - assert.equal(list4.items[list4.items.length - 1].id, 'D'); - assert.equal(list4.items[list4.items.length - 1].seq, 7); - assert.equal(list4.items[list4.items.length - 1].ver, 1); - assert.equal(list4.items[list4.items.length - 1].data, 'helloD4'); + assert.equal(secondItem.id, 'D'); + assert.equal(secondItem.seq, 0); + assert.equal(secondItem.ver, 1); + assert.equal(secondItem.data, 'helloD2'); + assert.equal(lastItem1.id, 'C'); + assert.equal(lastItem1.seq, 3); + assert.equal(lastItem1.ver, 1); + assert.equal(lastItem1.data, 'helloC2'); + assert.equal(lastItem2.id, 'D'); + assert.equal(lastItem2.seq, 7); + assert.equal(lastItem2.ver, 1); + assert.equal(lastItem2.data, 'helloD4'); done(); }); }); - it('solves a graph', (done) => { - done(); + describe('_findHeads', () => { + it('TODO', (done) => { + done(); + }); + }); + + describe('_isReferencedInChain', () => { + it('TODO', (done) => { + done(); + }); }); }); diff --git a/test1.js b/test1.js index 5c6d04a..1cff702 100644 --- a/test1.js +++ b/test1.js @@ -2,268 +2,8 @@ const _ = require('lodash'); const Timer = require('./examples/Timer'); - -Array.prototype.allEqual = function(val) { - for(var i = 1; i < this.length; i++) { - if(this[i] !== val || this[i] !== this[0]) - return false; - } - return true; -} - -if (!Array.prototype.last){ - Array.prototype.last = function(){ - return this[this.length - 1]; - }; -} - -class Node { - constructor(id, seq, ver, data, next) { - this.id = id; - this.seq = seq; - this.ver = ver; - this.data = data || null; - this.next = next ? next.map((f) => f.compactId ? f.compactId : f) : []; - } - - get compactId() { - return "" + this.id + "." + this.seq + "." + this.ver; - } - - compact() { - return { id: this.id, seq: this.seq, ver: this.ver, data: this.data, next: this.next } - // return { id: this.id, seq: this.seq, ver: this.ver, data: this.data, next: this.next.map((f) => f.compactId) } - } - - // static parseCompact(t) { - // let v = t.split('.'); - // return { id: v[0], seq: parseInt(v[1]), ver: parseInt(v[2]) }; - // } - -} - -class List { - constructor(id) { - this.id = id; - this.seq = 0; - this.ver = 0; - this._items = []; - this._currentBatch = []; - this._referenced = []; - } - - static fromJson(json) { - let list = new List(json.id); - list.seq = json.seq; - list.ver = json.ver; - // list._items = json.items.map((f) => new Node(f.id, f.seq, f.ver, f.data, f.next)); - list._items = _.uniqWith(json.items.map((f) => { - // console.log(JSON.stringify(f.next, null, 2)); - return new Node(f.id, f.seq, f.ver, f.data, f.next); - }), _.isEqual); - return list; - } - - get items() { - return this._items.concat(this._currentBatch); - } - - toJson() { - return { - id: this.id, - seq: this.seq, - ver: this.ver, - items: this._currentBatch.map((f) => f.compact()) - } - } - - toString() { - const items = this.items.map((f) => JSON.stringify(f.compact())).join("\n"); - return ` - id: ${this.id}, - seq: ${this.seq}, - ver: ${this.ver}, - items: \n${items} - ` - } - - add(data) { - // var ii = this.items.map((f) => f.compact()); - // console.log("--->", this.seq, this.ver) - const heads = this._findHeads(this.items);//.map((f) => f.compact()); - // const heads = this._findHeads(this.items) - // console.log("jjjj", this._referenced, "\n\n") - // console.log("jjjj", this.items, "\n\n") - const node = new Node(this.id, this.seq, this.ver, data, heads); - // console.log("aaaa", node) - this._currentBatch.push(node); - // this._referenced.push(node); - this.ver ++; - } - - join(other) { - let ms; - - if(other.seq && other.seq > this.seq) { - this.seq = other.seq + 1; - this.ver = 0; - } else { - this.seq = this.seq + 1; - this.ver = 0; - } - // if(other.items.last() && other.items.last().seq > this.seq) { - // this.seq = other.seq + 1; - // this.ver = 0; - // } - - // return items that are only in this._currentBatch - const current = _.differenceWith(this._currentBatch, this._items, this._equals); - // return items that are only in other.items - - let timer = new Timer(true); - const others = _.differenceWith(other.items, this._items, this._equals); - ms = timer.stop(true); - // return unique items from e and d - // const final = _.unionWith(others, this._currentBatch, this._equals); - const final = _.unionWith(current, others, this._equals); - // append new items to all items - this._items = this._items.concat(final); - - this._currentBatch = []; - if(ms > 20) { - console.log("OVER 20MS!!", other.items.length) - console.log(`join took ${timer.stop(true)} ms`); - } - } - - _findHeads(list) { - let timer = new Timer(true); - let ms; - const grouped = _.groupBy(list, 'id'); - // const heads = Object.keys(grouped).sort((a, b) => a === this.id ? -1 : (a < b ? 1 : 0)).map((g) => grouped[g].last()); - const heads = Object.keys(grouped).map((g) => grouped[g].last()); - // const heads = _.differenceWith(list, this._referenced); - // console.log("HEADS", JSON.stringify(heads)); - // const cleaned = heads.filter((e) => !this._isReferencedInChain(list, e, this._referenced, 0)); - const cleaned = heads.filter((e) => !this._isReferencedInChain2(list, e)); - // const cleaned = heads; - // console.log("CLEANED", JSON.stringify(cleaned), "\n"); - // this._referenced = []; - ms = timer.stop(true); - if(ms > 20) { - console.log("OVER 20MS!!") - console.log(`_findHeads took ${ms} ms`); - } - // console.log(`_findHeads took ${ms} ms`); - return cleaned; - } - - - _isReferencedInChain2(all, item) { - // console.log("item:", item); - let isReferenced = all.find((e) => this._references(e, item)) !== undefined; - if(!isReferenced) { - // console.log("check children", item.next) - let childHasRef = item.next.map((f) => { - const next = all.find((e) => this._equals(e, f)); - const res = next ? this._isReferencedInChain2(all, next) : false; - return _.find(res, (e) => e === true) !== undefined; - }); - isReferenced = _.find(childHasRef, (e) => e === true) !== undefined; - // console.log("children have ref", isReferenced) - } - - // console.log("red:", isReferenced); - return isReferenced; - } - - // _parse(t) { - // let v = t.split('.'); - // return { id: v[0], seq: parseInt(v[1]), ver: parseInt(v[2]) }; - // } - - _equals(a, b) { - return a.id == b.id && a.seq == b.seq && a.ver == b.ver; - } - - _references(a, b) { - // return _.includes(a.next, b.compactId); - // faster than _.includes() - for(let i = 0; i < a.next.length; i ++) { - if(b.compactId === a.next[i]) return true; - } - return false; - } - -/* - _isReferencedInChain(all, item, next2, refs, depth) { - console.log("...item:", item); - depth += 1; - let timer = new Timer(true); - let ms; - - if(!item) - return false; - - // let isReferenced = refs.find((e) => e.id == item.id && e.seq == item.seq && e.ver == item.ver) !== undefined; - let isReferenced = refs.find((e) => this._equals(e, item)) !== undefined; - - if(isReferenced) - console.log("ref", item) - - if(isReferenced) - return true; - - // if(item.id == 'C' && item.seq == 3 && item.ver == 1) { - // console.log("!!!!", refs,"\n", item) - // } - refs.splice(0, 0, item); - - var check = (o) => { - const next = all.find((e) => this._equals(e, this._parse(o))); - if(!next) - return false; - - return this._isReferencedInChain(all, item, next, refs, depth); - }; - - // refs.push(item); - - // console.log(item.next); - // let res = item.next.map(this._parse).map(check); - let res = item.next.map(check); - - if(depth > 5) { - console.log("WTF!!!", depth, item, refs, res); - } - - // refs.splice(0, 0, item); - - // if(item.id == 'A' && item.seq == 0 && item.ver == 1) { - // console.log("????", isReferenced, refs, "\n\n", item, "\n\n", res) - // } - - // if(item.id == 'A' && item.seq == 1 && item.ver == 2) { - // console.log("+++", res) - // } - - // const hasRef2 = _.find(res, (e) => e === true) !== undefined; - // const hasRef2 = res.allEqual(true) - - ms = timer.stop(true); - if(ms > 20) { - console.log("OVER 20MS!!", refs.length) - console.log(`_isReferencedInChain took ${ms} ms`); - } - let hasRef2 = _.find(res, (e) => e === true) !== undefined; - // console.log("...res:", hasRef2, res); - // if(hasRef2) - // refs.splice(0, 0, item); - - return hasRef2; - } -*/ -} +const List = require('./src/list/List'); +// const Node = require('./src/list/Node'); var run = () => { var redis = require("redis"); @@ -282,18 +22,14 @@ var run = () => { const l = List.fromJson(JSON.parse(event)); // console.log("LIST", l); - // var l = List.fromJson(JSON.parse(event)); if(l.id === 'A') { listB.join(l); listC.join(l); - // console.log(listB); } else if(l.id === 'B') { listA.join(l); listC.join(l); - // console.log("ListA:", listA); } else if(l.id === 'C') { listA.join(l); - // console.log("LIST", event); console.log("Items:", listA.items.length); // console.log(JSON.stringify(listA, null, 1)); } @@ -303,11 +39,6 @@ var run = () => { this.client1.on("message", handleMessage); this.client2.on("message", handleMessage); - setInterval(() => { - // listC.join(listB); - // listC.join(listA); - }, 5000); - let h = 0; setInterval(() => { listC.add("C--"+h); @@ -318,12 +49,12 @@ var run = () => { let i = 0; setInterval(() => { let a = 0; - // for(let a = 0; a < 100; a ++) { + for(let a = 0; a < 10; a ++) { listB.add("B--"+(i+a)); - // } + } this.client2.publish(hash, JSON.stringify(listB.toJson())); i++; - }, 10); + }, 20); let k = 0; setInterval(() => { @@ -338,8 +69,3 @@ var run = () => { }; run(); - -module.exports = { - Node: Node, - List: List -};