Merge deleted items more efficiently.
Previously deleted items were simply added to transaction._mergeStructs. But this inherently inefficient as it will splice the struct store for every item. Now Yjs iterates over transaction.ds and tries to merge structs. It iterates from right to left so merging should be more efficient that before. But more work needs to be done. For example we could set structs[i] = null and filter the structs after merging is done.
This commit is contained in:
@@ -423,6 +423,8 @@ export class AbstractItem extends AbstractStruct {
|
||||
gcChildren (transaction, store) { }
|
||||
|
||||
/**
|
||||
* @todo remove transaction param
|
||||
*
|
||||
* @param {Transaction} transaction
|
||||
* @param {StructStore} store
|
||||
* @param {boolean} parentGCd
|
||||
@@ -430,7 +432,9 @@ export class AbstractItem extends AbstractStruct {
|
||||
* @private
|
||||
*/
|
||||
gc (transaction, store, parentGCd) {
|
||||
this.delete(transaction) // @todo: shouldn't be necessary
|
||||
if (!this.deleted) {
|
||||
throw error.unexpectedCase()
|
||||
}
|
||||
let r
|
||||
if (parentGCd) {
|
||||
r = new GC(this.id, this.length)
|
||||
@@ -448,7 +452,6 @@ export class AbstractItem extends AbstractStruct {
|
||||
}
|
||||
}
|
||||
replaceStruct(store, this, r)
|
||||
transaction._mergeStructs.add(r.id)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -616,7 +619,7 @@ export const computeItemParams = (transaction, store, leftid, rightid, parentid,
|
||||
case GC:
|
||||
break
|
||||
default:
|
||||
if (!parentItem.deleted) {
|
||||
if (!parentItem.deleted && (left === null || left.constructor !== GC) && (right === null || right.constructor !== GC)) {
|
||||
parent = parentItem.type
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,11 +106,22 @@ export class ItemType extends AbstractItem {
|
||||
while (item !== null) {
|
||||
if (!item.deleted) {
|
||||
item.delete(transaction)
|
||||
} else {
|
||||
// Whis will be gc'd later and we want to merge it if possible
|
||||
// We try to merge all deleted items after each transaction,
|
||||
// but we have no knowledge about that this needs to be merged
|
||||
// since it is not in transaction.ds. Hence we add it to transaction._mergeStructs
|
||||
transaction._mergeStructs.add(item.id)
|
||||
}
|
||||
item = item.right
|
||||
}
|
||||
this.type._map.forEach(item => {
|
||||
item.delete(transaction)
|
||||
if (!item.deleted) {
|
||||
item.delete(transaction)
|
||||
} else {
|
||||
// same as above
|
||||
transaction._mergeStructs.add(item.id)
|
||||
}
|
||||
})
|
||||
transaction.changed.delete(this.type)
|
||||
transaction.changedParentTypes.delete(this.type)
|
||||
|
||||
Reference in New Issue
Block a user