Compare origin ids in item.integrate

This commit is contained in:
Kevin Jahns 2019-04-06 15:55:20 +02:00
parent 1b17b5e400
commit c635963747
5 changed files with 36 additions and 9 deletions

View File

@ -12,6 +12,8 @@ import {
addToDeleteSet,
ItemDeleted,
findRootTypeKey,
compareIDs,
getItem,
StructStore, ID, AbstractType, Y, Transaction // eslint-disable-line
} from '../internals.js'
@ -133,6 +135,7 @@ export class AbstractItem extends AbstractStruct {
* @param {Transaction} transaction
*/
integrate (transaction) {
const store = transaction.y.store
const id = this.id
const parent = this.parent
const parentSub = this.parentSub
@ -165,7 +168,13 @@ export class AbstractItem extends AbstractStruct {
} else {
o = parent._start
}
/**
* @type {Set<AbstractItem>}
*/
const conflictingItems = new Set()
/**
* @type {Set<AbstractItem>}
*/
const itemsBeforeOrigin = new Set()
// Let c in conflictingItems, b in itemsBeforeOrigin
// ***{origin}bbbb{this}{c,b}{c,b}{o}***
@ -173,22 +182,22 @@ export class AbstractItem extends AbstractStruct {
while (o !== null && o !== this.right) {
itemsBeforeOrigin.add(o)
conflictingItems.add(o)
if (this.origin === o.origin) {
if (compareIDs(this.origin, o.origin)) {
// case 1
if (o.id.client < id.client) {
this.left = o
conflictingItems.clear()
}
} else if (itemsBeforeOrigin.has(o.origin)) {
} // TODO: verify break else?
} else if (o.origin !== null && itemsBeforeOrigin.has(getItem(store, o.origin))) {
// case 2
if (!conflictingItems.has(o.origin)) {
if (o.origin === null || !conflictingItems.has(getItem(store, o.origin))) {
this.left = o
conflictingItems.clear()
}
} else {
break
}
// TODO: try to use right_origin instead.
// TODO: experiment with rightOrigin.
// Then you could basically omit conflictingItems!
// Note: you probably can't use right_origin in every case.. only when setting _left
o = o.right
@ -220,7 +229,7 @@ export class AbstractItem extends AbstractStruct {
if (parentSub === null && this.countable) {
parent._length += length
}
addStruct(transaction.y.store, this)
addStruct(store, this)
if (parent !== null) {
maplib.setIfUndefined(transaction.changed, parent, set.create).add(parentSub)
}

View File

@ -14,6 +14,7 @@ import {
GC,
splitItem,
compareIDs,
addToDeleteSet,
StructStore, Transaction, ID, AbstractType // eslint-disable-line
} from '../internals.js'
@ -53,6 +54,13 @@ export class ItemDeleted extends AbstractItem {
copy (id, left, origin, right, rightOrigin, parent, parentSub) {
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 {number} diff

View File

@ -125,6 +125,16 @@ export const find = (store, id) => {
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.
*

View File

@ -95,16 +95,16 @@ export class Y extends Observable {
callEventHandlerListeners(type._dEH, [events, transaction])
})
// 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) {
transaction.afterState = getStates(transaction.y.store)
// when all changes & events are processed, emit afterTransaction event
this.emit('afterTransaction', [this, transaction])
// transaction cleanup
const store = transaction.y.store
const ds = transaction.deleteSet
// replace deleted items with ItemDeleted / GC
sortAndMergeDeleteSet(ds)
this.emit('afterTransaction', [this, transaction])
/**
* @type {Set<ItemDeleted|GC>}
*/

View File

@ -63,7 +63,7 @@ export class TestYInstance extends Y.Y {
this.mMux = createMutex()
testConnector.allConns.add(this)
// set up observe on local model
this.on('afterTransaction', afterTransaction)
this.on('afterTransactionCleanup', afterTransaction)
this.connect()
}
/**