Items accept origins as IDs

This commit is contained in:
Kevin Jahns
2019-04-05 19:46:18 +02:00
parent 8a7416ad50
commit 7d0c048708
18 changed files with 212 additions and 141 deletions

View File

@@ -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))
}
}
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}
}