From 420821be31aadfea608c3720c145f106d2377f3f Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Fri, 24 Jul 2015 22:24:49 +0200 Subject: [PATCH] continuing DeleteStore --- src/OperationStores/Memory.js | 97 +++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 10 deletions(-) diff --git a/src/OperationStores/Memory.js b/src/OperationStores/Memory.js index ec142b4c..7d66b6d8 100644 --- a/src/OperationStores/Memory.js +++ b/src/OperationStores/Memory.js @@ -12,21 +12,98 @@ class DeletionStore { // eslint-disable-line constructor () { this.ds = {} } - deleteId (id) { - var dv = this.db[id[0]] - if (dv === void 0) { - dv = [] - this.db[id[0]] = dv - } - for (var i in dv) { - if (dv[i].pos <= id[1] && id[1] < dv[i].pos + length) { - // within the bound, already deleted + delete (id) { + var n = this.findNodeWithUpperBound(id) + if (n != null && n.val.id[0] === id[0]) { + if (n.val.id[1] === id[1]) { + // already deleted return + } else if (n.val.id[1] + n.val.length === id[1]) { + // can extend existing deletion + n.val.length++ } else { - + // cannot extend left + n = this.add({id: id, length: 1}) } + } else { + // cannot extend left + n = this.add({id: id, length: 1}) + } + var next = n.next() + if compareIds([n.val.id[0], n.val.id[1] + n.val.length], next.val.id) { + n.val.length += next.val.length + this.delete(next.val.id) } } + // a DeleteSet (ds) describes all the deleted ops in the OS + toDeleteSet () { + var ds = {} + this.iterate(null, null, function (n) { + var user = n.val.id[0] + var counter = n.val.id[1] + var length = n.val.length + var dv = ds[user] + if (dv === void 0) { + dv = [] + ds[user] = dv + } + dv.push([counter, length]) + }) + // returns a set of deletions that need to be applied in order to get to + // the state of the supplied ds + getDeletions (ds) { + var deletions = [] + function createDeletions (user, start, length) { + for (var c = start; c < start + length; c++) { + deletions.push({ + target: [user, c], + struct: 'Delete' + }) + } + } + for (var user in ds) { + var dv = ds[user] + var pos = 0 + var d = dv[pos] + this.iterate([user, 0], [user, Number.MAX_VALUE], function (n) { + // cases: + // 1. d deletes something to the right of n + // => go to next n (break) + // 2. d deletes something to the left of n + // => create deletions + // => reset d accordingly + // *)=> if d doesn't delete anything anymore, go to next d (continue) + // 3. not 2) and d deletes something that also n deletes + // => reset d so that it doesn't contain n's deletion + // *)=> if d does not delete anything anymore, go to next d (continue) + while (d != null) { + var diff // describe the diff of length in 1) and 2) + if (n.val.id[1] + n.val.length <= d[0]) { + // 1) + break + } else if (d[0] < n.val.id[1]) { + // 2) + // delete maximum the length of d + // else delete as much as possible + diff = Math.min(n.val.id[1]-d[0], d[1]) + createDeletions(user, d[0], diff) + } else { + // 3) + diff = n.val.id[1] + n.val.length - d[0] // never null (see 1) + } + if (d[1] <= diff) { + // d doesn't delete anything anymore + d = dv[++pos] + } else { + d[0] = d[0] + diff // reset pos + d[1] = d[1] - diff // reset length + } + } + }) + } + this.iterater() + + } } Y.Memory = (function () { // eslint-disable-line no-unused-vars