removed generators
This commit is contained in:
@@ -86,11 +86,11 @@ export default function extendTransaction (Y) {
|
||||
* does not check for Struct.*.requiredOps()
|
||||
* also broadcasts it through the connector
|
||||
*/
|
||||
* applyCreatedOperations (ops) {
|
||||
applyCreatedOperations (ops) {
|
||||
var send = []
|
||||
for (var i = 0; i < ops.length; i++) {
|
||||
var op = ops[i]
|
||||
yield * this.store.tryExecute.call(this, op)
|
||||
this.store.tryExecute.call(this, op)
|
||||
if (op.id == null || typeof op.id[1] !== 'string') {
|
||||
send.push(Y.Struct[op.struct].encode(op))
|
||||
}
|
||||
@@ -104,17 +104,17 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
}
|
||||
|
||||
* deleteList (start) {
|
||||
deleteList (start) {
|
||||
while (start != null) {
|
||||
start = yield * this.getOperation(start)
|
||||
start = this.getOperation(start)
|
||||
if (!start.gc) {
|
||||
start.gc = true
|
||||
start.deleted = true
|
||||
yield * this.setOperation(start)
|
||||
this.setOperation(start)
|
||||
var delLength = start.content != null ? start.content.length : 1
|
||||
yield * this.markDeleted(start.id, delLength)
|
||||
this.markDeleted(start.id, delLength)
|
||||
if (start.opContent != null) {
|
||||
yield * this.deleteOperation(start.opContent)
|
||||
this.deleteOperation(start.opContent)
|
||||
}
|
||||
this.store.queueGarbageCollector(start.id)
|
||||
}
|
||||
@@ -125,14 +125,14 @@ export default function extendTransaction (Y) {
|
||||
/*
|
||||
Mark an operation as deleted, and add it to the GC, if possible.
|
||||
*/
|
||||
* deleteOperation (targetId, length, preventCallType) /* :Generator<any, any, any> */ {
|
||||
deleteOperation (targetId, length, preventCallType) /* :Generator<any, any, any> */ {
|
||||
if (length == null) {
|
||||
length = 1
|
||||
}
|
||||
yield * this.markDeleted(targetId, length)
|
||||
this.markDeleted(targetId, length)
|
||||
while (length > 0) {
|
||||
var callType = false
|
||||
var target = yield * this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1])
|
||||
var target = this.os.findWithUpperBound([targetId[0], targetId[1] + length - 1])
|
||||
var targetLength = target != null && target.content != null ? target.content.length : 1
|
||||
if (target == null || target.id[0] !== targetId[0] || target.id[1] + targetLength <= targetId[1]) {
|
||||
// does not exist or is not in the range of the deletion
|
||||
@@ -143,12 +143,12 @@ export default function extendTransaction (Y) {
|
||||
if (!target.deleted) {
|
||||
if (target.id[1] < targetId[1]) {
|
||||
// starts to the left of the deletion range
|
||||
target = yield * this.getInsertionCleanStart(targetId)
|
||||
target = this.getInsertionCleanStart(targetId)
|
||||
targetLength = target.content.length // must have content property!
|
||||
}
|
||||
if (target.id[1] + targetLength > targetId[1] + length) {
|
||||
// ends to the right of the deletion range
|
||||
target = yield * this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1])
|
||||
target = this.getInsertionCleanEnd([targetId[0], targetId[1] + length - 1])
|
||||
targetLength = target.content.length
|
||||
}
|
||||
}
|
||||
@@ -163,35 +163,35 @@ export default function extendTransaction (Y) {
|
||||
// delete containing lists
|
||||
if (target.start != null) {
|
||||
// TODO: don't do it like this .. -.-
|
||||
yield * this.deleteList(target.start)
|
||||
// yield * this.deleteList(target.id) -- do not gc itself because this may still get referenced
|
||||
this.deleteList(target.start)
|
||||
// this.deleteList(target.id) -- do not gc itself because this may still get referenced
|
||||
}
|
||||
if (target.map != null) {
|
||||
for (var name in target.map) {
|
||||
yield * this.deleteList(target.map[name])
|
||||
this.deleteList(target.map[name])
|
||||
}
|
||||
// TODO: here to.. (see above)
|
||||
// yield * this.deleteList(target.id) -- see above
|
||||
// this.deleteList(target.id) -- see above
|
||||
}
|
||||
if (target.opContent != null) {
|
||||
yield * this.deleteOperation(target.opContent)
|
||||
this.deleteOperation(target.opContent)
|
||||
// target.opContent = null
|
||||
}
|
||||
if (target.requires != null) {
|
||||
for (var i = 0; i < target.requires.length; i++) {
|
||||
yield * this.deleteOperation(target.requires[i])
|
||||
this.deleteOperation(target.requires[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
var left
|
||||
if (target.left != null) {
|
||||
left = yield * this.getInsertion(target.left)
|
||||
left = this.getInsertion(target.left)
|
||||
} else {
|
||||
left = null
|
||||
}
|
||||
|
||||
// set here because it was deleted and/or gc'd
|
||||
yield * this.setOperation(target)
|
||||
this.setOperation(target)
|
||||
|
||||
/*
|
||||
Check if it is possible to add right to the gc.
|
||||
@@ -200,12 +200,12 @@ export default function extendTransaction (Y) {
|
||||
*/
|
||||
var right
|
||||
if (target.right != null) {
|
||||
right = yield * this.getOperation(target.right)
|
||||
right = this.getOperation(target.right)
|
||||
} else {
|
||||
right = null
|
||||
}
|
||||
if (callType && !preventCallType) {
|
||||
yield * this.store.operationAdded(this, {
|
||||
this.store.operationAdded(this, {
|
||||
struct: 'Delete',
|
||||
target: target.id,
|
||||
length: targetLength,
|
||||
@@ -213,9 +213,9 @@ export default function extendTransaction (Y) {
|
||||
})
|
||||
}
|
||||
// need to gc in the end!
|
||||
yield * this.store.addToGarbageCollector.call(this, target, left)
|
||||
this.store.addToGarbageCollector.call(this, target, left)
|
||||
if (right != null) {
|
||||
yield * this.store.addToGarbageCollector.call(this, right, target)
|
||||
this.store.addToGarbageCollector.call(this, right, target)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,25 +223,25 @@ export default function extendTransaction (Y) {
|
||||
/*
|
||||
Mark an operation as deleted&gc'd
|
||||
*/
|
||||
* markGarbageCollected (id, len) {
|
||||
markGarbageCollected (id, len) {
|
||||
// this.mem.push(["gc", id]);
|
||||
this.store.addToDebug('yield * this.markGarbageCollected(', id, ', ', len, ')')
|
||||
var n = yield * this.markDeleted(id, len)
|
||||
this.store.addToDebug('this.markGarbageCollected(', id, ', ', len, ')')
|
||||
var n = this.markDeleted(id, len)
|
||||
if (n.id[1] < id[1] && !n.gc) {
|
||||
// un-extend left
|
||||
var newlen = n.len - (id[1] - n.id[1])
|
||||
n.len -= newlen
|
||||
yield * this.ds.put(n)
|
||||
this.ds.put(n)
|
||||
n = {id: id, len: newlen, gc: false}
|
||||
yield * this.ds.put(n)
|
||||
this.ds.put(n)
|
||||
}
|
||||
// get prev&next before adding a new operation
|
||||
var prev = yield * this.ds.findPrev(id)
|
||||
var next = yield * this.ds.findNext(id)
|
||||
var prev = this.ds.findPrev(id)
|
||||
var next = this.ds.findNext(id)
|
||||
|
||||
if (id[1] + len < n.id[1] + n.len && !n.gc) {
|
||||
// un-extend right
|
||||
yield * this.ds.put({id: [id[0], id[1] + len], len: n.len - len, gc: false})
|
||||
this.ds.put({id: [id[0], id[1] + len], len: n.len - len, gc: false})
|
||||
n.len = len
|
||||
}
|
||||
// set gc'd
|
||||
@@ -253,7 +253,7 @@ export default function extendTransaction (Y) {
|
||||
Y.utils.compareIds([prev.id[0], prev.id[1] + prev.len], n.id)
|
||||
) {
|
||||
prev.len += n.len
|
||||
yield * this.ds.delete(n.id)
|
||||
this.ds.delete(n.id)
|
||||
n = prev
|
||||
// ds.put n here?
|
||||
}
|
||||
@@ -264,22 +264,22 @@ export default function extendTransaction (Y) {
|
||||
Y.utils.compareIds([n.id[0], n.id[1] + n.len], next.id)
|
||||
) {
|
||||
n.len += next.len
|
||||
yield * this.ds.delete(next.id)
|
||||
this.ds.delete(next.id)
|
||||
}
|
||||
yield * this.ds.put(n)
|
||||
yield * this.updateState(n.id[0])
|
||||
this.ds.put(n)
|
||||
this.updateState(n.id[0])
|
||||
}
|
||||
/*
|
||||
Mark an operation as deleted.
|
||||
|
||||
returns the delete node
|
||||
*/
|
||||
* markDeleted (id, length) {
|
||||
markDeleted (id, length) {
|
||||
if (length == null) {
|
||||
length = 1
|
||||
}
|
||||
// this.mem.push(["del", id]);
|
||||
var n = yield * this.ds.findWithUpperBound(id)
|
||||
var n = this.ds.findWithUpperBound(id)
|
||||
if (n != null && n.id[0] === id[0]) {
|
||||
if (n.id[1] <= id[1] && id[1] <= n.id[1] + n.len) {
|
||||
// id is in n's range
|
||||
@@ -293,7 +293,7 @@ export default function extendTransaction (Y) {
|
||||
if (diff < length) {
|
||||
// a partial deletion
|
||||
n = {id: [id[0], id[1] + diff], len: length - diff, gc: false}
|
||||
yield * this.ds.put(n)
|
||||
this.ds.put(n)
|
||||
} else {
|
||||
// already gc'd
|
||||
throw new Error(
|
||||
@@ -308,15 +308,15 @@ export default function extendTransaction (Y) {
|
||||
} else {
|
||||
// cannot extend left (there is no left!)
|
||||
n = {id: id, len: length, gc: false}
|
||||
yield * this.ds.put(n) // TODO: you double-put !!
|
||||
this.ds.put(n) // TODO: you double-put !!
|
||||
}
|
||||
} else {
|
||||
// cannot extend left
|
||||
n = {id: id, len: length, gc: false}
|
||||
yield * this.ds.put(n)
|
||||
this.ds.put(n)
|
||||
}
|
||||
// can extend right?
|
||||
var next = yield * this.ds.findNext(n.id)
|
||||
var next = this.ds.findNext(n.id)
|
||||
if (
|
||||
next != null &&
|
||||
n.id[0] === next.id[0] &&
|
||||
@@ -332,8 +332,8 @@ export default function extendTransaction (Y) {
|
||||
// delete the missing range after next
|
||||
diff = diff - next.len // missing range after next
|
||||
if (diff > 0) {
|
||||
yield * this.ds.put(n) // unneccessary? TODO!
|
||||
yield * this.markDeleted([next.id[0], next.id[1] + next.len], diff)
|
||||
this.ds.put(n) // unneccessary? TODO!
|
||||
this.markDeleted([next.id[0], next.id[1] + next.len], diff)
|
||||
}
|
||||
}
|
||||
break
|
||||
@@ -342,8 +342,8 @@ export default function extendTransaction (Y) {
|
||||
if (diff > next.len) {
|
||||
// n is even longer than next
|
||||
// get next.next, and try to extend it
|
||||
var _next = yield * this.ds.findNext(next.id)
|
||||
yield * this.ds.delete(next.id)
|
||||
var _next = this.ds.findNext(next.id)
|
||||
this.ds.delete(next.id)
|
||||
if (_next == null || n.id[0] !== _next.id[0]) {
|
||||
break
|
||||
} else {
|
||||
@@ -354,13 +354,13 @@ export default function extendTransaction (Y) {
|
||||
} else {
|
||||
// n just partially overlaps with next. extend n, delete next, and break this loop
|
||||
n.len += next.len - diff
|
||||
yield * this.ds.delete(next.id)
|
||||
this.ds.delete(next.id)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
yield * this.ds.put(n)
|
||||
this.ds.put(n)
|
||||
return n
|
||||
}
|
||||
/*
|
||||
@@ -368,7 +368,7 @@ export default function extendTransaction (Y) {
|
||||
other clients (e.g. master). This will query the database for
|
||||
operations that can be gc'd and add them to the garbage collector.
|
||||
*/
|
||||
* garbageCollectAfterSync () {
|
||||
garbageCollectAfterSync () {
|
||||
// debugger
|
||||
if (this.store.gc1.length > 0 || this.store.gc2.length > 0) {
|
||||
console.warn('gc should be empty after sync')
|
||||
@@ -376,28 +376,28 @@ export default function extendTransaction (Y) {
|
||||
if (!this.store.gc) {
|
||||
return
|
||||
}
|
||||
yield * this.os.iterate(this, null, null, function * (op) {
|
||||
this.os.iterate(this, null, null, function (op) {
|
||||
if (op.gc) {
|
||||
delete op.gc
|
||||
yield * this.setOperation(op)
|
||||
this.setOperation(op)
|
||||
}
|
||||
if (op.parent != null) {
|
||||
var parentDeleted = yield * this.isDeleted(op.parent)
|
||||
var parentDeleted = this.isDeleted(op.parent)
|
||||
if (parentDeleted) {
|
||||
op.gc = true
|
||||
if (!op.deleted) {
|
||||
yield * this.markDeleted(op.id, op.content != null ? op.content.length : 1)
|
||||
this.markDeleted(op.id, op.content != null ? op.content.length : 1)
|
||||
op.deleted = true
|
||||
if (op.opContent != null) {
|
||||
yield * this.deleteOperation(op.opContent)
|
||||
this.deleteOperation(op.opContent)
|
||||
}
|
||||
if (op.requires != null) {
|
||||
for (var i = 0; i < op.requires.length; i++) {
|
||||
yield * this.deleteOperation(op.requires[i])
|
||||
this.deleteOperation(op.requires[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
yield * this.setOperation(op)
|
||||
this.setOperation(op)
|
||||
this.store.gc1.push(op.id) // this is ok becaues its shortly before sync (otherwise use queueGarbageCollector!)
|
||||
return
|
||||
}
|
||||
@@ -405,9 +405,9 @@ export default function extendTransaction (Y) {
|
||||
if (op.deleted) {
|
||||
var left = null
|
||||
if (op.left != null) {
|
||||
left = yield * this.getInsertion(op.left)
|
||||
left = this.getInsertion(op.left)
|
||||
}
|
||||
yield * this.store.addToGarbageCollector.call(this, op, left)
|
||||
this.store.addToGarbageCollector.call(this, op, left)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -420,10 +420,10 @@ export default function extendTransaction (Y) {
|
||||
* reset parent.end
|
||||
* reset origins of all right ops
|
||||
*/
|
||||
* garbageCollectOperation (id) {
|
||||
this.store.addToDebug('yield * this.garbageCollectOperation(', id, ')')
|
||||
var o = yield * this.getOperation(id)
|
||||
yield * this.markGarbageCollected(id, (o != null && o.content != null) ? o.content.length : 1) // always mark gc'd
|
||||
garbageCollectOperation (id) {
|
||||
this.store.addToDebug('this.garbageCollectOperation(', id, ')')
|
||||
var o = this.getOperation(id)
|
||||
this.markGarbageCollected(id, (o != null && o.content != null) ? o.content.length : 1) // always mark gc'd
|
||||
// if op exists, then clean that mess up..
|
||||
if (o != null) {
|
||||
var deps = []
|
||||
@@ -434,32 +434,32 @@ export default function extendTransaction (Y) {
|
||||
deps = deps.concat(o.requires)
|
||||
}
|
||||
for (var i = 0; i < deps.length; i++) {
|
||||
var dep = yield * this.getOperation(deps[i])
|
||||
var dep = this.getOperation(deps[i])
|
||||
if (dep != null) {
|
||||
if (!dep.deleted) {
|
||||
yield * this.deleteOperation(dep.id)
|
||||
dep = yield * this.getOperation(dep.id)
|
||||
this.deleteOperation(dep.id)
|
||||
dep = this.getOperation(dep.id)
|
||||
}
|
||||
dep.gc = true
|
||||
yield * this.setOperation(dep)
|
||||
this.setOperation(dep)
|
||||
this.store.queueGarbageCollector(dep.id)
|
||||
} else {
|
||||
yield * this.markGarbageCollected(deps[i], 1)
|
||||
this.markGarbageCollected(deps[i], 1)
|
||||
}
|
||||
}
|
||||
|
||||
// remove gc'd op from the left op, if it exists
|
||||
if (o.left != null) {
|
||||
var left = yield * this.getInsertion(o.left)
|
||||
var left = this.getInsertion(o.left)
|
||||
left.right = o.right
|
||||
yield * this.setOperation(left)
|
||||
this.setOperation(left)
|
||||
}
|
||||
// remove gc'd op from the right op, if it exists
|
||||
// also reset origins of right ops
|
||||
if (o.right != null) {
|
||||
var right = yield * this.getOperation(o.right)
|
||||
var right = this.getOperation(o.right)
|
||||
right.left = o.left
|
||||
yield * this.setOperation(right)
|
||||
this.setOperation(right)
|
||||
|
||||
if (o.originOf != null && o.originOf.length > 0) {
|
||||
// find new origin of right ops
|
||||
@@ -478,7 +478,7 @@ export default function extendTransaction (Y) {
|
||||
right.origin = neworigin
|
||||
// search until you find origin pointer to the left of o
|
||||
if (right.right != null) {
|
||||
var i = yield * this.getOperation(right.right)
|
||||
var i = this.getOperation(right.right)
|
||||
var ids = [o.id, o.right]
|
||||
while (ids.some(function (id) {
|
||||
return Y.utils.compareIds(id, i.origin)
|
||||
@@ -486,14 +486,14 @@ export default function extendTransaction (Y) {
|
||||
if (Y.utils.compareIds(i.origin, o.id)) {
|
||||
// reset origin of i
|
||||
i.origin = neworigin
|
||||
yield * this.setOperation(i)
|
||||
this.setOperation(i)
|
||||
}
|
||||
// get next i
|
||||
if (i.right == null) {
|
||||
break
|
||||
} else {
|
||||
ids.push(i.id)
|
||||
i = yield * this.getOperation(i.right)
|
||||
i = this.getOperation(i.right)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -502,20 +502,20 @@ export default function extendTransaction (Y) {
|
||||
// ** Now the new implementation starts **
|
||||
// reset neworigin of all originOf[*]
|
||||
for (var _i in o.originOf) {
|
||||
var originsIn = yield * this.getOperation(o.originOf[_i])
|
||||
var originsIn = this.getOperation(o.originOf[_i])
|
||||
if (originsIn != null) {
|
||||
originsIn.origin = neworigin
|
||||
yield * this.setOperation(originsIn)
|
||||
this.setOperation(originsIn)
|
||||
}
|
||||
}
|
||||
if (neworigin != null) {
|
||||
var neworigin_ = yield * this.getInsertion(neworigin)
|
||||
var neworigin_ = this.getInsertion(neworigin)
|
||||
if (neworigin_.originOf == null) {
|
||||
neworigin_.originOf = o.originOf
|
||||
} else {
|
||||
neworigin_.originOf = o.originOf.concat(neworigin_.originOf)
|
||||
}
|
||||
yield * this.setOperation(neworigin_)
|
||||
this.setOperation(neworigin_)
|
||||
}
|
||||
// we don't need to set right here, because
|
||||
// right should be in o.originOf => it is set it the previous for loop
|
||||
@@ -524,15 +524,15 @@ export default function extendTransaction (Y) {
|
||||
// o may originate in another operation.
|
||||
// Since o is deleted, we have to reset o.origin's `originOf` property
|
||||
if (o.origin != null) {
|
||||
var origin = yield * this.getInsertion(o.origin)
|
||||
var origin = this.getInsertion(o.origin)
|
||||
origin.originOf = origin.originOf.filter(function (_id) {
|
||||
return !Y.utils.compareIds(id, _id)
|
||||
})
|
||||
yield * this.setOperation(origin)
|
||||
this.setOperation(origin)
|
||||
}
|
||||
var parent
|
||||
if (o.parent != null) {
|
||||
parent = yield * this.getOperation(o.parent)
|
||||
parent = this.getOperation(o.parent)
|
||||
}
|
||||
// remove gc'd op from parent, if it exists
|
||||
if (parent != null) {
|
||||
@@ -559,38 +559,38 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
}
|
||||
if (setParent) {
|
||||
yield * this.setOperation(parent)
|
||||
this.setOperation(parent)
|
||||
}
|
||||
}
|
||||
// finally remove it from the os
|
||||
yield * this.removeOperation(o.id)
|
||||
this.removeOperation(o.id)
|
||||
}
|
||||
}
|
||||
* checkDeleteStoreForState (state) {
|
||||
var n = yield * this.ds.findWithUpperBound([state.user, state.clock])
|
||||
checkDeleteStoreForState (state) {
|
||||
var n = this.ds.findWithUpperBound([state.user, state.clock])
|
||||
if (n != null && n.id[0] === state.user && n.gc) {
|
||||
state.clock = Math.max(state.clock, n.id[1] + n.len)
|
||||
}
|
||||
}
|
||||
* updateState (user) {
|
||||
var state = yield * this.getState(user)
|
||||
yield * this.checkDeleteStoreForState(state)
|
||||
var o = yield * this.getInsertion([user, state.clock])
|
||||
updateState (user) {
|
||||
var state = this.getState(user)
|
||||
this.checkDeleteStoreForState(state)
|
||||
var o = this.getInsertion([user, state.clock])
|
||||
var oLength = (o != null && o.content != null) ? o.content.length : 1
|
||||
while (o != null && user === o.id[0] && o.id[1] <= state.clock && o.id[1] + oLength > state.clock) {
|
||||
// either its a new operation (1. case), or it is an operation that was deleted, but is not yet in the OS
|
||||
state.clock += oLength
|
||||
yield * this.checkDeleteStoreForState(state)
|
||||
o = yield * this.os.findNext(o.id)
|
||||
this.checkDeleteStoreForState(state)
|
||||
o = this.os.findNext(o.id)
|
||||
oLength = (o != null && o.content != null) ? o.content.length : 1
|
||||
}
|
||||
yield * this.setState(state)
|
||||
this.setState(state)
|
||||
}
|
||||
/*
|
||||
apply a delete set in order to get
|
||||
the state of the supplied ds
|
||||
*/
|
||||
* applyDeleteSet (decoder) {
|
||||
applyDeleteSet (decoder) {
|
||||
var deletions = []
|
||||
|
||||
let dsLength = decoder.readUint32()
|
||||
@@ -606,7 +606,7 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
var pos = 0
|
||||
var d = dv[pos]
|
||||
yield * this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], function * (n) {
|
||||
this.ds.iterate(this, [user, 0], [user, Number.MAX_VALUE], function (n) {
|
||||
// cases:
|
||||
// 1. d deletes something to the right of n
|
||||
// => go to next n (break)
|
||||
@@ -655,14 +655,14 @@ export default function extendTransaction (Y) {
|
||||
for (var i = 0; i < deletions.length; i++) {
|
||||
var del = deletions[i]
|
||||
// always try to delete..
|
||||
yield * this.deleteOperation([del[0], del[1]], del[2])
|
||||
this.deleteOperation([del[0], del[1]], del[2])
|
||||
if (del[3]) {
|
||||
// gc..
|
||||
yield * this.markGarbageCollected([del[0], del[1]], del[2]) // always mark gc'd
|
||||
this.markGarbageCollected([del[0], del[1]], del[2]) // always mark gc'd
|
||||
// remove operation..
|
||||
var counter = del[1] + del[2]
|
||||
while (counter >= del[1]) {
|
||||
var o = yield * this.os.findWithUpperBound([del[0], counter - 1])
|
||||
var o = this.os.findWithUpperBound([del[0], counter - 1])
|
||||
if (o == null) {
|
||||
break
|
||||
}
|
||||
@@ -673,14 +673,14 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
if (o.id[1] + oLen > del[1] + del[2]) {
|
||||
// overlaps right
|
||||
o = yield * this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1])
|
||||
o = this.getInsertionCleanEnd([del[0], del[1] + del[2] - 1])
|
||||
}
|
||||
if (o.id[1] < del[1]) {
|
||||
// overlaps left
|
||||
o = yield * this.getInsertionCleanStart([del[0], del[1]])
|
||||
o = this.getInsertionCleanStart([del[0], del[1]])
|
||||
}
|
||||
counter = o.id[1]
|
||||
yield * this.garbageCollectOperation(o.id)
|
||||
this.garbageCollectOperation(o.id)
|
||||
}
|
||||
}
|
||||
if (this.store.forwardAppliedOperations || this.store.y.persistence != null) {
|
||||
@@ -695,16 +695,16 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
}
|
||||
}
|
||||
* isGarbageCollected (id) {
|
||||
var n = yield * this.ds.findWithUpperBound(id)
|
||||
isGarbageCollected (id) {
|
||||
var n = this.ds.findWithUpperBound(id)
|
||||
return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len && n.gc
|
||||
}
|
||||
/*
|
||||
A DeleteSet (ds) describes all the deleted ops in the OS
|
||||
*/
|
||||
* writeDeleteSet (encoder) {
|
||||
writeDeleteSet (encoder) {
|
||||
var ds = new Map()
|
||||
yield * this.ds.iterate(this, null, null, function * (n) {
|
||||
this.ds.iterate(this, null, null, function (n) {
|
||||
var user = n.id[0]
|
||||
var counter = n.id[1]
|
||||
var len = n.len
|
||||
@@ -731,16 +731,16 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
}
|
||||
}
|
||||
* isDeleted (id) {
|
||||
var n = yield * this.ds.findWithUpperBound(id)
|
||||
isDeleted (id) {
|
||||
var n = this.ds.findWithUpperBound(id)
|
||||
return n != null && n.id[0] === id[0] && id[1] < n.id[1] + n.len
|
||||
}
|
||||
* setOperation (op) {
|
||||
yield * this.os.put(op)
|
||||
setOperation (op) {
|
||||
this.os.put(op)
|
||||
return op
|
||||
}
|
||||
* addOperation (op) {
|
||||
yield * this.os.put(op)
|
||||
addOperation (op) {
|
||||
this.os.put(op)
|
||||
// case op is created by this user, op is already broadcasted in applyCreatedOperations
|
||||
if (op.id[0] !== this.store.userId && typeof op.id[1] !== 'string') {
|
||||
if (this.store.forwardAppliedOperations) {
|
||||
@@ -753,7 +753,7 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
}
|
||||
// if insertion, try to combine with left insertion (if both have content property)
|
||||
* tryCombineWithLeft (op) {
|
||||
tryCombineWithLeft (op) {
|
||||
if (
|
||||
op != null &&
|
||||
op.left != null &&
|
||||
@@ -761,7 +761,7 @@ export default function extendTransaction (Y) {
|
||||
op.left[0] === op.id[0] &&
|
||||
Y.utils.compareIds(op.left, op.origin)
|
||||
) {
|
||||
var left = yield * this.getInsertion(op.left)
|
||||
var left = this.getInsertion(op.left)
|
||||
if (left.content != null &&
|
||||
left.id[1] + left.content.length === op.id[1] &&
|
||||
left.originOf.length === 1 &&
|
||||
@@ -776,13 +776,13 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
left.content = left.content.concat(op.content)
|
||||
left.right = op.right
|
||||
yield * this.os.delete(op.id)
|
||||
yield * this.setOperation(left)
|
||||
this.os.delete(op.id)
|
||||
this.setOperation(left)
|
||||
}
|
||||
}
|
||||
}
|
||||
* getInsertion (id) {
|
||||
var ins = yield * this.os.findWithUpperBound(id)
|
||||
getInsertion (id) {
|
||||
var ins = this.os.findWithUpperBound(id)
|
||||
if (ins == null) {
|
||||
return null
|
||||
} else {
|
||||
@@ -794,14 +794,14 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
}
|
||||
}
|
||||
* getInsertionCleanStartEnd (id) {
|
||||
yield * this.getInsertionCleanStart(id)
|
||||
return yield * this.getInsertionCleanEnd(id)
|
||||
getInsertionCleanStartEnd (id) {
|
||||
this.getInsertionCleanStart(id)
|
||||
return this.getInsertionCleanEnd(id)
|
||||
}
|
||||
// Return an insertion such that id is the first element of content
|
||||
// This function manipulates an operation, if necessary
|
||||
* getInsertionCleanStart (id) {
|
||||
var ins = yield * this.getInsertion(id)
|
||||
getInsertionCleanStart (id) {
|
||||
var ins = this.getInsertion(id)
|
||||
if (ins != null) {
|
||||
if (ins.id[1] === id[1]) {
|
||||
return ins
|
||||
@@ -815,8 +815,8 @@ export default function extendTransaction (Y) {
|
||||
left.right = ins.id
|
||||
ins.left = leftLid
|
||||
// debugger // check
|
||||
yield * this.setOperation(left)
|
||||
yield * this.setOperation(ins)
|
||||
this.setOperation(left)
|
||||
this.setOperation(ins)
|
||||
if (left.gc) {
|
||||
this.store.queueGarbageCollector(ins.id)
|
||||
}
|
||||
@@ -828,8 +828,8 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
// Return an insertion such that id is the last element of content
|
||||
// This function manipulates an operation, if necessary
|
||||
* getInsertionCleanEnd (id) {
|
||||
var ins = yield * this.getInsertion(id)
|
||||
getInsertionCleanEnd (id) {
|
||||
var ins = this.getInsertion(id)
|
||||
if (ins != null) {
|
||||
if (ins.content == null || (ins.id[1] + ins.content.length - 1 === id[1])) {
|
||||
return ins
|
||||
@@ -843,8 +843,8 @@ export default function extendTransaction (Y) {
|
||||
ins.right = right.id
|
||||
right.left = insLid
|
||||
// debugger // check
|
||||
yield * this.setOperation(right)
|
||||
yield * this.setOperation(ins)
|
||||
this.setOperation(right)
|
||||
this.setOperation(ins)
|
||||
if (ins.gc) {
|
||||
this.store.queueGarbageCollector(right.id)
|
||||
}
|
||||
@@ -854,8 +854,8 @@ export default function extendTransaction (Y) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
* getOperation (id/* :any */)/* :Transaction<any> */ {
|
||||
var o = yield * this.os.find(id)
|
||||
getOperation (id/* :any */)/* :Transaction<any> */ {
|
||||
var o = this.os.find(id)
|
||||
if (id[0] !== 0xFFFFFF || o != null) {
|
||||
return o
|
||||
} else { // type is string
|
||||
@@ -870,7 +870,7 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
var op = Y.Struct[struct].create(id, args)
|
||||
op.type = comp[1]
|
||||
yield * this.setOperation(op)
|
||||
this.setOperation(op)
|
||||
return op
|
||||
} else {
|
||||
throw new Error(
|
||||
@@ -880,18 +880,18 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
}
|
||||
}
|
||||
* removeOperation (id) {
|
||||
yield * this.os.delete(id)
|
||||
removeOperation (id) {
|
||||
this.os.delete(id)
|
||||
}
|
||||
* setState (state) {
|
||||
setState (state) {
|
||||
var val = {
|
||||
id: [state.user],
|
||||
clock: state.clock
|
||||
}
|
||||
yield * this.ss.put(val)
|
||||
this.ss.put(val)
|
||||
}
|
||||
* getState (user) {
|
||||
var n = yield * this.ss.find([user])
|
||||
getState (user) {
|
||||
var n = this.ss.find([user])
|
||||
var clock = n == null ? null : n.clock
|
||||
if (clock == null) {
|
||||
clock = 0
|
||||
@@ -901,9 +901,9 @@ export default function extendTransaction (Y) {
|
||||
clock: clock
|
||||
}
|
||||
}
|
||||
* getStateVector () {
|
||||
getStateVector () {
|
||||
var stateVector = []
|
||||
yield * this.ss.iterate(this, null, null, function * (n) {
|
||||
this.ss.iterate(this, null, null, function (n) {
|
||||
stateVector.push({
|
||||
user: n.id[0],
|
||||
clock: n.clock
|
||||
@@ -911,18 +911,18 @@ export default function extendTransaction (Y) {
|
||||
})
|
||||
return stateVector
|
||||
}
|
||||
* getStateSet () {
|
||||
getStateSet () {
|
||||
var ss = {}
|
||||
yield * this.ss.iterate(this, null, null, function * (n) {
|
||||
this.ss.iterate(this, null, null, function (n) {
|
||||
ss[n.id[0]] = n.clock
|
||||
})
|
||||
return ss
|
||||
}
|
||||
* writeStateSet (encoder) {
|
||||
writeStateSet (encoder) {
|
||||
let lenPosition = encoder.pos
|
||||
let len = 0
|
||||
encoder.writeUint32(0)
|
||||
yield * this.ss.iterate(this, null, null, function * (n) {
|
||||
this.ss.iterate(this, null, null, function (n) {
|
||||
encoder.writeVarUint(n.id[0])
|
||||
encoder.writeVarUint(n.clock)
|
||||
len++
|
||||
@@ -976,14 +976,14 @@ export default function extendTransaction (Y) {
|
||||
3. Found o = op.origin -> set op.left = op.origin, and send it to the user. start again from 1. (set op = o)
|
||||
4. Found some o -> set o.right = op, o.left = o.origin, send it to the user, continue
|
||||
*/
|
||||
* getOperations (startSS) {
|
||||
getOperations (startSS) {
|
||||
// TODO: use bounds here!
|
||||
if (startSS == null) {
|
||||
startSS = new Map()
|
||||
}
|
||||
var send = []
|
||||
|
||||
var endSV = yield * this.getStateVector()
|
||||
var endSV = this.getStateVector()
|
||||
for (let endState of endSV) {
|
||||
let user = endState.user
|
||||
if (user === 0xFFFFFF) {
|
||||
@@ -993,7 +993,7 @@ export default function extendTransaction (Y) {
|
||||
if (startPos > 0) {
|
||||
// There is a change that [user, startPos] is in a composed Insertion (with a smaller counter)
|
||||
// find out if that is the case
|
||||
let firstMissing = yield * this.getInsertion([user, startPos])
|
||||
let firstMissing = this.getInsertion([user, startPos])
|
||||
if (firstMissing != null) {
|
||||
// update startPos
|
||||
startPos = firstMissing.id[1]
|
||||
@@ -1007,7 +1007,7 @@ export default function extendTransaction (Y) {
|
||||
if (user === 0xFFFFFF) {
|
||||
continue
|
||||
}
|
||||
yield * this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function * (op) {
|
||||
this.os.iterate(this, [user, startPos], [user, Number.MAX_VALUE], function (op) {
|
||||
op = Y.Struct[op.struct].encode(op)
|
||||
if (op.struct !== 'Insert') {
|
||||
send.push(op)
|
||||
@@ -1038,7 +1038,7 @@ export default function extendTransaction (Y) {
|
||||
*/
|
||||
break
|
||||
}
|
||||
o = yield * this.getInsertion(o.left)
|
||||
o = this.getInsertion(o.left)
|
||||
// we set another o, check if we can reduce $missingOrigins
|
||||
while (missingOrigins.length > 0 && Y.utils.matchesId(o, missingOrigins[missingOrigins.length - 1].origin)) {
|
||||
missingOrigins.pop()
|
||||
@@ -1076,7 +1076,7 @@ export default function extendTransaction (Y) {
|
||||
return send.reverse()
|
||||
}
|
||||
|
||||
* writeOperations (encoder, decoder) {
|
||||
writeOperations (encoder, decoder) {
|
||||
let ss = new Map()
|
||||
let ssLength = decoder.readUint32()
|
||||
for (let i = 0; i < ssLength; i++) {
|
||||
@@ -1084,7 +1084,7 @@ export default function extendTransaction (Y) {
|
||||
let clock = decoder.readVarUint()
|
||||
ss.set(user, clock)
|
||||
}
|
||||
let ops = yield * this.getOperations(ss)
|
||||
let ops = this.getOperations(ss)
|
||||
encoder.writeUint32(ops.length)
|
||||
for (let i = 0; i < ops.length; i++) {
|
||||
let op = ops[i]
|
||||
@@ -1092,17 +1092,17 @@ export default function extendTransaction (Y) {
|
||||
}
|
||||
}
|
||||
|
||||
* toBinary () {
|
||||
toBinary () {
|
||||
let encoder = new BinaryEncoder()
|
||||
yield * this.writeOperationsUntransformed(encoder)
|
||||
yield * this.writeDeleteSet(encoder)
|
||||
this.writeOperationsUntransformed(encoder)
|
||||
this.writeDeleteSet(encoder)
|
||||
return encoder.createBuffer()
|
||||
}
|
||||
|
||||
* fromBinary (buffer) {
|
||||
fromBinary (buffer) {
|
||||
let decoder = new BinaryDecoder(buffer)
|
||||
yield * this.applyOperationsUntransformed(decoder)
|
||||
yield * this.applyDeleteSet(decoder)
|
||||
this.applyOperationsUntransformed(decoder)
|
||||
this.applyDeleteSet(decoder)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1110,43 +1110,43 @@ export default function extendTransaction (Y) {
|
||||
* You can apply these operations using .applyOperationsUntransformed(ops)
|
||||
*
|
||||
*/
|
||||
* writeOperationsUntransformed (encoder) {
|
||||
writeOperationsUntransformed (encoder) {
|
||||
let lenPosition = encoder.pos
|
||||
let len = 0
|
||||
encoder.writeUint32(0) // placeholder
|
||||
yield * this.os.iterate(this, null, null, function * (op) {
|
||||
this.os.iterate(this, null, null, function (op) {
|
||||
if (op.id[0] !== 0xFFFFFF) {
|
||||
len++
|
||||
Y.Struct[op.struct].binaryEncode(encoder, Y.Struct[op.struct].encode(op))
|
||||
}
|
||||
})
|
||||
encoder.setUint32(lenPosition, len)
|
||||
yield * this.writeStateSet(encoder)
|
||||
this.writeStateSet(encoder)
|
||||
}
|
||||
* applyOperationsUntransformed (decoder) {
|
||||
applyOperationsUntransformed (decoder) {
|
||||
let len = decoder.readUint32()
|
||||
for (let i = 0; i < len; i++) {
|
||||
let op = Y.Struct.binaryDecodeOperation(decoder)
|
||||
yield * this.os.put(op)
|
||||
this.os.put(op)
|
||||
}
|
||||
yield * this.os.iterate(this, null, null, function * (op) {
|
||||
this.os.iterate(this, null, null, function (op) {
|
||||
if (op.parent != null) {
|
||||
if (op.struct === 'Insert') {
|
||||
// update parents .map/start/end properties
|
||||
if (op.parentSub != null && op.left == null) {
|
||||
// op is child of Map
|
||||
let parent = yield * this.getOperation(op.parent)
|
||||
let parent = this.getOperation(op.parent)
|
||||
parent.map[op.parentSub] = op.id
|
||||
yield * this.setOperation(parent)
|
||||
this.setOperation(parent)
|
||||
} else if (op.right == null || op.left == null) {
|
||||
let parent = yield * this.getOperation(op.parent)
|
||||
let parent = this.getOperation(op.parent)
|
||||
if (op.right == null) {
|
||||
parent.end = Y.utils.getLastId(op)
|
||||
}
|
||||
if (op.left == null) {
|
||||
parent.start = op.id
|
||||
}
|
||||
yield * this.setOperation(parent)
|
||||
this.setOperation(parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1155,14 +1155,14 @@ export default function extendTransaction (Y) {
|
||||
for (let i = 0; i < stateSetLength; i++) {
|
||||
let user = decoder.readVarUint()
|
||||
let clock = decoder.readVarUint()
|
||||
yield * this.ss.put({
|
||||
this.ss.put({
|
||||
id: [user],
|
||||
clock: clock
|
||||
})
|
||||
}
|
||||
}
|
||||
/* this is what we used before.. use this as a reference..
|
||||
* makeOperationReady (startSS, op) {
|
||||
makeOperationReady (startSS, op) {
|
||||
op = Y.Struct[op.struct].encode(op)
|
||||
op = Y.utils.copyObject(op) -- use copyoperation instead now!
|
||||
var o = op
|
||||
@@ -1172,7 +1172,7 @@ export default function extendTransaction (Y) {
|
||||
// or the o that has no origin to the right of op
|
||||
// (this is why we use the ids array)
|
||||
while (o.right != null) {
|
||||
var right = yield * this.getOperation(o.right)
|
||||
var right = this.getOperation(o.right)
|
||||
if (o.right[1] < (startSS[o.right[0]] || 0) || !ids.some(function (id) {
|
||||
return Y.utils.compareIds(id, right.origin)
|
||||
})) {
|
||||
@@ -1186,10 +1186,10 @@ export default function extendTransaction (Y) {
|
||||
return op
|
||||
}
|
||||
*/
|
||||
* flush () {
|
||||
yield * this.os.flush()
|
||||
yield * this.ss.flush()
|
||||
yield * this.ds.flush()
|
||||
flush () {
|
||||
this.os.flush()
|
||||
this.ss.flush()
|
||||
this.ds.flush()
|
||||
}
|
||||
}
|
||||
Y.Transaction = TransactionInterface
|
||||
|
||||
Reference in New Issue
Block a user