continuing DeleteStore
This commit is contained in:
parent
d1fda080d9
commit
420821be31
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user