Compare origin ids in item.integrate
This commit is contained in:
parent
1b17b5e400
commit
c635963747
@ -12,6 +12,8 @@ import {
|
|||||||
addToDeleteSet,
|
addToDeleteSet,
|
||||||
ItemDeleted,
|
ItemDeleted,
|
||||||
findRootTypeKey,
|
findRootTypeKey,
|
||||||
|
compareIDs,
|
||||||
|
getItem,
|
||||||
StructStore, ID, AbstractType, Y, Transaction // eslint-disable-line
|
StructStore, ID, AbstractType, Y, Transaction // eslint-disable-line
|
||||||
} from '../internals.js'
|
} from '../internals.js'
|
||||||
|
|
||||||
@ -133,6 +135,7 @@ export class AbstractItem extends AbstractStruct {
|
|||||||
* @param {Transaction} transaction
|
* @param {Transaction} transaction
|
||||||
*/
|
*/
|
||||||
integrate (transaction) {
|
integrate (transaction) {
|
||||||
|
const store = transaction.y.store
|
||||||
const id = this.id
|
const id = this.id
|
||||||
const parent = this.parent
|
const parent = this.parent
|
||||||
const parentSub = this.parentSub
|
const parentSub = this.parentSub
|
||||||
@ -165,7 +168,13 @@ export class AbstractItem extends AbstractStruct {
|
|||||||
} else {
|
} else {
|
||||||
o = parent._start
|
o = parent._start
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @type {Set<AbstractItem>}
|
||||||
|
*/
|
||||||
const conflictingItems = new Set()
|
const conflictingItems = new Set()
|
||||||
|
/**
|
||||||
|
* @type {Set<AbstractItem>}
|
||||||
|
*/
|
||||||
const itemsBeforeOrigin = new Set()
|
const itemsBeforeOrigin = new Set()
|
||||||
// Let c in conflictingItems, b in itemsBeforeOrigin
|
// Let c in conflictingItems, b in itemsBeforeOrigin
|
||||||
// ***{origin}bbbb{this}{c,b}{c,b}{o}***
|
// ***{origin}bbbb{this}{c,b}{c,b}{o}***
|
||||||
@ -173,22 +182,22 @@ export class AbstractItem extends AbstractStruct {
|
|||||||
while (o !== null && o !== this.right) {
|
while (o !== null && o !== this.right) {
|
||||||
itemsBeforeOrigin.add(o)
|
itemsBeforeOrigin.add(o)
|
||||||
conflictingItems.add(o)
|
conflictingItems.add(o)
|
||||||
if (this.origin === o.origin) {
|
if (compareIDs(this.origin, o.origin)) {
|
||||||
// case 1
|
// case 1
|
||||||
if (o.id.client < id.client) {
|
if (o.id.client < id.client) {
|
||||||
this.left = o
|
this.left = o
|
||||||
conflictingItems.clear()
|
conflictingItems.clear()
|
||||||
}
|
} // TODO: verify break else?
|
||||||
} else if (itemsBeforeOrigin.has(o.origin)) {
|
} else if (o.origin !== null && itemsBeforeOrigin.has(getItem(store, o.origin))) {
|
||||||
// case 2
|
// case 2
|
||||||
if (!conflictingItems.has(o.origin)) {
|
if (o.origin === null || !conflictingItems.has(getItem(store, o.origin))) {
|
||||||
this.left = o
|
this.left = o
|
||||||
conflictingItems.clear()
|
conflictingItems.clear()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// TODO: try to use right_origin instead.
|
// TODO: experiment with rightOrigin.
|
||||||
// Then you could basically omit conflictingItems!
|
// Then you could basically omit conflictingItems!
|
||||||
// Note: you probably can't use right_origin in every case.. only when setting _left
|
// Note: you probably can't use right_origin in every case.. only when setting _left
|
||||||
o = o.right
|
o = o.right
|
||||||
@ -220,7 +229,7 @@ export class AbstractItem extends AbstractStruct {
|
|||||||
if (parentSub === null && this.countable) {
|
if (parentSub === null && this.countable) {
|
||||||
parent._length += length
|
parent._length += length
|
||||||
}
|
}
|
||||||
addStruct(transaction.y.store, this)
|
addStruct(store, this)
|
||||||
if (parent !== null) {
|
if (parent !== null) {
|
||||||
maplib.setIfUndefined(transaction.changed, parent, set.create).add(parentSub)
|
maplib.setIfUndefined(transaction.changed, parent, set.create).add(parentSub)
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import {
|
|||||||
GC,
|
GC,
|
||||||
splitItem,
|
splitItem,
|
||||||
compareIDs,
|
compareIDs,
|
||||||
|
addToDeleteSet,
|
||||||
StructStore, Transaction, ID, AbstractType // eslint-disable-line
|
StructStore, Transaction, ID, AbstractType // eslint-disable-line
|
||||||
} from '../internals.js'
|
} from '../internals.js'
|
||||||
|
|
||||||
@ -53,6 +54,13 @@ export class ItemDeleted extends AbstractItem {
|
|||||||
copy (id, left, origin, right, rightOrigin, parent, parentSub) {
|
copy (id, left, origin, right, rightOrigin, parent, parentSub) {
|
||||||
return new ItemDeleted(id, left, origin, right, rightOrigin, parent, parentSub, this.length)
|
return new ItemDeleted(id, left, origin, right, rightOrigin, parent, parentSub, this.length)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @param {Transaction} transaction
|
||||||
|
*/
|
||||||
|
integrate (transaction) {
|
||||||
|
super.integrate(transaction)
|
||||||
|
addToDeleteSet(transaction.deleteSet, this.id, this.length)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @param {StructStore} store
|
* @param {StructStore} store
|
||||||
* @param {number} diff
|
* @param {number} diff
|
||||||
|
@ -125,6 +125,16 @@ export const find = (store, id) => {
|
|||||||
return structs[findIndexSS(structs, id.clock)]
|
return structs[findIndexSS(structs, id.clock)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
|
||||||
|
*
|
||||||
|
* @param {StructStore} store
|
||||||
|
* @param {ID} id
|
||||||
|
* @return {AbstractItem}
|
||||||
|
*/
|
||||||
|
// @ts-ignore
|
||||||
|
export const getItem = (store, id) => find(store, id)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
|
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
|
||||||
*
|
*
|
||||||
|
@ -95,16 +95,16 @@ export class Y extends Observable {
|
|||||||
callEventHandlerListeners(type._dEH, [events, transaction])
|
callEventHandlerListeners(type._dEH, [events, transaction])
|
||||||
})
|
})
|
||||||
// only call afterTransaction listeners if anything changed
|
// only call afterTransaction listeners if anything changed
|
||||||
const transactionChangedContent = transaction.changedParentTypes.size !== 0
|
const transactionChangedContent = transaction.changedParentTypes.size > 0 || transaction.deleteSet.clients.size > 0
|
||||||
if (transactionChangedContent) {
|
if (transactionChangedContent) {
|
||||||
transaction.afterState = getStates(transaction.y.store)
|
transaction.afterState = getStates(transaction.y.store)
|
||||||
// when all changes & events are processed, emit afterTransaction event
|
// when all changes & events are processed, emit afterTransaction event
|
||||||
this.emit('afterTransaction', [this, transaction])
|
|
||||||
// transaction cleanup
|
// transaction cleanup
|
||||||
const store = transaction.y.store
|
const store = transaction.y.store
|
||||||
const ds = transaction.deleteSet
|
const ds = transaction.deleteSet
|
||||||
// replace deleted items with ItemDeleted / GC
|
// replace deleted items with ItemDeleted / GC
|
||||||
sortAndMergeDeleteSet(ds)
|
sortAndMergeDeleteSet(ds)
|
||||||
|
this.emit('afterTransaction', [this, transaction])
|
||||||
/**
|
/**
|
||||||
* @type {Set<ItemDeleted|GC>}
|
* @type {Set<ItemDeleted|GC>}
|
||||||
*/
|
*/
|
||||||
|
@ -63,7 +63,7 @@ export class TestYInstance extends Y.Y {
|
|||||||
this.mMux = createMutex()
|
this.mMux = createMutex()
|
||||||
testConnector.allConns.add(this)
|
testConnector.allConns.add(this)
|
||||||
// set up observe on local model
|
// set up observe on local model
|
||||||
this.on('afterTransaction', afterTransaction)
|
this.on('afterTransactionCleanup', afterTransaction)
|
||||||
this.connect()
|
this.connect()
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user