type._map points to the last element instead to enable merging of deletes in Map
This commit is contained in:
@@ -140,6 +140,9 @@ export class AbstractItem extends AbstractStruct {
|
||||
o = this.left.right
|
||||
} else if (parentSub !== null) {
|
||||
o = parent._map.get(parentSub) || null
|
||||
while (o !== null && o.left !== null) {
|
||||
o = o.left
|
||||
}
|
||||
} else {
|
||||
o = parent._start
|
||||
}
|
||||
@@ -180,39 +183,39 @@ export class AbstractItem extends AbstractStruct {
|
||||
const right = this.left.right
|
||||
this.right = right
|
||||
this.left.right = this
|
||||
if (right !== null) {
|
||||
right.left = this
|
||||
}
|
||||
} else {
|
||||
let r
|
||||
if (parentSub !== null) {
|
||||
const pmap = parent._map
|
||||
r = pmap.get(parentSub) || null
|
||||
pmap.set(parentSub, this)
|
||||
r = parent._map.get(parentSub) || null
|
||||
while (r !== null && r.left !== null) {
|
||||
r = r.left
|
||||
}
|
||||
} else {
|
||||
r = parent._start
|
||||
parent._start = this
|
||||
}
|
||||
this.right = r
|
||||
if (r !== null) {
|
||||
r.left = this
|
||||
}
|
||||
if (this.right !== null) {
|
||||
this.right.left = this
|
||||
} else if (parentSub !== null) {
|
||||
// set as current parent value if right === null and this is parentSub
|
||||
parent._map.set(parentSub, this)
|
||||
if (this.left !== null) {
|
||||
// this is the current attribute value of parent. delete right
|
||||
this.left.delete(transaction)
|
||||
}
|
||||
}
|
||||
// adjust the length of parent
|
||||
// adjust length of parent
|
||||
if (parentSub === null && this.countable && !this.deleted) {
|
||||
parent._length += length
|
||||
}
|
||||
addStruct(store, this)
|
||||
if (parent !== null) {
|
||||
maplib.setIfUndefined(transaction.changed, parent, set.create).add(parentSub)
|
||||
}
|
||||
maplib.setIfUndefined(transaction.changed, parent, set.create).add(parentSub)
|
||||
// @ts-ignore
|
||||
if ((parent._item !== null && parent._item.deleted) || (this.left !== null && parentSub !== null)) {
|
||||
if ((parent._item !== null && parent._item.deleted) || (this.right !== null && parentSub !== null)) {
|
||||
// delete if parent is deleted or if this is not the current attribute value of parent
|
||||
this.delete(transaction)
|
||||
} else if (parentSub !== null && this.left === null && this.right !== null) {
|
||||
// this is the current attribute value of parent. delete right
|
||||
this.right.delete(transaction)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,9 +284,9 @@ export class AbstractItem extends AbstractStruct {
|
||||
left = this.left
|
||||
right = this
|
||||
} else {
|
||||
// Is a map item. Insert at the start
|
||||
left = null
|
||||
right = parent.type._map.get(this.parentSub)
|
||||
// Is a map item. Insert as current value
|
||||
left = parent.type._map.get(this.parentSub)
|
||||
right = null
|
||||
}
|
||||
// make sure that parent is redone
|
||||
if (parent._deleted === true && parent.redone === null) {
|
||||
@@ -308,7 +311,7 @@ export class AbstractItem extends AbstractStruct {
|
||||
if (right.redone !== null && right.redone.parent === parent) {
|
||||
right = right.redone
|
||||
}
|
||||
right = right._right
|
||||
right = right.right
|
||||
}
|
||||
}
|
||||
this.redone = this.copy(nextID(transaction), left, left === null ? null : left.lastId, right, right === null ? null : right.id, parent, this.parentSub)
|
||||
@@ -411,18 +414,15 @@ export class AbstractItem extends AbstractStruct {
|
||||
r = new GC(this.id, this.length)
|
||||
} else {
|
||||
r = new ItemDeleted(this.id, this.left, this.origin, this.right, this.rightOrigin, this.parent, this.parentSub, this.length)
|
||||
if (r.left !== null) {
|
||||
r.left.right = r
|
||||
}
|
||||
if (r.right !== null) {
|
||||
r.right.left = r
|
||||
} else if (r.parentSub !== null) {
|
||||
r.parent._map.set(r.parentSub, r)
|
||||
}
|
||||
if (r.left === null) {
|
||||
if (r.parentSub === null) {
|
||||
r.parent._start = r
|
||||
} else {
|
||||
r.parent._map.set(r.parentSub, r)
|
||||
}
|
||||
if (r.left !== null) {
|
||||
r.left.right = r
|
||||
} else if (r.parentSub === null) {
|
||||
r.parent._start = r
|
||||
}
|
||||
}
|
||||
replaceStruct(store, this, r)
|
||||
|
||||
@@ -21,18 +21,6 @@ import {
|
||||
import * as encoding from 'lib0/encoding.js' // eslint-disable-line
|
||||
import * as decoding from 'lib0/decoding.js'
|
||||
|
||||
/**
|
||||
* @param {Transaction} transaction
|
||||
* @param {StructStore} store
|
||||
* @param {AbstractItem | null} item
|
||||
*/
|
||||
const gcChildren = (transaction, store, item) => {
|
||||
while (item !== null) {
|
||||
item.gc(transaction, store)
|
||||
item = item.right
|
||||
}
|
||||
}
|
||||
|
||||
export const structTypeRefNumber = 7
|
||||
|
||||
/**
|
||||
@@ -113,23 +101,7 @@ export class ItemType extends AbstractItem {
|
||||
super.delete(transaction)
|
||||
transaction.changed.delete(this.type)
|
||||
transaction.changedParentTypes.delete(this.type)
|
||||
// delete map types
|
||||
for (let value of this.type._map.values()) {
|
||||
if (!value.deleted) {
|
||||
value.delete(transaction)
|
||||
}
|
||||
}
|
||||
// delete array types
|
||||
let t = this.type._start
|
||||
while (t !== null) {
|
||||
if (!t.deleted) {
|
||||
t.delete(transaction)
|
||||
}
|
||||
t = t.right
|
||||
}
|
||||
if (gcChildren) {
|
||||
this.gcChildren(transaction, transaction.y.store)
|
||||
}
|
||||
this.gcChildren(transaction, transaction.y.store)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,10 +109,18 @@ export class ItemType extends AbstractItem {
|
||||
* @param {StructStore} store
|
||||
*/
|
||||
gcChildren (transaction, store) {
|
||||
gcChildren(transaction, store, this.type._start)
|
||||
let item = this.type._start
|
||||
while (item !== null) {
|
||||
item.gc(transaction, store)
|
||||
item = item.right
|
||||
}
|
||||
this.type._start = null
|
||||
this.type._map.forEach(item => {
|
||||
gcChildren(transaction, store, item)
|
||||
while (item !== null) {
|
||||
item.gc(transaction, store)
|
||||
// @ts-ignore
|
||||
item = item.left
|
||||
}
|
||||
})
|
||||
this._map = new Map()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user