From 08a79d0e7b609d5ce26477b10570af2733f184e0 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Thu, 7 Apr 2016 15:54:47 +0200 Subject: [PATCH] several bug fixes regarding "content is an array" --- src/Connectors/Test.js | 2 +- src/Database.js | 16 ++++++++------- src/SpecHelper.js | 4 ++-- src/Struct.js | 24 +++++++++++++---------- src/Transaction.js | 44 +++++++++++++++++++++++++++++++----------- 5 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/Connectors/Test.js b/src/Connectors/Test.js index 2f95a0d7..1a04b330 100644 --- a/src/Connectors/Test.js +++ b/src/Connectors/Test.js @@ -4,7 +4,7 @@ module.exports = function (Y) { var globalRoom = { users: {}, - buffers: {}, + buffers: {}, // TODO: reimplement this idea. This does not cover all cases!! Here, you have a queue which is unrealistic (i.e. think about multiple incoming connections) removeUser: function (user) { for (var i in this.users) { this.users[i].userLeft(user) diff --git a/src/Database.js b/src/Database.js index 540f6629..e830b955 100644 --- a/src/Database.js +++ b/src/Database.js @@ -146,8 +146,10 @@ module.exports = function (Y /* :any */) { self.gc2 = [] for (var i = 0; i < ungc.length; i++) { var op = yield* this.getOperation(ungc[i]) - delete op.gc - yield* this.setOperation(op) + if (op != null) { + delete op.gc + yield* this.setOperation(op) + } } resolve() }) @@ -386,11 +388,11 @@ module.exports = function (Y /* :any */) { let o = Y.utils.copyObject(op) yield* t._changed(transaction, o) } - // Delete if DS says this is actually deleted - var len = op.content != null ? op.content.length : 1 - for (var i = 0; i < len; i++) { - var id = [op.id[0], op.id[1] + i] - if (!op.deleted) { + if (!op.deleted) { + // Delete if DS says this is actually deleted + var len = op.content != null ? op.content.length : 1 + for (var i = 0; i < len; i++) { + var id = [op.id[0], op.id[1] + i] var opIsDeleted = yield* transaction.isDeleted(id) if (opIsDeleted) { var delop = { diff --git a/src/SpecHelper.js b/src/SpecHelper.js index 303153c1..682bf99e 100644 --- a/src/SpecHelper.js +++ b/src/SpecHelper.js @@ -25,7 +25,7 @@ g.g = g g.YConcurrency_TestingMode = true -jasmine.DEFAULT_TIMEOUT_INTERVAL = 2000 +jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000 g.describeManyTimes = function describeManyTimes (times, name, f) { for (var i = 0; i < times; i++) { @@ -200,7 +200,7 @@ g.compareAllUsers = async(function * compareAllUsers (users) { for (var j in ds) { var d = ds[j] for (var i = 0; i < d.len; i++) { - var o = yield* this.getOperation([d.id[0], d.id[1] + i]) + var o = yield* this.getInsertion([d.id[0], d.id[1] + i]) // gc'd or deleted if (d.gc) { expect(o).toBeFalsy() diff --git a/src/Struct.js b/src/Struct.js index 2ca4d6a3..0bffeb65 100644 --- a/src/Struct.js +++ b/src/Struct.js @@ -68,7 +68,7 @@ module.exports = function (Y/* :any */) { if (op.hasOwnProperty('opContent')) { e.opContent = op.opContent } else { - e.content = op.content + e.content = op.content.slice() } return e @@ -93,17 +93,21 @@ module.exports = function (Y/* :any */) { return ids }, getDistanceToOrigin: function * (op) { - var d = 0 - var o = op - while (!Y.utils.matchesId(o, op.origin)) { - d++ - if (o.left == null) { - break - } else { - o = yield* this.getInsertion(o.left) + if (op.left == null) { + return 0 + } else { + var d = 0 + var o = yield* this.getInsertion(op.left) + while (!Y.utils.matchesId(o, op.origin)) { + d++ + if (o.left == null) { + break + } else { + o = yield* this.getInsertion(o.left) + } } + return d } - return d }, /* # $this has to find a unique position between origin and the next known character diff --git a/src/Transaction.js b/src/Transaction.js index 99c37702..659a949a 100644 --- a/src/Transaction.js +++ b/src/Transaction.js @@ -160,12 +160,20 @@ module.exports = function (Y/* :any */) { start.gc = true start.deleted = true yield* this.setOperation(start) - yield* this.markDeleted(start.id, 1) + var delLength = start.content != null ? start.content.length : 1 + yield* this.markDeleted(start.id, delLength) if (start.opContent != null) { yield* this.deleteOperation(start.opContent) } if (this.store.y.connector.isSynced) { this.store.gc1.push(start.id) + for (var i = 0; i < delLength; i++) { + if (i === 0) { + this.store.gc1.push(start.id) + } else { + this.store.gc1.push([start.id[0], start.id[1] + i]) + } + } } } start = start.right @@ -386,15 +394,22 @@ module.exports = function (Y/* :any */) { */ * garbageCollectAfterSync () { yield* this.os.iterate(this, null, null, function * (op) { + var opLength = op.content != null ? op.content.length : 1 if (op.gc) { - this.store.gc1.push(op.id) + for (var i = 0; i < opLength; i++) { + if (i === 0) { + this.store.gc1.push(op.id) + } else { + this.store.gc1.push([op.id[0], op.id[1] + i]) + } + } } else { if (op.parent != null) { var parentDeleted = yield* this.isDeleted(op.parent) if (parentDeleted) { op.gc = true if (!op.deleted) { - yield* this.markDeleted(op.id, 1) + yield* this.markDeleted(op.id, delLength) op.deleted = true if (op.opContent != null) { yield* this.deleteOperation(op.opContent) @@ -412,7 +427,13 @@ module.exports = function (Y/* :any */) { } } yield* this.setOperation(op) - this.store.gc1.push(op.id) + for (var i = 0; i < opLength; i++) { + if (i === 0) { + this.store.gc1.push(op.id) + } else { + this.store.gc1.push([op.id[0], op.id[1] + i]) + } + } return } } @@ -753,11 +774,15 @@ module.exports = function (Y/* :any */) { } * getInsertion (id) { var ins = yield* this.os.findWithUpperBound(id) - var len = ins.content != null ? ins.content.length : 1 // in case of opContent - if (ins != null && id[0] === ins.id[0] && id[1] < ins.id[1] + len) { - return ins - } else { + if (ins == null) { return null + } else { + var len = ins.content != null ? ins.content.length : 1 // in case of opContent + if (id[0] === ins.id[0] && id[1] < ins.id[1] + len) { + return ins + } else { + return null + } } } * getInsertionCleanStartEnd (id) { @@ -815,9 +840,6 @@ module.exports = function (Y/* :any */) { } } * getOperation (id/* :any */)/* :Transaction */ { - if (id.length > 2) { - id = [id[0], id[1]] - } var o = yield* this.os.find(id) if (id[0] !== '_' || o != null) { return o