Items accept origins as IDs
This commit is contained in:
@@ -60,8 +60,10 @@ export const findIndexDS = (dis, clock) => {
|
||||
return midindex
|
||||
}
|
||||
left = midindex
|
||||
} else {
|
||||
} else if (right !== midindex) {
|
||||
right = midindex
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return null
|
||||
@@ -125,14 +127,16 @@ export const createDeleteSetFromStructStore = ss => {
|
||||
const dsitems = []
|
||||
for (let i = 0; i < structs.length; i++) {
|
||||
const struct = structs[i]
|
||||
const clock = struct.id.clock
|
||||
let len = struct.length
|
||||
if (i + 1 < structs.length) {
|
||||
for (let next = structs[i + 1]; i + 1 < structs.length && next.id.clock === clock + len; i++) {
|
||||
len += next.length
|
||||
if (struct.deleted) {
|
||||
const clock = struct.id.clock
|
||||
let len = struct.length
|
||||
if (i + 1 < structs.length) {
|
||||
for (let next = structs[i + 1]; i + 1 < structs.length && next.id.clock === clock + len; i++) {
|
||||
len += next.length
|
||||
}
|
||||
}
|
||||
dsitems.push(new DeleteItem(clock, len))
|
||||
}
|
||||
dsitems.push(new DeleteItem(clock, len))
|
||||
}
|
||||
if (dsitems.length > 0) {
|
||||
ds.clients.set(client, dsitems)
|
||||
@@ -172,7 +176,7 @@ export const readDeleteSet = (decoder, ss, transaction) => {
|
||||
for (let i = 0; i < len; i++) {
|
||||
const clock = decoding.readVarUint(decoder)
|
||||
const len = decoding.readVarUint(decoder)
|
||||
getItemRange(ss, transaction, client, clock, len).forEach(struct => struct.delete(transaction))
|
||||
getItemRange(ss, client, clock, len).forEach(struct => struct.delete(transaction))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +50,8 @@ export class ID {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ID} a
|
||||
* @param {ID} b
|
||||
* @param {ID | null} a
|
||||
* @param {ID | null} b
|
||||
* @return {boolean}
|
||||
*/
|
||||
export const compareIDs = (a, b) => a === b || (a !== null && b !== null && a.client === b.client && a.clock === b.clock)
|
||||
|
||||
@@ -129,13 +129,12 @@ export const getItemType = (store, id) => find(store, id)
|
||||
/**
|
||||
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
|
||||
* @param {StructStore} store
|
||||
* @param {Transaction} transaction
|
||||
* @param {ID} id
|
||||
* @return {AbstractItem}
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
export const getItemCleanStart = (store, transaction, id) => {
|
||||
export const getItemCleanStart = (store, id) => {
|
||||
/**
|
||||
* @type {Array<AbstractItem>}
|
||||
*/
|
||||
@@ -147,7 +146,7 @@ export const getItemCleanStart = (store, transaction, id) => {
|
||||
*/
|
||||
let struct = structs[index]
|
||||
if (struct.id.clock < id.clock) {
|
||||
struct = struct.splitAt(transaction, id.clock - struct.id.clock)
|
||||
struct = struct.splitAt(store, id.clock - struct.id.clock)
|
||||
structs.splice(index, 0, struct)
|
||||
}
|
||||
return struct
|
||||
@@ -156,13 +155,12 @@ export const getItemCleanStart = (store, transaction, id) => {
|
||||
/**
|
||||
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
|
||||
* @param {StructStore} store
|
||||
* @param {Transaction} transaction
|
||||
* @param {ID} id
|
||||
* @return {AbstractItem}
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
export const getItemCleanEnd = (store, transaction, id) => {
|
||||
export const getItemCleanEnd = (store, id) => {
|
||||
/**
|
||||
* @type {Array<AbstractItem>}
|
||||
*/
|
||||
@@ -171,7 +169,7 @@ export const getItemCleanEnd = (store, transaction, id) => {
|
||||
const index = findIndexSS(structs, id.clock)
|
||||
const struct = structs[index]
|
||||
if (id.clock !== struct.id.clock + struct.length - 1) {
|
||||
structs.splice(index, 0, struct.splitAt(transaction, id.clock - struct.id.clock + 1))
|
||||
structs.splice(index, 0, struct.splitAt(store, id.clock - struct.id.clock + 1))
|
||||
}
|
||||
return struct
|
||||
}
|
||||
@@ -179,7 +177,6 @@ export const getItemCleanEnd = (store, transaction, id) => {
|
||||
/**
|
||||
* Expects that id is actually in store. This function throws or is an infinite loop otherwise.
|
||||
* @param {StructStore} store
|
||||
* @param {Transaction} transaction
|
||||
* @param {number} client
|
||||
* @param {number} clock
|
||||
* @param {number} len
|
||||
@@ -187,7 +184,7 @@ export const getItemCleanEnd = (store, transaction, id) => {
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
export const getItemRange = (store, transaction, client, clock, len) => {
|
||||
export const getItemRange = (store, client, clock, len) => {
|
||||
/**
|
||||
* @type {Array<AbstractItem>}
|
||||
*/
|
||||
@@ -196,17 +193,24 @@ export const getItemRange = (store, transaction, client, clock, len) => {
|
||||
let index = findIndexSS(structs, clock)
|
||||
let struct = structs[index]
|
||||
let range = []
|
||||
if (struct.id.clock < clock) {
|
||||
struct = struct.splitAt(transaction, clock - struct.id.clock)
|
||||
structs.splice(index, 0, struct)
|
||||
}
|
||||
while (struct.id.clock + struct.length <= clock + len) {
|
||||
if (struct.id.clock <= clock) {
|
||||
if (struct.id.clock < clock) {
|
||||
struct = struct.splitAt(store, clock - struct.id.clock)
|
||||
structs.splice(index, 0, struct)
|
||||
}
|
||||
range.push(struct)
|
||||
struct = structs[++index]
|
||||
}
|
||||
if (clock < struct.id.clock + struct.length) {
|
||||
structs.splice(index, 0, struct.splitAt(transaction, clock + len - struct.id.clock))
|
||||
range.push(struct)
|
||||
index++
|
||||
while (index < structs.length) {
|
||||
struct = structs[index++]
|
||||
if (struct.id.clock < clock + len) {
|
||||
range.push(struct)
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
if (struct.id.clock < clock + len && struct.id.clock + struct.length > clock + len) {
|
||||
structs.splice(index, 0, struct.splitAt(store, clock + len - struct.id.clock))
|
||||
}
|
||||
return range
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ export class Transaction {
|
||||
get updateMessage () {
|
||||
if (this._updateMessage === null) {
|
||||
const encoder = encoding.createEncoder()
|
||||
writeStructsFromTransaction(encoder, this)
|
||||
sortAndMergeDeleteSet(this.deleteSet)
|
||||
writeStructsFromTransaction(encoder, this)
|
||||
writeDeleteSet(encoder, this.deleteSet)
|
||||
this._updateMessage = encoder
|
||||
}
|
||||
|
||||
@@ -140,12 +140,13 @@ export const readStructs = (decoder, transaction, store) => {
|
||||
*/
|
||||
const stack = []
|
||||
const localState = getStates(store)
|
||||
let lastStructReader = null
|
||||
for (let i = 0; i < clientbeforeState; i++) {
|
||||
const nextID = readID(decoder)
|
||||
const decoderPos = decoder.pos + decoding.readUint32(decoder)
|
||||
const structReaderDecoder = decoding.clone(decoder, decoderPos)
|
||||
const numberOfStructs = decoding.readVarUint(structReaderDecoder)
|
||||
structReaders.set(nextID.client, createStructReaderIterator(structReaderDecoder, numberOfStructs, nextID, localState.get(nextID.client) || 0))
|
||||
lastStructReader = decoding.clone(decoder, decoderPos)
|
||||
const numberOfStructs = decoding.readVarUint(lastStructReader)
|
||||
structReaders.set(nextID.client, createStructReaderIterator(lastStructReader, numberOfStructs, nextID, localState.get(nextID.client) || 0))
|
||||
}
|
||||
for (const it of structReaders.values()) {
|
||||
// todo try for in of it
|
||||
@@ -172,4 +173,8 @@ export const readStructs = (decoder, transaction, store) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
// if we read some structs, this points to the end of the transaction
|
||||
if (lastStructReader !== null) {
|
||||
decoder.pos = lastStructReader.pos
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user