implementing new insertion struct (unfinished)
This commit is contained in:
parent
fe75ed6208
commit
1c32067908
@ -25,7 +25,7 @@ g.g = g
|
|||||||
|
|
||||||
g.YConcurrency_TestingMode = true
|
g.YConcurrency_TestingMode = true
|
||||||
|
|
||||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000
|
||||||
|
|
||||||
g.describeManyTimes = function describeManyTimes (times, name, f) {
|
g.describeManyTimes = function describeManyTimes (times, name, f) {
|
||||||
for (var i = 0; i < times; i++) {
|
for (var i = 0; i < times; i++) {
|
||||||
|
@ -41,7 +41,8 @@ module.exports = function (Y/* :any */) {
|
|||||||
},
|
},
|
||||||
Insert: {
|
Insert: {
|
||||||
/* {
|
/* {
|
||||||
content: any,
|
content: [any],
|
||||||
|
opContent: Id,
|
||||||
id: Id,
|
id: Id,
|
||||||
left: Id,
|
left: Id,
|
||||||
origin: Id,
|
origin: Id,
|
||||||
@ -96,13 +97,13 @@ module.exports = function (Y/* :any */) {
|
|||||||
return 0
|
return 0
|
||||||
} else {
|
} else {
|
||||||
var d = 0
|
var d = 0
|
||||||
var o = yield* this.getOperation(op.left)
|
var o = yield* this.getInsertion(op.left)
|
||||||
while (!Y.utils.compareIds(op.origin, (o ? o.id : null))) {
|
while (!Y.utils.compareIds(op.origin, (o ? o.id : null))) {
|
||||||
d++
|
d++
|
||||||
if (o.left == null) {
|
if (o.left == null) {
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
o = yield* this.getOperation(o.left)
|
o = yield* this.getInsertion(o.left)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return d
|
return d
|
||||||
@ -130,7 +131,7 @@ module.exports = function (Y/* :any */) {
|
|||||||
if (op.origin != null) { // TODO: !== instead of !=
|
if (op.origin != null) { // TODO: !== instead of !=
|
||||||
// we save in origin that op originates in it
|
// we save in origin that op originates in it
|
||||||
// we need that later when we eventually garbage collect origin (see transaction)
|
// we need that later when we eventually garbage collect origin (see transaction)
|
||||||
var origin = yield* this.getOperation(op.origin)
|
var origin = yield* this.getInsertionCleanEnd(op.origin)
|
||||||
if (origin.originOf == null) {
|
if (origin.originOf == null) {
|
||||||
origin.originOf = []
|
origin.originOf = []
|
||||||
}
|
}
|
||||||
@ -145,8 +146,8 @@ module.exports = function (Y/* :any */) {
|
|||||||
|
|
||||||
// find o. o is the first conflicting operation
|
// find o. o is the first conflicting operation
|
||||||
if (op.left != null) {
|
if (op.left != null) {
|
||||||
o = yield* this.getOperation(op.left)
|
o = yield* this.getInsertionCleanEnd(op.left)
|
||||||
o = (o.right == null) ? null : yield* this.getOperation(o.right)
|
o = (o.right == null) ? null : yield* this.getInsertionCleanStart(o.right)
|
||||||
} else { // left == null
|
} else { // left == null
|
||||||
parent = yield* this.getOperation(op.parent)
|
parent = yield* this.getOperation(op.parent)
|
||||||
let startId = op.parentSub ? parent.map[op.parentSub] : parent.start
|
let startId = op.parentSub ? parent.map[op.parentSub] : parent.start
|
||||||
@ -175,7 +176,7 @@ module.exports = function (Y/* :any */) {
|
|||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
if (o.right != null) {
|
if (o.right != null) {
|
||||||
o = yield* this.getOperation(o.right)
|
o = yield* this.getInsertionCleanStart(o.right)
|
||||||
} else {
|
} else {
|
||||||
o = null
|
o = null
|
||||||
}
|
}
|
||||||
@ -194,15 +195,24 @@ module.exports = function (Y/* :any */) {
|
|||||||
// reconnect left and set right of op
|
// reconnect left and set right of op
|
||||||
if (op.left != null) {
|
if (op.left != null) {
|
||||||
left = yield* this.getOperation(op.left)
|
left = yield* this.getOperation(op.left)
|
||||||
|
if (false && op.content != null && left.content != null && left.id[0] === op.id[0] && left.id[1] + left.content.length === op.id[1] && left.originOf == null && left.deleted !== true && left.gc !== true) {
|
||||||
|
// extend left
|
||||||
|
left.content = left.content.concat(op.content)
|
||||||
|
op = left
|
||||||
|
} else {
|
||||||
|
// link left
|
||||||
op.right = left.right
|
op.right = left.right
|
||||||
left.right = op.id
|
left.right = op.id
|
||||||
|
|
||||||
yield* this.setOperation(left)
|
yield* this.setOperation(left)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// set op.right from parent, if necessary
|
||||||
op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start
|
op.right = op.parentSub ? parent.map[op.parentSub] || null : parent.start
|
||||||
}
|
}
|
||||||
// reconnect right
|
// reconnect right
|
||||||
if (op.right != null) {
|
if (op.right != null) {
|
||||||
|
// TODO: wanna connect right too?
|
||||||
right = yield* this.getOperation(op.right)
|
right = yield* this.getOperation(op.right)
|
||||||
right.left = op.id
|
right.left = op.id
|
||||||
|
|
||||||
@ -367,7 +377,7 @@ module.exports = function (Y/* :any */) {
|
|||||||
if (res == null || res.deleted) {
|
if (res == null || res.deleted) {
|
||||||
return void 0
|
return void 0
|
||||||
} else if (res.opContent == null) {
|
} else if (res.opContent == null) {
|
||||||
return res.content
|
return res.content[0]
|
||||||
} else {
|
} else {
|
||||||
return yield* this.getType(res.opContent)
|
return yield* this.getType(res.opContent)
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ module.exports = function (Y/* :any */) {
|
|||||||
Mark an operation as deleted, and add it to the GC, if possible.
|
Mark an operation as deleted, and add it to the GC, if possible.
|
||||||
*/
|
*/
|
||||||
* deleteOperation (targetId, preventCallType) /* :Generator<any, any, any> */ {
|
* deleteOperation (targetId, preventCallType) /* :Generator<any, any, any> */ {
|
||||||
var target = yield* this.getOperation(targetId)
|
var target = yield* this.getInsertionCleanStartEnd(targetId)
|
||||||
var callType = false
|
var callType = false
|
||||||
|
|
||||||
if (target == null || !target.deleted) {
|
if (target == null || !target.deleted) {
|
||||||
@ -751,11 +751,75 @@ module.exports = function (Y/* :any */) {
|
|||||||
this.store.y.connector.broadcastOps([op])
|
this.store.y.connector.broadcastOps([op])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
* getOperation (id/* :any */)/* :Transaction<any> */ {
|
* getInsertion (id) {
|
||||||
var o = yield* this.os.find(id)
|
var ins = yield* this.os.findWithUpperBound(id)
|
||||||
if (o != null || id[0] !== '_') {
|
var len = ins.content != null ? ins.content.length : 1 // in case of opContent
|
||||||
return o
|
if (ins != null && id[0] === ins.id[0] && id[1] < ins.id[1] + len) {
|
||||||
|
return ins
|
||||||
} else {
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
* getInsertionCleanStartEnd (id) {
|
||||||
|
yield* this.getInsertionCleanStart(id)
|
||||||
|
yield* 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)
|
||||||
|
if (ins != null) {
|
||||||
|
if (ins.id[1] === id[1]) {
|
||||||
|
return ins
|
||||||
|
} else {
|
||||||
|
var left = Y.utils.copyObject(ins)
|
||||||
|
ins.content = left.content.splice(ins.id[1] - id[1])
|
||||||
|
ins.id = id
|
||||||
|
ins.origin = left.id
|
||||||
|
left.originOf = [ins.id]
|
||||||
|
left.right = ins.id
|
||||||
|
ins.left = left.id
|
||||||
|
debugger // check
|
||||||
|
yield* this.setOperation(left)
|
||||||
|
yield* this.setOperation(ins)
|
||||||
|
return ins
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 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)
|
||||||
|
if (ins != null) {
|
||||||
|
if (ins.content == null || (ins.id[1] + ins.content.length - 1 === id[1])) {
|
||||||
|
return ins
|
||||||
|
} else {
|
||||||
|
var right = Y.utils.copyObject(ins)
|
||||||
|
right.content = ins.content.splice(-(ins.id[1] + ins.content.length - 1 - id[1])) // cut off remainder
|
||||||
|
right.id = [id[0], id[1] + 1]
|
||||||
|
right.origin = ins.id
|
||||||
|
ins.originOf = [right.id]
|
||||||
|
ins.right = right.id
|
||||||
|
right.left = ins.id
|
||||||
|
debugger // check
|
||||||
|
yield* this.setOperation(right)
|
||||||
|
yield* this.setOperation(ins)
|
||||||
|
return ins
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
* getOperation (id/* :any */)/* :Transaction<any> */ {
|
||||||
|
if (id.length > 2) {
|
||||||
|
id = [id[0], id[1]]
|
||||||
|
}
|
||||||
|
var o = yield* this.os.find(id)
|
||||||
|
if (id[0] !== '_' || o != null) {
|
||||||
|
return o
|
||||||
|
} else { // type is string
|
||||||
// generate this operation?
|
// generate this operation?
|
||||||
var comp = id[1].split('_')
|
var comp = id[1].split('_')
|
||||||
if (comp.length > 1) {
|
if (comp.length > 1) {
|
||||||
@ -770,7 +834,6 @@ module.exports = function (Y/* :any */) {
|
|||||||
debugger // eslint-disable-line
|
debugger // eslint-disable-line
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
* removeOperation (id) {
|
* removeOperation (id) {
|
||||||
|
23
src/Utils.js
23
src/Utils.js
@ -249,12 +249,15 @@ module.exports = function (Y /* : any*/) {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (id1[0] === id2[0] && id1[1] === id2[1]) {
|
if (id1[0] === id2[0]) {
|
||||||
|
var add1 = id1.length > 2 ? id1[2] : 0
|
||||||
|
var add2 = id2.length > 2 ? id2[2] : 0
|
||||||
|
if (id1[1] + add1 === id2[1] + add2) {
|
||||||
return true
|
return true
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
Y.utils.compareIds = compareIds
|
Y.utils.compareIds = compareIds
|
||||||
|
|
||||||
function createEmptyOpsArray (n) {
|
function createEmptyOpsArray (n) {
|
||||||
@ -374,14 +377,24 @@ module.exports = function (Y /* : any*/) {
|
|||||||
yield* this.flush()
|
yield* this.flush()
|
||||||
yield* super.delete(id)
|
yield* super.delete(id)
|
||||||
}
|
}
|
||||||
* findWithLowerBound () {
|
* findWithLowerBound (id) {
|
||||||
|
var o = yield* this.find(id)
|
||||||
|
if (o != null) {
|
||||||
|
return o
|
||||||
|
} else {
|
||||||
yield* this.flush()
|
yield* this.flush()
|
||||||
return yield* super.findWithLowerBound.apply(this, arguments)
|
return yield* super.findWithLowerBound.apply(this, arguments)
|
||||||
}
|
}
|
||||||
* findWithUpperBound () {
|
}
|
||||||
|
* findWithUpperBound (id) {
|
||||||
|
var o = yield* this.find(id)
|
||||||
|
if (o != null) {
|
||||||
|
return o
|
||||||
|
} else {
|
||||||
yield* this.flush()
|
yield* this.flush()
|
||||||
return yield* super.findWithUpperBound.apply(this, arguments)
|
return yield* super.findWithUpperBound.apply(this, arguments)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
* findNext () {
|
* findNext () {
|
||||||
yield* this.flush()
|
yield* this.flush()
|
||||||
return yield* super.findNext.apply(this, arguments)
|
return yield* super.findNext.apply(this, arguments)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user