duplicate references to the merge target into the struct store

this avoids mutating the struct objects beyond the merge, no additional properties
This commit is contained in:
Noel Levy 2023-07-06 16:28:02 -07:00
parent 17cc6d0226
commit 4305ca2196
2 changed files with 10 additions and 13 deletions

View File

@ -112,7 +112,7 @@ export const addStruct = (store, struct) => {
export const findIndexSS = (structs, clock) => { export const findIndexSS = (structs, clock) => {
let left = 0 let left = 0
let right = structs.length - 1 let right = structs.length - 1
while (/** @type any */(structs[right])._wasMerged) { while (right > 0 && structs[right] === structs[right - 1]) {
right-- right--
} }
let mid = structs[right] let mid = structs[right]
@ -129,7 +129,7 @@ export const findIndexSS = (structs, clock) => {
midclock = mid.id.clock midclock = mid.id.clock
if (midclock <= clock) { if (midclock <= clock) {
if (clock < midclock + mid.length) { if (clock < midclock + mid.length) {
while (/** @type any */(structs[midindex])._wasMerged) { while (midindex > 0 && structs[midindex] === structs[midindex - 1]) {
midindex-- midindex--
} }
return midindex return midindex

View File

@ -184,24 +184,21 @@ const tryToMergeWithLeft = (structs, pos) => {
* @param {Array<AbstractStruct>} structs * @param {Array<AbstractStruct>} structs
* @param {number} pos * @param {number} pos
*/ */
const tryToMergeWithLeftNoSplice = (structs, pos) => { export const tryToMergeWithLeftNoSplice = (structs, pos) => {
const left = structs[pos - 1]
const right = structs[pos] const right = structs[pos]
if (/** @type any */(right)._wasMerged) { if (left === right) {
return 0 return 0
} }
let offset = 1
let left
do {
left = structs[pos - offset++]
} while (/** @type any */(left)._wasMerged)
if (left.deleted === right.deleted && left.constructor === right.constructor) { if (left.deleted === right.deleted && left.constructor === right.constructor) {
if (left.mergeWith(right)) { if (left.mergeWith(right)) {
/** @type any */(right)._wasMerged = true
if (right instanceof Item && right.parentSub !== null && /** @type {AbstractType<any>} */ (right.parent)._map.get(right.parentSub) === right) { if (right instanceof Item && right.parentSub !== null && /** @type {AbstractType<any>} */ (right.parent)._map.get(right.parentSub) === right) {
/** @type {AbstractType<any>} */ (right.parent)._map.set(right.parentSub, /** @type {Item} */ (left)) /** @type {AbstractType<any>} */ (right.parent)._map.set(right.parentSub, /** @type {Item} */ (left))
} }
right.id = left.id let rightPos = pos
right.length = left.length while (structs[rightPos] === right) {
structs[rightPos++] = left
}
return 1 return 1
} }
} }
@ -215,7 +212,7 @@ const tryToMergeWithLeftNoSplice = (structs, pos) => {
const filterMergedStructs = (structs, mergedCount) => { const filterMergedStructs = (structs, mergedCount) => {
let from = 0 let from = 0
for (let to = 0; to < structs.length - mergedCount; to++) { for (let to = 0; to < structs.length - mergedCount; to++) {
while (/** @type any */(structs[from])._wasMerged) { while (structs[from] === structs[from - 1]) {
from++ from++
} }
structs[to] = structs[from] structs[to] = structs[from]