fix a bunch of issues with range-move approach
This commit is contained in:
parent
69b7f4bfb9
commit
1f99e8203a
@ -38,10 +38,10 @@ const maxSearchMarker = 80
|
|||||||
export const useSearchMarker = (tr, yarray, index, f) => {
|
export const useSearchMarker = (tr, yarray, index, f) => {
|
||||||
const searchMarker = yarray._searchMarker
|
const searchMarker = yarray._searchMarker
|
||||||
if (searchMarker === null || yarray._start === null) { // @todo add condition `index < 5`
|
if (searchMarker === null || yarray._start === null) { // @todo add condition `index < 5`
|
||||||
return f(new ListIterator(yarray).forward(tr, index))
|
return f(new ListIterator(yarray).forward(tr, index, true))
|
||||||
}
|
}
|
||||||
if (searchMarker.length === 0) {
|
if (searchMarker.length === 0) {
|
||||||
const sm = new ListIterator(yarray).forward(tr, index)
|
const sm = new ListIterator(yarray).forward(tr, index, true)
|
||||||
searchMarker.push(sm)
|
searchMarker.push(sm)
|
||||||
if (sm.nextItem) sm.nextItem.marker = true
|
if (sm.nextItem) sm.nextItem.marker = true
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ export const useSearchMarker = (tr, yarray, index, f) => {
|
|||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
fsm.backward(tr, diff)
|
fsm.backward(tr, diff)
|
||||||
} else {
|
} else {
|
||||||
fsm.forward(tr, -diff)
|
fsm.forward(tr, -diff, true)
|
||||||
}
|
}
|
||||||
// @todo remove this test
|
// @todo remove this test
|
||||||
/*
|
/*
|
||||||
|
@ -144,17 +144,21 @@ export class ListIterator {
|
|||||||
moveTo (tr, index) {
|
moveTo (tr, index) {
|
||||||
const diff = index - this.index
|
const diff = index - this.index
|
||||||
if (diff > 0) {
|
if (diff > 0) {
|
||||||
this.forward(tr, diff)
|
this.forward(tr, diff, true)
|
||||||
} else if (diff < 0) {
|
} else if (diff < 0) {
|
||||||
this.backward(tr, -diff)
|
this.backward(tr, -diff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* When using skipUncountables=false within a "useSearchMarker" call, it is recommended
|
||||||
|
* to move the marker to the end. @todo do this after each useSearchMarkerCall
|
||||||
|
*
|
||||||
* @param {Transaction} tr
|
* @param {Transaction} tr
|
||||||
* @param {number} len
|
* @param {number} len
|
||||||
|
* @param {boolean} skipUncountables Iterate as much as possible iterating over uncountables until we find the next item.
|
||||||
*/
|
*/
|
||||||
forward (tr, len) {
|
forward (tr, len, skipUncountables) {
|
||||||
if (len === 0 && this.nextItem == null) {
|
if (len === 0 && this.nextItem == null) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
@ -168,7 +172,8 @@ export class ListIterator {
|
|||||||
len += this.rel
|
len += this.rel
|
||||||
this.rel = 0
|
this.rel = 0
|
||||||
}
|
}
|
||||||
while ((!this.reachedEnd || this.currMove !== null) && (len > 0 || (len === 0 && item && (!item.countable || item.deleted || item === this.currMoveEnd || (this.reachedEnd && this.currMoveEnd === null) || item.moved !== this.currMove)))) {
|
// eslint-disable-next-line no-unmodified-loop-condition
|
||||||
|
while ((!this.reachedEnd || this.currMove !== null) && (len > 0 || (skipUncountables && len === 0 && item && (!item.countable || item.deleted || item === this.currMoveEnd || (this.reachedEnd && this.currMoveEnd === null) || item.moved !== this.currMove)))) {
|
||||||
if (item === this.currMoveEnd || (this.currMoveEnd === null && this.reachedEnd && this.currMove)) {
|
if (item === this.currMoveEnd || (this.currMoveEnd === null && this.reachedEnd && this.currMove)) {
|
||||||
item = /** @type {Item} */ (this.currMove) // we iterate to the right after the current condition
|
item = /** @type {Item} */ (this.currMove) // we iterate to the right after the current condition
|
||||||
popMovedStack(tr, this)
|
popMovedStack(tr, this)
|
||||||
@ -337,7 +342,7 @@ export class ListIterator {
|
|||||||
if ((!this.reachedEnd || this.currMove !== null) && len > 0) {
|
if ((!this.reachedEnd || this.currMove !== null) && len > 0) {
|
||||||
// always set nextItem before any method call
|
// always set nextItem before any method call
|
||||||
this.nextItem = nextItem
|
this.nextItem = nextItem
|
||||||
this.forward(tr, 0)
|
this.forward(tr, 0, true)
|
||||||
if (this.nextItem == null) {
|
if (this.nextItem == null) {
|
||||||
throw new Error('debug me') // @todo remove
|
throw new Error('debug me') // @todo remove
|
||||||
}
|
}
|
||||||
@ -381,7 +386,7 @@ export class ListIterator {
|
|||||||
}
|
}
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
this.nextItem = item
|
this.nextItem = item
|
||||||
this.forward(tr, 0)
|
this.forward(tr, 0, true)
|
||||||
item = this.nextItem
|
item = this.nextItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -622,7 +627,7 @@ export const getMinimalListViewRanges = (tr, walker, len) => {
|
|||||||
const preItem = /** @type {Item} */ (walker.nextItem)
|
const preItem = /** @type {Item} */ (walker.nextItem)
|
||||||
const preRel = walker.rel
|
const preRel = walker.rel
|
||||||
|
|
||||||
walker.forward(tr, len)
|
walker.forward(tr, len, false)
|
||||||
|
|
||||||
// store the same information for the end, after we iterate forward
|
// store the same information for the end, after we iterate forward
|
||||||
/**
|
/**
|
||||||
@ -630,21 +635,30 @@ export const getMinimalListViewRanges = (tr, walker, len) => {
|
|||||||
*/
|
*/
|
||||||
const afterStack = walker.movedStack.map(si => si.move)
|
const afterStack = walker.movedStack.map(si => si.move)
|
||||||
const afterMove = walker.currMove
|
const afterMove = walker.currMove
|
||||||
const afterItem = /** @type {Item} */ (walker.nextItem)
|
const nextIsCurrMoveStart = walker.nextItem === walker.currMoveStart
|
||||||
const afterRel = walker.rel
|
const afterItem = /** @type {Item} */ (nextIsCurrMoveStart
|
||||||
|
? walker.currMove
|
||||||
|
: (walker.rel > 0 || walker.reachedEnd)
|
||||||
|
? walker.nextItem
|
||||||
|
: /** @type {Item} */ (walker.nextItem).left
|
||||||
|
)
|
||||||
|
/**
|
||||||
|
* afterRel is always > 0
|
||||||
|
*/
|
||||||
|
const afterRel = nextIsCurrMoveStart
|
||||||
|
? 1
|
||||||
|
: walker.rel > 0
|
||||||
|
? walker.rel
|
||||||
|
: afterItem.length
|
||||||
|
|
||||||
|
walker.forward(tr, 0, false) // @todo remove once this is done is useSearchMarker
|
||||||
|
|
||||||
let start = createRelativePosition(walker.type, createID(preItem.id.client, preItem.id.clock + preRel), 0)
|
let start = createRelativePosition(walker.type, createID(preItem.id.client, preItem.id.clock + preRel), 0)
|
||||||
let end = walker.reachedEnd
|
let end = createRelativePosition(
|
||||||
? createRelativePosition(
|
walker.type,
|
||||||
walker.type,
|
createID(afterItem.id.client, afterItem.id.clock + afterRel - 1),
|
||||||
createID(afterItem.id.client, afterItem.id.clock + afterItem.length - 1),
|
-1
|
||||||
-1
|
)
|
||||||
)
|
|
||||||
: createRelativePosition(
|
|
||||||
walker.type,
|
|
||||||
createID(afterItem.id.client, afterItem.id.clock + afterRel),
|
|
||||||
0
|
|
||||||
)
|
|
||||||
|
|
||||||
if (preMove) {
|
if (preMove) {
|
||||||
preStack.push(preMove)
|
preStack.push(preMove)
|
||||||
|
@ -569,7 +569,6 @@ const arrayTransactions = [
|
|||||||
const newPos = _newPosAdj + (_newPosAdj > yarray.length - len ? len : 0)
|
const newPos = _newPosAdj + (_newPosAdj > yarray.length - len ? len : 0)
|
||||||
const oldContent = yarray.toArray()
|
const oldContent = yarray.toArray()
|
||||||
yarray.moveRange(pos, pos + len - 1, newPos)
|
yarray.moveRange(pos, pos + len - 1, newPos)
|
||||||
console.log(`moving range ${pos}-${pos + len - 1} to ${newPos}`)
|
|
||||||
const movedValues = oldContent.splice(pos, len)
|
const movedValues = oldContent.splice(pos, len)
|
||||||
oldContent.splice(pos < newPos ? newPos - len : newPos, 0, ...movedValues)
|
oldContent.splice(pos < newPos ? newPos - len : newPos, 0, ...movedValues)
|
||||||
t.compareArrays(yarray.toArray(), oldContent) // we want to make sure that fastSearch markers insert at the correct position
|
t.compareArrays(yarray.toArray(), oldContent) // we want to make sure that fastSearch markers insert at the correct position
|
||||||
|
Loading…
x
Reference in New Issue
Block a user