constructor()

in backend/new.js [1655:1728]


  constructor(buffer) {
    this.maxOp = 0
    this.haveHashGraph = false
    this.changes = []
    this.changeIndexByHash = {}
    this.dependenciesByHash = {}
    this.dependentsByHash = {}
    this.hashesByActor = {}
    this.actorIds = []
    this.heads = []
    this.clock = {}
    this.queue = []
    this.objectMeta = {_root: {parentObj: null, parentKey: null, opId: null, type: 'map', children: {}}}

    if (buffer) {
      const doc = decodeDocumentHeader(buffer)
      const {clock, headActors, encoders, numChanges} = readDocumentChanges(doc)
      this.binaryDoc = buffer
      this.changes = new Array(numChanges)
      this.actorIds = doc.actorIds
      this.heads = doc.heads
      this.clock = clock
      this.changesEncoders = encoders
      this.extraBytes = doc.extraBytes

      // If there is a single head, we can unambiguously point at the actorId and sequence number of
      // the head hash without having to reconstruct the hash graph
      if (doc.heads.length === 1 && headActors.length === 1) {
        this.hashesByActor[headActors[0]] = []
        this.hashesByActor[headActors[0]][clock[headActors[0]] - 1] = doc.heads[0]
      }

      // The encoded document gives each change an index, and expresses dependencies in terms of
      // those indexes. Initialise the translation table from hash to index.
      if (doc.heads.length === doc.headsIndexes.length) {
        for (let i = 0; i < doc.heads.length; i++) {
          this.changeIndexByHash[doc.heads[i]] = doc.headsIndexes[i]
        }
      } else if (doc.heads.length === 1) {
        // If there is only one head, it must be the last change
        this.changeIndexByHash[doc.heads[0]] = numChanges - 1
      } else {
        // We know the heads hashes, but not their indexes
        for (let head of doc.heads) this.changeIndexByHash[head] = -1
      }

      this.blocks = [{columns: makeDecoders(doc.opsColumns, DOC_OPS_COLUMNS)}]
      updateBlockMetadata(this.blocks[0], this.actorIds)
      if (this.blocks[0].numOps > MAX_BLOCK_SIZE) {
        this.blocks = splitBlock(this.blocks[0], this.actorIds)
      }

      let docState = {blocks: this.blocks, actorIds: this.actorIds, objectMeta: this.objectMeta, maxOp: 0}
      this.initPatch = documentPatch(docState)
      this.maxOp = docState.maxOp

    } else {
      this.haveHashGraph = true
      this.changesEncoders = DOCUMENT_COLUMNS.map(col => ({columnId: col.columnId, encoder: encoderByColumnId(col.columnId)}))
      this.blocks = [{
        columns: makeDecoders([], DOC_OPS_COLUMNS),
        bloom: new Uint8Array(BLOOM_FILTER_SIZE),
        lastKey: {},
        numVisible: {},
        numOps: 0,
        lastObjectActor: undefined,
        lastObjectCtr: undefined,
        firstVisibleActor: undefined,
        firstVisibleCtr: undefined,
        lastVisibleActor: undefined,
        lastVisibleCtr: undefined
      }]
    }
  }