Implement experimental new encoder 🚀

This commit is contained in:
Kevin Jahns
2020-07-12 18:25:45 +02:00
parent e31e968f0d
commit 6c2cf0f769
36 changed files with 1224 additions and 336 deletions

View File

@@ -1,7 +1,5 @@
import {
readID,
writeID,
GC,
getState,
AbstractStruct,
@@ -23,12 +21,10 @@ import {
readContentFormat,
readContentType,
addChangedTypeToTransaction,
Doc, ContentType, ContentDeleted, StructStore, ID, AbstractType, Transaction // eslint-disable-line
AbstractUpdateDecoder, AbstractUpdateEncoder, ContentType, ContentDeleted, StructStore, ID, AbstractType, Transaction // eslint-disable-line
} from '../internals.js'
import * as error from 'lib0/error.js'
import * as encoding from 'lib0/encoding.js'
import * as decoding from 'lib0/decoding.js'
import * as maplib from 'lib0/map.js'
import * as set from 'lib0/set.js'
import * as binary from 'lib0/binary.js'
@@ -574,7 +570,7 @@ export class Item extends AbstractStruct {
parent._length -= this.length
}
this.markDeleted()
addToDeleteSet(transaction.deleteSet, this.id, this.length)
addToDeleteSet(transaction.deleteSet, this.id.client, this.id.clock, this.length)
maplib.setIfUndefined(transaction.changed, parent, set.create).add(this.parentSub)
this.content.delete(transaction)
}
@@ -602,7 +598,7 @@ export class Item extends AbstractStruct {
*
* This is called when this Item is sent to a remote peer.
*
* @param {encoding.Encoder} encoder The encoder to write data to.
* @param {AbstractUpdateEncoder} encoder The encoder to write data to.
* @param {number} offset
*/
write (encoder, offset) {
@@ -613,12 +609,12 @@ export class Item extends AbstractStruct {
(origin === null ? 0 : binary.BIT8) | // origin is defined
(rightOrigin === null ? 0 : binary.BIT7) | // right origin is defined
(parentSub === null ? 0 : binary.BIT6) // parentSub is non-null
encoding.writeUint8(encoder, info)
encoder.writeInfo(info)
if (origin !== null) {
writeID(encoder, origin)
encoder.writeLeftID(origin)
}
if (rightOrigin !== null) {
writeID(encoder, rightOrigin)
encoder.writeRightID(rightOrigin)
}
if (origin === null && rightOrigin === null) {
const parent = /** @type {AbstractType<any>} */ (this.parent)
@@ -627,14 +623,14 @@ export class Item extends AbstractStruct {
// parent type on y._map
// find the correct key
const ykey = findRootTypeKey(parent)
encoding.writeVarUint(encoder, 1) // write parentYKey
encoding.writeVarString(encoder, ykey)
encoder.writeParentInfo(true) // write parentYKey
encoder.writeString(ykey)
} else {
encoding.writeVarUint(encoder, 0) // write parent id
writeID(encoder, parentItem.id)
encoder.writeParentInfo(false) // write parent id
encoder.writeLeftID(parentItem.id)
}
if (parentSub !== null) {
encoding.writeVarString(encoder, parentSub)
encoder.writeString(parentSub)
}
}
this.content.write(encoder, offset)
@@ -642,15 +638,15 @@ export class Item extends AbstractStruct {
}
/**
* @param {decoding.Decoder} decoder
* @param {AbstractUpdateDecoder} decoder
* @param {number} info
*/
const readItemContent = (decoder, info) => contentRefs[info & binary.BITS5](decoder)
export const readItemContent = (decoder, info) => contentRefs[info & binary.BITS5](decoder)
/**
* A lookup map for reading Item content.
*
* @type {Array<function(decoding.Decoder):AbstractContent>}
* @type {Array<function(AbstractUpdateDecoder):AbstractContent>}
*/
export const contentRefs = [
() => { throw error.unexpectedCase() }, // GC is not ItemContent
@@ -741,7 +737,7 @@ export class AbstractContent {
}
/**
* @param {encoding.Encoder} encoder
* @param {AbstractUpdateEncoder} encoder
* @param {number} offset
*/
write (encoder, offset) {
@@ -755,38 +751,3 @@ export class AbstractContent {
throw error.methodUnimplemented()
}
}
/**
* @param {decoding.Decoder} decoder
* @param {ID} id
* @param {number} info
* @param {Doc} doc
*/
export const readItem = (decoder, id, info, doc) => {
/**
* The item that was originally to the left of this item.
* @type {ID | null}
*/
const origin = (info & binary.BIT8) === binary.BIT8 ? readID(decoder) : null
/**
* The item that was originally to the right of this item.
* @type {ID | null}
*/
const rightOrigin = (info & binary.BIT7) === binary.BIT7 ? readID(decoder) : null
const canCopyParentInfo = (info & (binary.BIT7 | binary.BIT8)) === 0
const hasParentYKey = canCopyParentInfo ? decoding.readVarUint(decoder) === 1 : false
/**
* If parent = null and neither left nor right are defined, then we know that `parent` is child of `y`
* and we read the next string as parentYKey.
* It indicates how we store/retrieve parent from `y.share`
* @type {string|null}
*/
const parentYKey = canCopyParentInfo && hasParentYKey ? decoding.readVarString(decoder) : null
return new Item(
id, null, origin, null, rightOrigin,
canCopyParentInfo && !hasParentYKey ? readID(decoder) : (parentYKey ? doc.get(parentYKey) : null), // parent
canCopyParentInfo && (info & binary.BIT6) === binary.BIT6 ? decoding.readVarString(decoder) : null, // parentSub
/** @type {AbstractContent} */ (readItemContent(decoder, info)) // item content
)
}