fixed part of split/merge logic
This commit is contained in:
parent
7a111de186
commit
e1a9f314a7
@ -221,7 +221,7 @@ export class AbstractItem extends AbstractStruct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// adjust the length of parent
|
// adjust the length of parent
|
||||||
if (parentSub === null && this.countable) {
|
if (parentSub === null && this.countable && !this.deleted) {
|
||||||
parent._length += length
|
parent._length += length
|
||||||
}
|
}
|
||||||
addStruct(store, this)
|
addStruct(store, this)
|
||||||
@ -393,8 +393,8 @@ export class AbstractItem extends AbstractStruct {
|
|||||||
mergeWith (right) {
|
mergeWith (right) {
|
||||||
if (compareIDs(right.origin, this.lastId) && this.right === right && compareIDs(this.rightOrigin, right.rightOrigin)) {
|
if (compareIDs(right.origin, this.lastId) && this.right === right && compareIDs(this.rightOrigin, right.rightOrigin)) {
|
||||||
this.right = right.right
|
this.right = right.right
|
||||||
if (right.right !== null) {
|
if (this.right !== null) {
|
||||||
right.right = this
|
this.right.left = this
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -472,28 +472,27 @@ export class AbstractItem extends AbstractStruct {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
write (encoder, offset, encodingRef) {
|
write (encoder, offset, encodingRef) {
|
||||||
|
const origin = offset > 0 ? createID(this.id.client, this.id.clock + offset - 1) : this.origin
|
||||||
|
const rightOrigin = this.rightOrigin
|
||||||
|
const parentSub = this.parentSub
|
||||||
const info = (encodingRef & binary.BITS5) |
|
const info = (encodingRef & binary.BITS5) |
|
||||||
((this.origin === null) ? 0 : binary.BIT8) | // origin is defined
|
(origin === null ? 0 : binary.BIT8) | // origin is defined
|
||||||
((this.rightOrigin === null) ? 0 : binary.BIT7) | // right origin is defined
|
(rightOrigin === null ? 0 : binary.BIT7) | // right origin is defined
|
||||||
((this.parentSub === null) ? 0 : binary.BIT6) // parentSub is non-null
|
(parentSub === null ? 0 : binary.BIT6) // parentSub is non-null
|
||||||
encoding.writeUint8(encoder, info)
|
encoding.writeUint8(encoder, info)
|
||||||
if (this.origin !== null) {
|
if (origin !== null) {
|
||||||
if (offset === 0) {
|
writeID(encoder, origin)
|
||||||
writeID(encoder, this.origin)
|
|
||||||
} else {
|
|
||||||
writeID(encoder, createID(this.id.client, this.id.clock + offset - 1))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (this.rightOrigin !== null) {
|
if (rightOrigin !== null) {
|
||||||
writeID(encoder, this.rightOrigin)
|
writeID(encoder, rightOrigin)
|
||||||
}
|
}
|
||||||
if (this.origin === null && this.rightOrigin === null) {
|
if (origin === null && rightOrigin === null) {
|
||||||
const parent = this.parent
|
const parent = this.parent
|
||||||
if (parent._item === null) {
|
if (parent._item === null) {
|
||||||
// parent type on y._map
|
// parent type on y._map
|
||||||
// find the correct key
|
// find the correct key
|
||||||
// @ts-ignore we know that y exists
|
// @ts-ignore we know that y exists
|
||||||
const ykey = findRootTypeKey(this.parent)
|
const ykey = findRootTypeKey(parent)
|
||||||
encoding.writeVarUint(encoder, 1) // write parentYKey
|
encoding.writeVarUint(encoder, 1) // write parentYKey
|
||||||
encoding.writeVarString(encoder, ykey)
|
encoding.writeVarString(encoder, ykey)
|
||||||
} else {
|
} else {
|
||||||
@ -501,8 +500,8 @@ export class AbstractItem extends AbstractStruct {
|
|||||||
// @ts-ignore _item is defined because parent is integrated
|
// @ts-ignore _item is defined because parent is integrated
|
||||||
writeID(encoder, parent._item.id)
|
writeID(encoder, parent._item.id)
|
||||||
}
|
}
|
||||||
if (this.parentSub !== null) {
|
if (parentSub !== null) {
|
||||||
encoding.writeVarString(encoder, this.parentSub)
|
encoding.writeVarString(encoder, parentSub)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -403,6 +403,7 @@ export const typeArrayInsertGenerics = (transaction, parent, index, content) =>
|
|||||||
* @param {number} length
|
* @param {number} length
|
||||||
*/
|
*/
|
||||||
export const typeArrayDelete = (transaction, parent, index, length) => {
|
export const typeArrayDelete = (transaction, parent, index, length) => {
|
||||||
|
if (length === 0) { return }
|
||||||
let n = parent._start
|
let n = parent._start
|
||||||
// compute the first item to be deleted
|
// compute the first item to be deleted
|
||||||
for (; n !== null; n = n.right) {
|
for (; n !== null; n = n.right) {
|
||||||
|
@ -189,13 +189,11 @@ export const readDeleteSet = (decoder, transaction, store) => {
|
|||||||
* @type {AbstractItem}
|
* @type {AbstractItem}
|
||||||
*/
|
*/
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
let struct = structs[index++]
|
let struct = structs[index]
|
||||||
if (!struct.deleted) {
|
// split the first item if necessary
|
||||||
if (struct.id.clock < clock) {
|
if (!struct.deleted && struct.id.clock < clock) {
|
||||||
struct = struct.splitAt(store, clock - struct.id.clock)
|
structs.splice(index + 1, 0, struct.splitAt(store, clock - struct.id.clock))
|
||||||
structs.splice(index, 0, struct)
|
index++ // increase we now want to use the next struct
|
||||||
}
|
|
||||||
struct.delete(transaction)
|
|
||||||
}
|
}
|
||||||
while (index < structs.length) {
|
while (index < structs.length) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
@ -98,7 +98,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
|
let right = structs.length - 1
|
||||||
while (left <= right) {
|
while (left <= right) {
|
||||||
const midindex = math.floor((left + right) / 2)
|
const midindex = math.floor((left + right) / 2)
|
||||||
const mid = structs[midindex]
|
const mid = structs[midindex]
|
||||||
@ -112,6 +112,8 @@ export const findIndexSS = (structs, clock) => {
|
|||||||
right = midindex - 1
|
right = midindex - 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Always check state before looking for a struct in StructStore
|
||||||
|
// Therefore the case of not finding a struct is unexpected
|
||||||
throw error.unexpectedCase()
|
throw error.unexpectedCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +62,8 @@ export class Y extends Observable {
|
|||||||
* other peers.
|
* other peers.
|
||||||
*
|
*
|
||||||
* @param {function(Transaction):void} f The function that should be executed as a transaction
|
* @param {function(Transaction):void} f The function that should be executed as a transaction
|
||||||
|
*
|
||||||
|
* @todo separate this into a separate function
|
||||||
*/
|
*/
|
||||||
transact (f) {
|
transact (f) {
|
||||||
let initialCall = false
|
let initialCall = false
|
||||||
|
@ -226,6 +226,9 @@ const execStructReaders = (transaction, store, localState, structReaders, stack)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (stack.length > 0) {
|
||||||
|
store.pendingStructReaders.add({ stack, structReaders, missing: stack[stack.length - 1].id })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -322,14 +322,19 @@ export const compareStructStores = (ss1, ss2) => {
|
|||||||
if (s1 instanceof AbstractItem) {
|
if (s1 instanceof AbstractItem) {
|
||||||
if (
|
if (
|
||||||
!(s2 instanceof AbstractItem) ||
|
!(s2 instanceof AbstractItem) ||
|
||||||
!compareItemIDs(s1.left, s2.left) ||
|
!((s1.left === null && s2.left === null) || (s1.left !== null && s2.left !== null && Y.compareIDs(s1.left.lastId, s2.left.lastId))) ||
|
||||||
!compareItemIDs(s1.right, s2.right) ||
|
!compareItemIDs(s1.right, s2.right) ||
|
||||||
!Y.compareIDs(s1.origin, s2.origin) ||
|
!Y.compareIDs(s1.origin, s2.origin) ||
|
||||||
!Y.compareIDs(s1.rightOrigin, s2.rightOrigin) ||
|
!Y.compareIDs(s1.rightOrigin, s2.rightOrigin) ||
|
||||||
s1.parentSub !== s2.parentSub
|
s1.parentSub !== s2.parentSub
|
||||||
) {
|
) {
|
||||||
t.fail('Items dont match')
|
return t.fail('Items dont match')
|
||||||
}
|
}
|
||||||
|
// make sure that items are connected correctly
|
||||||
|
t.assert(s1.left === null || s1.left.right === s1)
|
||||||
|
t.assert(s1.right === null || s1.right.left === s1)
|
||||||
|
t.assert(s2.left === null || s2.left.right === s2)
|
||||||
|
t.assert(s2.right === null || s2.right.left === s2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -310,7 +310,7 @@ const arrayTransactions = [
|
|||||||
* @param {t.TestCase} tc
|
* @param {t.TestCase} tc
|
||||||
*/
|
*/
|
||||||
export const testRepeatGeneratingYarrayTests20 = tc => {
|
export const testRepeatGeneratingYarrayTests20 = tc => {
|
||||||
applyRandomTests(tc, arrayTransactions, 2)
|
applyRandomTests(tc, arrayTransactions, 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user