diff --git a/src/Databases/Memory.js b/src/Databases/Memory.js index 7b2de91e..ed3c0d0a 100644 --- a/src/Databases/Memory.js +++ b/src/Databases/Memory.js @@ -22,17 +22,26 @@ Y.Memory = (function () { } logTable () { var self = this - return new Promise(function (resolve) { - self.requestTransaction(function * () { - console.log('User: ', this.store.y.connector.userId, "==============================") // eslint-disable-line - console.log("State Set (SS):", this.ss) // eslint-disable-line - console.log("Operation Store (OS):") // eslint-disable-line - yield* this.os.logTable() // eslint-disable-line - console.log("Deletion Store (DS):") //eslint-disable-line - yield* this.ds.logTable() // eslint-disable-line - resolve() - }, true) - }) + self.requestTransaction(function * () { + console.log('User: ', this.store.y.connector.userId, "==============================") // eslint-disable-line + console.log("State Set (SS):", yield* this.getStateSet()) // eslint-disable-line + console.log("Operation Store (OS):") // eslint-disable-line + yield* this.os.logTable() // eslint-disable-line + console.log("Deletion Store (DS):") //eslint-disable-line + yield* this.ds.logTable() // eslint-disable-line + if (this.store.gc1.length > 0 || this.store.gc2.length > 0) { + console.warn('GC1|2 not empty!', this.store.gc1, this.store.gc2) + } + if (JSON.stringify(this.store.listenersById) !== '{}') { + console.warn('listenersById not empty!') + } + if (JSON.stringify(this.store.listenersByIdExecuteNow) !== '[]') { + console.warn('listenersByIdExecuteNow not empty!') + } + if (this.store.transactionInProgress) { + console.warn('Transaction still in progress!') + } + }, true) } transact (makeGen) { var t = new Transaction(this) diff --git a/src/Databases/RedBlackTree.js b/src/Databases/RedBlackTree.js index 3aebe4b8..ee80dc7a 100644 --- a/src/Databases/RedBlackTree.js +++ b/src/Databases/RedBlackTree.js @@ -131,10 +131,12 @@ class RBTree { this.length = 0 } * findNext (id) { - return yield* this.findNodeWithLowerBound([id[0], id[1] + 1]) + var n = yield* this.findNodeWithLowerBound([id[0], id[1] + 1]) + return n == null ? null : n.val } * findPrev (id) { - return yield* this.findNodeWithUpperBound([id[0], id[1] - 1]) + var n = yield* this.findNodeWithUpperBound([id[0], id[1] - 1]) + return n == null ? null : n.val } * findNodeWithLowerBound (from) { if (from === void 0) { diff --git a/src/Helper.spec.js b/src/Helper.spec.js index b350975c..d5cd7238 100644 --- a/src/Helper.spec.js +++ b/src/Helper.spec.js @@ -18,7 +18,7 @@ g.g = g g.YConcurrency_TestingMode = true -jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000 +jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000 g.describeManyTimes = function describeManyTimes (times, name, f) { for (var i = 0; i < times; i++) { @@ -154,6 +154,7 @@ g.compareAllUsers = async(function * compareAllUsers (users) { }) } yield users[0].connector.flushAll() + yield wait() yield g.garbageCollectAllUsers(users) for (var uid = 0; uid < users.length; uid++) { diff --git a/src/Transaction.js b/src/Transaction.js index 3e37f449..7f147a90 100644 --- a/src/Transaction.js +++ b/src/Transaction.js @@ -195,42 +195,47 @@ class Transaction { * markGarbageCollected (id) { // this.mem.push(["gc", id]); var n = yield* this.markDeleted(id) - if (!n.val.gc) { - if (n.val.id[1] < id[1]) { + if (!n.gc) { + if (n.id[1] < id[1]) { // un-extend left - var newlen = n.val.len - (id[1] - n.val.id[1]) - n.val.len -= newlen + var newlen = n.len - (id[1] - n.id[1]) + n.len -= newlen + yield* this.ds.put(n) n = yield* this.ds.put({id: id, len: newlen, gc: false}) + n = n.val } // get prev&next before adding a new operation - var prev = n.prev() - var next = n.next() - if (id[1] < n.val.id[1] + n.val.len - 1) { + var prev = yield* this.ds.findPrev(id) + var next = yield* this.ds.findNext(id) + + if (id[1] < n.id[1] + n.len - 1) { // un-extend right - yield* this.ds.put({id: [id[0], id[1] + 1], len: n.val.len - 1, gc: false}) - n.val.len = 1 + yield* this.ds.put({id: [id[0], id[1] + 1], len: n.len - 1, gc: false}) + n.len = 1 } // set gc'd - n.val.gc = true + n.gc = true // can extend left? if ( prev != null && - prev.val.gc && - Y.utils.compareIds([prev.val.id[0], prev.val.id[1] + prev.val.len], n.val.id) + prev.gc && + Y.utils.compareIds([prev.id[0], prev.id[1] + prev.len], n.id) ) { - prev.val.len += n.val.len - yield* this.ds.delete(n.val.id) + prev.len += n.len + yield* this.ds.delete(n.id) n = prev + // ds.put n here? } // can extend right? if ( next != null && - next.val.gc && - Y.utils.compareIds([n.val.id[0], n.val.id[1] + n.val.len], next.val.id) + next.gc && + Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id) ) { - n.val.len += next.val.len - yield* this.ds.delete(next.val.id) + n.len += next.len + yield* this.ds.delete(next.id) } + yield* this.ds.put(n) } } /* @@ -241,34 +246,36 @@ class Transaction { * markDeleted (id) { // this.mem.push(["del", id]); var n = yield* this.ds.findNodeWithUpperBound(id) - if (n != null && n.val.id[0] === id[0]) { - if (n.val.id[1] <= id[1] && id[1] < n.val.id[1] + n.val.len) { + n = n == null ? n : n.val + if (n != null && n.id[0] === id[0]) { + if (n.id[1] <= id[1] && id[1] < n.id[1] + n.len) { // already deleted return n - } else if (n.val.id[1] + n.val.len === id[1] && !n.val.gc) { + } else if (n.id[1] + n.len === id[1] && !n.gc) { // can extend existing deletion - n.val.len++ + n.len++ } else { // cannot extend left n = yield* this.ds.put({id: id, len: 1, gc: false}) + n = n.val } } else { // cannot extend left n = yield* this.ds.put({id: id, len: 1, gc: false}) + n = n.val } // can extend right? - var next = n.next() + var next = yield* this.ds.findNext(n.id) if ( - next !== null && - Y.utils.compareIds([n.val.id[0], n.val.id[1] + n.val.len], next.val.id) && - !next.val.gc + next != null && + Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id) && + !next.gc ) { - n.val.len = n.val.len + next.val.len - yield* this.ds.delete(next.val.id) - return this.ds.findNode(n.val.id) - } else { - return n + n.len = n.len + next.len + yield* this.ds.delete(next.id) } + yield* this.ds.put(n) + return n } /* Call this method when the client is connected&synced with the diff --git a/src/Types/Array.spec.js b/src/Types/Array.spec.js index 7f909565..ebf5a190 100644 --- a/src/Types/Array.spec.js +++ b/src/Types/Array.spec.js @@ -1,7 +1,7 @@ /* global createUsers, wait, Y, compareAllUsers, getRandomNumber, applyRandomTransactionsAllRejoinNoGC, applyRandomTransactionsWithGC, async, garbageCollectAllUsers, describeManyTimes */ /* eslint-env browser,jasmine */ -var numberOfYArrayTests = 200 +var numberOfYArrayTests = 40 var repeatArrayTests = 1 describe('Array Type', function () { @@ -187,7 +187,6 @@ describe('Array Type', function () { l3 = yield y3.get('Array') yield flushAll() yield garbageCollectAllUsers(this.users) - yconfig1.db.logTable() expect(l1.toArray()).toEqual(l2.toArray()) expect(l2.toArray()).toEqual(l3.toArray()) expect(l2.toArray()).toEqual([]) diff --git a/src/Types/Map.spec.js b/src/Types/Map.spec.js index f36f6712..245292d6 100644 --- a/src/Types/Map.spec.js +++ b/src/Types/Map.spec.js @@ -1,7 +1,7 @@ /* global createUsers, Y, compareAllUsers, getRandomNumber, applyRandomTransactionsAllRejoinNoGC, applyRandomTransactionsWithGC, async, describeManyTimes */ /* eslint-env browser,jasmine */ -var numberOfYMapTests = 10 +var numberOfYMapTests = 40 var repeatMapTeasts = 1 describe('Map Type', function () {