@fluidframework/merge-tree 2.74.0 → 2.81.0-374083

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/collections/rbTree.d.ts.map +1 -1
  3. package/dist/collections/rbTree.js +2 -0
  4. package/dist/collections/rbTree.js.map +1 -1
  5. package/dist/localReference.d.ts.map +1 -1
  6. package/dist/localReference.js +1 -0
  7. package/dist/localReference.js.map +1 -1
  8. package/dist/partialLengths.d.ts.map +1 -1
  9. package/dist/partialLengths.js +3 -0
  10. package/dist/partialLengths.js.map +1 -1
  11. package/dist/properties.d.ts.map +1 -1
  12. package/dist/properties.js +1 -0
  13. package/dist/properties.js.map +1 -1
  14. package/dist/test/Snapshot.perf.spec.js +6 -1
  15. package/dist/test/Snapshot.perf.spec.js.map +1 -1
  16. package/dist/test/beastTest.spec.d.ts.map +1 -1
  17. package/dist/test/beastTest.spec.js +2 -0
  18. package/dist/test/beastTest.spec.js.map +1 -1
  19. package/dist/test/client.rollback.spec.js +2 -0
  20. package/dist/test/client.rollback.spec.js.map +1 -1
  21. package/eslint.config.mts +4 -4
  22. package/lib/collections/rbTree.d.ts.map +1 -1
  23. package/lib/collections/rbTree.js +2 -0
  24. package/lib/collections/rbTree.js.map +1 -1
  25. package/lib/localReference.d.ts.map +1 -1
  26. package/lib/localReference.js +1 -0
  27. package/lib/localReference.js.map +1 -1
  28. package/lib/partialLengths.d.ts.map +1 -1
  29. package/lib/partialLengths.js +3 -0
  30. package/lib/partialLengths.js.map +1 -1
  31. package/lib/properties.d.ts.map +1 -1
  32. package/lib/properties.js +1 -0
  33. package/lib/properties.js.map +1 -1
  34. package/lib/test/Snapshot.perf.spec.js +6 -1
  35. package/lib/test/Snapshot.perf.spec.js.map +1 -1
  36. package/lib/test/beastTest.spec.d.ts.map +1 -1
  37. package/lib/test/beastTest.spec.js +2 -0
  38. package/lib/test/beastTest.spec.js.map +1 -1
  39. package/lib/test/client.rollback.spec.js +2 -0
  40. package/lib/test/client.rollback.spec.js.map +1 -1
  41. package/package.json +25 -25
  42. package/src/collections/rbTree.ts +2 -0
  43. package/src/localReference.ts +1 -0
  44. package/src/partialLengths.ts +3 -0
  45. package/src/properties.ts +1 -0
  46. package/.eslintrc.cjs +0 -19
@@ -1 +1 @@
1
- {"version":3,"file":"partialLengths.js","sourceRoot":"","sources":["../src/partialLengths.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport type { MergeTree } from \"./mergeTree.js\";\nimport {\n\ttype CollaborationWindow,\n\tgetMinSeqStamp,\n\ttype IMergeNode,\n\ttype ISegmentPrivate,\n\ttype MergeBlock,\n} from \"./mergeTreeNodes.js\";\nimport {\n\tLocalDefaultPerspective,\n\tLocalReconnectingPerspective,\n\tPriorPerspective,\n} from \"./perspective.js\";\nimport { toRemovalInfo, assertInserted, wasRemovedOnInsert } from \"./segmentInfos.js\";\nimport { SortedSet } from \"./sortedSet.js\";\nimport * as opstampUtils from \"./stamps.js\";\n\nclass PartialSequenceLengthsSet extends SortedSet<PartialSequenceLength> {\n\tprotected compare(a: PartialSequenceLength, b: PartialSequenceLength): number {\n\t\treturn a.seq - b.seq;\n\t}\n\n\tpublic addOrUpdate(\n\t\tnewItem: PartialSequenceLength,\n\t\tupdate?: (existingItem: PartialSequenceLength, newItem: PartialSequenceLength) => void,\n\t): void {\n\t\tif (newItem.seglen === 0) {\n\t\t\t// Don't bother doing any updates for deltas of 0.\n\t\t\treturn;\n\t\t}\n\t\tconst prev = this.latestLeq(newItem.seq);\n\n\t\tif (prev?.seq !== newItem.seq) {\n\t\t\t// new element, update len\n\t\t\tnewItem.len = (prev?.len ?? 0) + newItem.seglen;\n\t\t}\n\n\t\t// update the len of all following elements\n\t\tfor (let i = this.sortedItems.length - 1; i >= 0; i--) {\n\t\t\tconst element = this.sortedItems[i];\n\t\t\tif (!element || element.seq <= newItem.seq) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\telement.len += newItem.seglen;\n\t\t}\n\n\t\tsuper.addOrUpdate(newItem, (currentPartial, partialLength) => {\n\t\t\tassert(\n\t\t\t\tpartialLength.clientId === currentPartial.clientId,\n\t\t\t\t0xab6 /* clientId mismatch */,\n\t\t\t);\n\t\t\tcurrentPartial.seglen += partialLength.seglen;\n\t\t\tcurrentPartial.len += partialLength.seglen;\n\t\t});\n\t}\n\n\t/**\n\t * Returns the partial length whose sequence number is the greatest sequence\n\t * number that is less than or equal to key.\n\t * @param key - sequence number\n\t */\n\tlatestLeq(key: number): PartialSequenceLength | undefined {\n\t\treturn this.sortedItems[this.latestLeqIndex(key)];\n\t}\n\n\t/**\n\t * Returns the partial length whose sequence number is the lowest sequence\n\t * number that is greater than or equal to key.\n\t * @param key - sequence number\n\t */\n\tfirstGte(key: number): PartialSequenceLength | undefined {\n\t\tconst { index } = this.findItemPosition({ seq: key, len: 0, seglen: 0 });\n\t\treturn this.sortedItems[index];\n\t}\n\n\tprivate latestLeqIndex(key: number): number {\n\t\tconst { exists, index } = this.findItemPosition({ seq: key, len: 0, seglen: 0 });\n\t\treturn exists ? index : index - 1;\n\t}\n\n\tcopyDown(minSeq: number): number {\n\t\tconst mindex = this.latestLeqIndex(minSeq);\n\t\tlet minLength = 0;\n\t\tif (mindex >= 0) {\n\t\t\tminLength = this.sortedItems[mindex].len;\n\t\t\tconst seqCount = this.size;\n\t\t\tif (mindex <= seqCount - 1) {\n\t\t\t\t// Still some entries remaining\n\t\t\t\tconst remainingCount = seqCount - mindex - 1;\n\t\t\t\t// Copy down\n\t\t\t\tfor (let i = 0; i < remainingCount; i++) {\n\t\t\t\t\tthis.sortedItems[i] = this.sortedItems[i + mindex + 1];\n\t\t\t\t\tthis.sortedItems[i].len -= minLength;\n\t\t\t\t}\n\t\t\t\tthis.sortedItems.length = remainingCount;\n\t\t\t}\n\t\t}\n\t\treturn minLength;\n\t}\n}\n\n/**\n * Tracks length information for a part of a MergeTree (block) at a given time (seq).\n * These objects are associated with internal nodes (i.e. blocks).\n */\nexport interface PartialSequenceLength {\n\t/**\n\t * Sequence number\n\t */\n\tseq: number;\n\t/**\n\t * The length of the associated block.\n\t */\n\tlen: number;\n\t/**\n\t * The delta between the current length of the associated block and its length at the previous seq number.\n\t */\n\tseglen: number;\n\t/**\n\t * clientId for the client that submitted the op with sequence number `seq`.\n\t */\n\tclientId?: number;\n}\n\ninterface UnsequencedPartialLengthInfo {\n\t/**\n\t * Contains entries for all local operations.\n\t * The \"seq\" field of each entry actually corresponds to the delta at that localSeq on the local client.\n\t *\n\t * The length entries in this set are analogous to `PartialSequenceLengths.partialLengths` in that they represent the delta over the min seq\n\t * that an observer client would see if they were to observe the local client's edits performed from the minSeq.\n\t */\n\tpartialLengths: PartialSequenceLengthsSet;\n\n\t/**\n\t * Like PerClientAdjustments, except we store one set of PartialSequenceLengthsSet for each refSeq. The \"seq\" keys in these sets\n\t * are all local seqs.\n\t *\n\t * These entries are aggregated by {@link PartialSequenceLengths.computeOverallRefSeqAdjustment} when a local perspective for a\n\t * given refSeq is requested.\n\t *\n\t * In general, adjustments in this map are added to avoid double-counting an operation performed by both the local client and some\n\t * remote client, and an adjustment at (refSeq = A, clientSeq = B) takes effect for all perspectives (refSeq = C, clientSeq = D) where\n\t * A \\<= C and B \\<= D.\n\t */\n\tperRefSeqAdjustments: Map<number, PartialSequenceLengthsSet>;\n\n\t/**\n\t * Cache keyed on refSeq which stores length information for the total overlap of removed segments at\n\t * that refSeq.\n\t * This information is derivable from the entries of `perRefSeqAdjustments`.\n\t *\n\t * Like the `partialLengths` field, `seq` on each entry is actually the local seq.\n\t * See `computeOverallRefSeqAdjustment` for more information.\n\t */\n\tcachedAdjustmentByRefSeq: Map<number, PartialSequenceLengthsSet>;\n}\n\nexport interface PartialSequenceLengthsOptions {\n\tverifier?: (partialLengths: PartialSequenceLengths) => void;\n\tverifyExpected?: (\n\t\tmergeTree: MergeTree,\n\t\tnode: MergeBlock,\n\t\trefSeq: number,\n\t\tclientId: number,\n\t\tlocalSeq?: number,\n\t) => void;\n\tzamboni: boolean;\n}\n\n/**\n * Keeps track of partial sums of segment lengths for all sequence numbers in the current collaboration window.\n * Only used during active collaboration.\n *\n * This class is associated with an internal node (block) of a MergeTree. It efficiently answers queries of the form\n * \"What is the length of `block` from the perspective of some particular seq and clientId?\".\n *\n * It also supports incremental updating of state for newly-sequenced ops that don't affect the structure of the\n * MergeTree (in most cases--see AB#31003 or comments on {@link PartialSequenceLengths.update}).\n *\n * To answer these queries, it pre-builds several lists which track the length of the block at a per-sequence-number\n * level. These lists are:\n *\n * 1. (`partialLengths`): Stores the total length of the block.\n * 2. (`perClientAdjustments[clientId]`): Stores adjustments to the base length which account for all changes submitted by `clientId`. [see footnote]\n *\n * The reason both lists are necessary is that resolving the length of the block from the perspective of\n * (clientId, refSeq) requires including both of the following types of segments:\n * 1. Segments sequenced before `refSeq`\n * 2. Segments submitted by `clientId`\n *\n * This is possible with the above bookkeeping, using:\n *\n * (length of the block at the minimum sequence number)\n * + (partialLengths total length at refSeq)\n * + (clientSeqNumbers total length at most recent op)\n * - (clientSeqNumbers total length at refSeq)\n *\n * where the subtraction avoids double-counting segments submitted by clientId sequenced within the collab window.\n *\n * To enable reconnect, if constructed with `computeLocalPartials === true` it also supports querying for the length of\n * the block from the perspective of the local client at a particular `refSeq` and `localSeq`. This computation is\n * similar to the above:\n *\n * (length of the block at the minimum sequence number)\n * + (partialLengths total length at refSeq)\n * + (unsequenced edits' total length submitted before localSeq)\n * + (adjustments for changes double-counted by happening at or before both localSeq and refSeq)\n *\n * This algorithm scales roughly linearly with number of editing clients and the size of the collab window.\n * (certain unlikely sequences of operations may introduce log factors on those variables)\n *\n * @privateRemarks\n * If you are looking to understand this class in more detail, a suggested order of internalization is:\n *\n * 1. The above description and how it relates to the implementation of `getPartialLength` (which implements the above high-level description\n * 2. `PartialSequenceLengthsSet`, which allows binary searching for overall length deltas at a given sequence number and handles updates.\n * 3. The `fromLeaves` method, which is the base case for the [potential] recursion in `combine`\n * 4. The logic in `combine` to aggregate smaller block entries into larger ones\n * 5. The incremental code path of `update`\n */\nexport class PartialSequenceLengths {\n\tpublic static options: PartialSequenceLengthsOptions = {\n\t\tzamboni: true,\n\t};\n\n\t/**\n\t * Length of the block this PartialSequenceLength corresponds to when viewed at `minSeq`.\n\t */\n\tprivate minLength = 0;\n\n\t/**\n\t * Total number of segments in the subtree rooted at the block this PartialSequenceLength corresponds to.\n\t */\n\tprivate segmentCount = 0;\n\n\t/**\n\t * List of PartialSequenceLength objects--ordered by increasing seq--giving length information about\n\t * the block associated with this PartialSequenceLengths object.\n\t *\n\t * `minLength + partialLengths[i].len` gives the length of this block when considering the perspective of an observer\n\t * client who has received edits up to (and including) sequence number `i`.\n\t */\n\tprivate readonly partialLengths: PartialSequenceLengthsSet = new PartialSequenceLengthsSet();\n\n\t/**\n\t * perClientAdjustments[clientId] contains a PartialSequenceLengthsSet of adjustments to the observer client's\n\t * perspective (see {@link PartialSequenceLengths.partialLengths}) necessary to account for changes made by\n\t * that client.\n\t *\n\t * As per doc comment on {@link PartialSequenceLengths}, the overall adjustment performed for the perspective of\n\t * (clientId, refSeq) is given by the sum of length deltas in `perClientAdjustments[clientId]`\n\t * for all sequence numbers S such that S \\>= refSeq.\n\t *\n\t * (since these are ordered by sequence number and we cache cumulative sums, this is implemented using two lookups and a subtraction).\n\t *\n\t * The specific adjustments are roughly categorized as follows:\n\t *\n\t * - Ops submitted by a given client generally receive a partial lengths entry corresponding to their sequence number.\n\t * e.g. insert of \"ABC\" at seq 5 will have a per-client adjustment entry of \\{ seq: 5, seglen: 3 \\}.\n\t *\n\t * - When client A deletes a segment concurrently with client B and loses the race (B's delete is sequenced first),\n\t * A's per-client adjustments will contain an entry with a negative `seglen` corresponding to the length of the segment\n\t * and a sequence number corresponding to that of B's delete. It will *not* receive a per-client adjustment for its own delete.\n\t * This ensures that for perspectives (A, refSeq), the deleted segment will show up as a negative delta for all values of refSeq, since:\n\t * 1. For refSeq \\< B's delete, the per-client adjustment will apply and be added to the total length\n\t * 2. For refSeq \\>= B's delete, B's partial length entry in the overall set will apply, and the per-client adjustment will not apply\n\t *\n\t * - When client A attempts to insert a segment into a location that is concurrently obliterated by client B immediately upon insertion,\n\t * A's per-client adjustments will again not include an entry for its own insert.\n\t * Instead, the entry which would normally contain `seq` equal to that of A's insert would instead have `seq` equal to that of B's obliterate.\n\t * This gives the overall correct behavior: for any perspective which isn't client A, there is no adjustment necessary anywhere (it's as if\n\t * the segment never existed). For client A's perspective, the segment should be considered visible until A has acked B's obliterate.\n\t * This is accomplished as for the perspective (A, refSeq):\n\t * 1. For refSeq \\< B's obliterate, the segment length will be included as part of the per-client adjustment for A\n\t * 2. For refSeq \\>= B's obliterate, the segment will be omitted from the per-client adjustment for A\n\t *\n\t * Note that the special-casing for inserting segments that are immediately obliterated is only necessary for segments that never were visible\n\t * in the tree. If an insert and obliterate are concurrent but the insert is sequenced first, the normal per-client adjustment is fine.\n\t *\n\t * The second case (overlapping removal) applies to any combination of remove / obliterate operations.\n\t */\n\tprivate readonly perClientAdjustments: PartialSequenceLengthsSet[] = [];\n\n\t/**\n\t * Contains information required to answer queries for the length of this segment from the perspective of\n\t * the local client but not including all local segments (i.e., `localSeq !== collabWindow.localSeq`).\n\t * This field is only computed if requested in the constructor (i.e. `computeLocalPartials === true`).\n\t *\n\t * Note that the usage pattern for this list is a bit different from perClientAdjustments: when dealing with perspectives of remote clients,\n\t * we generally want to know what their view of the block was accounting for all changes made by that client as well as all \\<= some refSeq.\n\t *\n\t * However, when dealing with perspectives relevant to the local client, we are still interested in changes made \\<= some refSeq, but instead\n\t * of caring about all changes made by the local client, we additionally want the subset of them that were made \\<= some localSeq.\n\t *\n\t * The PartialSequenceLengthsSets stored in this field therefore track localSeqs rather than seqs (it's still named seq for ease of implementation).\n\t * Furthermore, when computing the length of the block at a given refSeq/localSeq perspective,\n\t * rather than add something like `perClientAdjustments[clientId].latestLeq(latestSeq) - perClientAdjustments[clientId].latestLeq(refSeq)` [to\n\t * get the tail end of adjustments necessary for a remote client client], we instead add `unsequencedRecords.partialLengths.latestLeq(localSeq)`\n\t * [to get the head end of adjustments necessary for the local client].\n\t */\n\tprivate unsequencedRecords: UnsequencedPartialLengthInfo | undefined;\n\n\tconstructor(\n\t\t/**\n\t\t * The minimumSequenceNumber as defined by the collab window used in the last call to `update`,\n\t\t * or if no such calls have been made, the one used on construction.\n\t\t */\n\t\tpublic minSeq: number,\n\t\tcomputeLocalPartials: boolean,\n\t) {\n\t\tif (computeLocalPartials) {\n\t\t\tthis.unsequencedRecords = {\n\t\t\t\tpartialLengths: new PartialSequenceLengthsSet(),\n\t\t\t\tperRefSeqAdjustments: new Map(),\n\t\t\t\tcachedAdjustmentByRefSeq: new Map(),\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Combine the partial lengths of block's children\n\t * @param block - an interior node. If `recur` is false, it is assumed that each interior node child of this block\n\t * has its partials up to date.\n\t * @param collabWindow - segment window of the segment tree containing `block`.\n\t * @param recur - whether to recursively compute partial lengths for internal children of `block`.\n\t * This incurs more work, but gives correct bookkeeping in the case that a descendant in the merge tree has been\n\t * modified without bubbling up the resulting partial length change to this block's partials.\n\t * @param computeLocalPartials - whether to compute partial length information about local unsequenced ops.\n\t * This enables querying for the length of the block at a given localSeq, but incurs extra work.\n\t * Local partial information doesn't support `update`.\n\t */\n\tpublic static combine(\n\t\tblock: MergeBlock,\n\t\tcollabWindow: CollaborationWindow,\n\t\trecur = false,\n\t\tcomputeLocalPartials = false,\n\t): PartialSequenceLengths {\n\t\tconst leafPartialLengths = PartialSequenceLengths.fromLeaves(\n\t\t\tblock,\n\t\t\tcollabWindow,\n\t\t\tcomputeLocalPartials,\n\t\t);\n\n\t\tlet hasInternalChild = false;\n\t\tconst childPartials: PartialSequenceLengths[] = [];\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tif (!child.isLeaf()) {\n\t\t\t\thasInternalChild = true;\n\t\t\t\tif (recur) {\n\t\t\t\t\tchild.partialLengths = PartialSequenceLengths.combine(\n\t\t\t\t\t\tchild,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tcomputeLocalPartials,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tchildPartials.push(child.partialLengths!);\n\t\t\t}\n\t\t}\n\n\t\t// If there are no internal children, the PartialSequenceLengths returns from `fromLeaves` is exactly correct.\n\t\t// Otherwise, we must additively combine all of the children partial lengths to get this block's totals.\n\t\tconst combinedPartialLengths = hasInternalChild\n\t\t\t? new PartialSequenceLengths(collabWindow.minSeq, computeLocalPartials)\n\t\t\t: leafPartialLengths;\n\t\tif (hasInternalChild) {\n\t\t\tif (leafPartialLengths.partialLengths.size > 0) {\n\t\t\t\t// Some children were leaves; add combined partials from these segments\n\t\t\t\tchildPartials.push(leafPartialLengths);\n\t\t\t}\n\n\t\t\tconst childPartialsLen = childPartials.length;\n\n\t\t\tconst childPartialLengths: PartialSequenceLength[][] = [];\n\t\t\tconst childUnsequencedPartialLengths: PartialSequenceLength[][] = [];\n\t\t\tconst childPerRefSeqAdjustments: Map<number, PartialSequenceLengthsSet>[] = [];\n\t\t\tfor (let i = 0; i < childPartialsLen; i++) {\n\t\t\t\tconst { segmentCount, minLength, partialLengths, unsequencedRecords } =\n\t\t\t\t\tchildPartials[i];\n\t\t\t\tcombinedPartialLengths.segmentCount += segmentCount;\n\t\t\t\tcombinedPartialLengths.minLength += minLength;\n\t\t\t\tchildPartialLengths.push(partialLengths.items as PartialSequenceLength[]);\n\t\t\t\tif (unsequencedRecords) {\n\t\t\t\t\tchildUnsequencedPartialLengths.push(\n\t\t\t\t\t\tunsequencedRecords.partialLengths.items as PartialSequenceLength[],\n\t\t\t\t\t);\n\t\t\t\t\tchildPerRefSeqAdjustments.push(unsequencedRecords.perRefSeqAdjustments);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmergePartialLengths(childPartialLengths, combinedPartialLengths.partialLengths);\n\n\t\t\tif (computeLocalPartials) {\n\t\t\t\tcombinedPartialLengths.unsequencedRecords = {\n\t\t\t\t\tpartialLengths: mergePartialLengths(childUnsequencedPartialLengths),\n\t\t\t\t\tcachedAdjustmentByRefSeq: new Map(),\n\t\t\t\t\tperRefSeqAdjustments: new Map(),\n\t\t\t\t};\n\n\t\t\t\tfor (const perRefSeq of childPerRefSeqAdjustments) {\n\t\t\t\t\tfor (const [refSeq, partials] of perRefSeq) {\n\t\t\t\t\t\tlet combinedPartials =\n\t\t\t\t\t\t\tcombinedPartialLengths.unsequencedRecords.perRefSeqAdjustments.get(refSeq);\n\t\t\t\t\t\tif (combinedPartials === undefined) {\n\t\t\t\t\t\t\tcombinedPartials = new PartialSequenceLengthsSet();\n\t\t\t\t\t\t\tcombinedPartialLengths.unsequencedRecords.perRefSeqAdjustments.set(\n\t\t\t\t\t\t\t\trefSeq,\n\t\t\t\t\t\t\t\tcombinedPartials,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const item of partials.items) {\n\t\t\t\t\t\t\tcombinedPartials.addOrUpdate({ ...item });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// could merge these like we do above rather than do out of order like this\n\t\t\tfor (let i = 0; i < childPartialsLen; i++) {\n\t\t\t\tconst { perClientAdjustments } = childPartials[i];\n\t\t\t\tif (perClientAdjustments.length > 0) {\n\t\t\t\t\tfor (let clientId = 0; clientId < perClientAdjustments.length; clientId++) {\n\t\t\t\t\t\tconst clientAdjustment = perClientAdjustments[clientId];\n\t\t\t\t\t\tif (clientAdjustment === undefined) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (const partial of perClientAdjustments[clientId].items) {\n\t\t\t\t\t\t\tcombinedPartialLengths.addClientAdjustment(\n\t\t\t\t\t\t\t\tclientId,\n\t\t\t\t\t\t\t\tpartial.seq,\n\t\t\t\t\t\t\t\tpartial.seglen,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// TODO: incremental zamboni during build\n\t\tif (PartialSequenceLengths.options.zamboni) {\n\t\t\tcombinedPartialLengths.zamboni(collabWindow);\n\t\t}\n\n\t\tPartialSequenceLengths.options.verifier?.(combinedPartialLengths);\n\t\treturn combinedPartialLengths;\n\t}\n\n\t/**\n\t * Create a `PartialSequenceLengths` which tracks only changes incurred by direct child leaves of `block`.\n\t */\n\tprivate static fromLeaves(\n\t\tblock: MergeBlock,\n\n\t\tcollabWindow: CollaborationWindow,\n\t\tcomputeLocalPartials: boolean,\n\t\tretry = true,\n\t): PartialSequenceLengths {\n\t\tconst combinedPartialLengths = new PartialSequenceLengths(\n\t\t\tcollabWindow.minSeq,\n\t\t\tcomputeLocalPartials,\n\t\t);\n\t\tcombinedPartialLengths.segmentCount = block.childCount;\n\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tif (child.isLeaf()) {\n\t\t\t\t// Leaf segment\n\t\t\t\tconst segment = child;\n\t\t\t\tif (wasRemovedOnInsert(segment)) {\n\t\t\t\t\tPartialSequenceLengths.accountForRemoveOnInsert(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tPartialSequenceLengths.accountForInsertion(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t);\n\n\t\t\t\t\tPartialSequenceLengths.accountForRemoval(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tPartialSequenceLengths.options.verifier?.(combinedPartialLengths);\n\t\treturn combinedPartialLengths;\n\t}\n\n\t/**\n\t * Assuming this segment was removed on insertion, inserts length information about that operation\n\t * into the appropriate per-client adjustments (the overall view needs no such adjustment since\n\t * from an observing client's perspective, the segment never exists).\n\t */\n\tprivate static accountForRemoveOnInsert(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tassertInserted(segment);\n\t\tconst removeInfo = toRemovalInfo(segment);\n\t\tassert(\n\t\t\tremoveInfo !== undefined && wasRemovedOnInsert(segment),\n\t\t\t0xab7 /* Segment was not removed on insert */,\n\t\t);\n\t\tconst firstRemove = removeInfo?.removes[0];\n\t\tif (opstampUtils.lte(firstRemove, getMinSeqStamp(collabWindow))) {\n\t\t\t// This segment was obliterated as soon as it was inserted, and everyone was aware of the obliterate.\n\t\t\t// Thus every single client treats this segment as length 0 from every perspective, and no adjustments\n\t\t\t// are necessary.\n\t\t\treturn;\n\t\t}\n\n\t\tconst { insert, cachedLength } = segment;\n\t\tconst isLocal = opstampUtils.isLocal(insert);\n\t\tconst { clientId } = insert;\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (partials === undefined) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\t// Implication -> this is a local segment which will be obliterated as soon as it is acked.\n\t\t\t// For refSeqs preceding that removedSeq and localSeqs following the localSeq, it will be visible.\n\t\t\t// For the rest, it will not be visible.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst localSeq = insert.localSeq!;\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: localSeq,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: cachedLength,\n\t\t\t\tclientId,\n\t\t\t});\n\n\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\trefSeq: firstRemove.seq,\n\t\t\t\tlocalSeq,\n\t\t\t\tseglen: -cachedLength,\n\t\t\t});\n\n\t\t\tconst lastRemove = removeInfo.removes[removeInfo.removes.length - 1];\n\t\t\tif (opstampUtils.isLocal(lastRemove)) {\n\t\t\t\t// In addition to a remote sliceRemove causing this segment to be removed as soon as its insertion is acked,\n\t\t\t\t// the local client has also removed it before its insertion was acked.\n\t\t\t\t// It will therefore not be visible for a local reconnecting perspective beyond the removed localSeq.\n\t\t\t\tpartials.addOrUpdate({\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tseq: lastRemove.localSeq!,\n\t\t\t\t\tlen: 0,\n\t\t\t\t\tseglen: -cachedLength,\n\t\t\t\t\tclientId,\n\t\t\t\t});\n\n\t\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\t\trefSeq: firstRemove.seq,\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tlocalSeq: lastRemove.localSeq!,\n\t\t\t\t\tseglen: cachedLength,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\t// Segment was obliterated on insert. Generally this means it should be visible only to the\n\t\t\t// inserting client (in which case we add an adjustment to only that client's perspective),\n\t\t\t// but if that client has also removed it, we don't need to add anything.\n\t\t\tconst wasRemovedByInsertingClient = removeInfo?.removes.some(\n\t\t\t\t(remove) => remove.clientId === clientId,\n\t\t\t);\n\n\t\t\tif (!wasRemovedByInsertingClient) {\n\t\t\t\tconst removeSeq = firstRemove?.seq;\n\t\t\t\tassert(\n\t\t\t\t\tremoveSeq !== undefined,\n\t\t\t\t\t0xab8 /* ObliterateOnInsertion implies removeSeq is defined */,\n\t\t\t\t);\n\t\t\t\tcombinedPartialLengths.addClientAdjustment(clientId, removeSeq, cachedLength);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Inserts length information about the insertion of `segment` into\n\t * `combinedPartialLengths.partialLengths` and the appropriate per-client adjustments.\n\t */\n\tprivate static accountForInsertion(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tassertInserted(segment);\n\t\tif (opstampUtils.lte(segment.insert, getMinSeqStamp(collabWindow))) {\n\t\t\tcombinedPartialLengths.minLength += segment.cachedLength;\n\t\t\treturn;\n\t\t}\n\n\t\tconst { insert, cachedLength: segmentLen } = segment;\n\n\t\tconst isLocal = opstampUtils.isLocal(insert);\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst seqOrLocalSeq = isLocal ? insert.localSeq! : insert.seq;\n\t\tconst clientId = insert.clientId;\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (!partials) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: segmentLen,\n\t\t\t});\n\t\t} else {\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: segmentLen,\n\t\t\t});\n\t\t\tcombinedPartialLengths.addClientAdjustment(clientId, seqOrLocalSeq, segmentLen);\n\t\t}\n\t}\n\n\t/**\n\t * Inserts length information about the removal or obliteration of `segment` into\n\t * `combinedPartialLengths.partialLengths` and the appropriate per-client adjustments.\n\t */\n\tprivate static accountForRemoval(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tassertInserted(segment);\n\n\t\tconst removalInfo = toRemovalInfo(segment);\n\t\tif (!removalInfo) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst firstRemove = removalInfo?.removes[0];\n\t\tconst minSeqStamp = getMinSeqStamp(collabWindow);\n\t\tif (firstRemove !== undefined && opstampUtils.lte(firstRemove, minSeqStamp)) {\n\t\t\tcombinedPartialLengths.minLength -= segment.cachedLength;\n\t\t\treturn;\n\t\t}\n\n\t\tconst removalIsLocal = !!firstRemove && opstampUtils.isLocal(firstRemove);\n\t\tconst isLocalInsertion = opstampUtils.isLocal(segment.insert);\n\t\tconst isOnlyLocalRemoval = removalIsLocal;\n\t\tconst isLocal = isLocalInsertion || isOnlyLocalRemoval;\n\n\t\tif (isLocalInsertion && !removalIsLocal) {\n\t\t\tthrow new Error(\"Should have handled this codepath in wasRemovedOnInsertion\");\n\t\t}\n\n\t\tconst lenDelta = -segment.cachedLength;\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst seqOrLocalSeq = removalIsLocal ? firstRemove.localSeq! : firstRemove.seq;\n\t\tconst clientId = firstRemove.clientId;\n\n\t\tconst clientsWithRemoveOrObliterate = new Set<number>(\n\t\t\tremovalInfo?.removes.map((stamp) => stamp.clientId),\n\t\t);\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (partials === undefined) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\t// The segment is either inserted only locally or removed only locally.\n\t\t\t// We already accounted for the insertion in the accountForInsertion codepath.\n\t\t\t// Only thing left to do is account for the removal in local partial lengths.\n\t\t\t// One thing to be careful about is that the removal should only apply to perspectives that saw\n\t\t\t// the segment's insertion in the first place.\n\t\t\t// When the segment's insertion was common knowledge (at or below minSeq) or also by the local client,\n\t\t\t// all possible perspectives will have seen it.\n\t\t\tif (\n\t\t\t\topstampUtils.lte(segment.insert, minSeqStamp) ||\n\t\t\t\tcollabWindow.clientId === segment.insert.clientId\n\t\t\t) {\n\t\t\t\tpartials.addOrUpdate({\n\t\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\t\tclientId,\n\t\t\t\t\tlen: 0,\n\t\t\t\t\tseglen: lenDelta,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// ... otherwise, it's only visible to reconnecting perspectives above the seq of the insert.\n\t\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\t\tlocalSeq: seqOrLocalSeq,\n\t\t\t\t\trefSeq: segment.insert.seq,\n\t\t\t\t\tseglen: lenDelta,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: lenDelta,\n\t\t\t});\n\n\t\t\tfor (const id of clientsWithRemoveOrObliterate) {\n\t\t\t\tif (id === collabWindow.clientId) {\n\t\t\t\t\t// The local client also removed or obliterated this segment.\n\t\t\t\t\tconst { localSeq } = removalInfo.removes[removalInfo.removes.length - 1];\n\t\t\t\t\tif (localSeq === undefined) {\n\t\t\t\t\t\t// Sure, the local client did it--but that change was already acked.\n\t\t\t\t\t\t// No need to account for it in the unsequenced records.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst { unsequencedRecords } = combinedPartialLengths;\n\t\t\t\t\tif (!unsequencedRecords) {\n\t\t\t\t\t\t// Local partial but its computation isn't required.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tassert(\n\t\t\t\t\t\tlocalSeq !== undefined,\n\t\t\t\t\t\t0xaba /* Local client was in removed client ids but segment has no local seq for either */,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Here...\n\t\t\t\t\t// - The segment was removed locally at `localSeq`\n\t\t\t\t\t// - The segment was also removed remotely at `seqOrLocalSeq`\n\t\t\t\t\t// - We're ensuring that partial lengths works for arbitrary `LocalReconnectingPerspective`s.\n\t\t\t\t\t//\n\t\t\t\t\t// Visualize an arbitrary local reconnecting perspective in 2d space, where the x-axis is `seq` and the y-axis is `localSeq`.\n\t\t\t\t\t// The events that have occurred to this segment divide the space into up to 6 regions:\n\t\t\t\t\t//\n\t\t\t\t\t// (localSeq)\n\t\t\t\t\t// | | |\n\t\t\t\t\t// | 1 | 2 | 3\n\t\t\t\t\t// local remove |-----------------------------\n\t\t\t\t\t// | | |\n\t\t\t\t\t// | 4 | 5 | 6\n\t\t\t\t\t// |----------------------------- (seq)\n\t\t\t\t\t// insert remove\n\t\t\t\t\t// In all regions but region 5, the segment has length 0 (it was not inserted yet in regions 1 or 4, and removed locally and/or remotely\n\t\t\t\t\t// in regions 2, 3, and 6).\n\t\t\t\t\t// `accountForInsertion` already added a partial lengths adjustment of +segment.cachedLength for regions 2, 3, 5, and 6.\n\t\t\t\t\t// Above in this function, we've added a partial lengths adjustment of -segment.cachedLength for regions 3 and 6.\n\t\t\t\t\t//\n\t\t\t\t\t// Note that in this picture:\n\t\t\t\t\t// - Adding entries to `unsequencedRecords.partialLengths` is like adding adjustments that affect anything above a given Y value\n\t\t\t\t\t// - Adding entries to `combinedPartialLengths.partialLengths` is like adding adjustments that affect anything above a given X value\n\t\t\t\t\t// - Adding entries with `addLocalAdjustment` is like adding adjustments that affect anything above a given X *and* Y value\n\t\t\t\t\t// The remainder this block adds the necessary adjustments to make the length appear 0 in region 2 as well, keeping in mind that\n\t\t\t\t\t// region 1 may or may not exist depending on if the insertion is in the collab window.\n\t\t\t\t\tif (\n\t\t\t\t\t\topstampUtils.isAcked(segment.insert) &&\n\t\t\t\t\t\topstampUtils.greaterThan(segment.insert, minSeqStamp)\n\t\t\t\t\t) {\n\t\t\t\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\t\t\t\trefSeq: segment.insert.seq,\n\t\t\t\t\t\t\tlocalSeq,\n\t\t\t\t\t\t\tseglen: lenDelta,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tunsequencedRecords.partialLengths.addOrUpdate({\n\t\t\t\t\t\t\tseq: localSeq,\n\t\t\t\t\t\t\tclientId: collabWindow.clientId,\n\t\t\t\t\t\t\tseglen: lenDelta,\n\t\t\t\t\t\t\tlen: 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Because we've included deltas which take effect when either of localSeq or refSeq are high enough,\n\t\t\t\t\t// we need to offset this with an adjustment that takes effect when both are high enough.\n\t\t\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\t\t\trefSeq: seqOrLocalSeq,\n\t\t\t\t\t\tlocalSeq,\n\t\t\t\t\t\t// combinedPartialLengths.partialLengths has an entry removing this segment from a perspective >= seqOrLocalSeq.\n\t\t\t\t\t\t// combinedPartialLengths.unsequencedRecords.partialLengths now has an entry removing this segment from a perspective\n\t\t\t\t\t\t// with local seq >= `localSeq`.\n\t\t\t\t\t\t// In order to only remove this segment once, we add back in the length (where this entry only takes effect when\n\t\t\t\t\t\t// both above are true due to logic in computeOverallRefSeqAdjustment).\n\t\t\t\t\t\tseglen: segment.cachedLength,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Note that all clients that have a remove or obliterate operation on this segment\n\t\t\t\t\t// use the seq of the winning obliterate in their per-client adjustments!\n\t\t\t\t\tcombinedPartialLengths.addClientAdjustment(id, seqOrLocalSeq, lenDelta);\n\n\t\t\t\t\t// Also ensure that all these clients have seen the segment as inserted before being removed\n\t\t\t\t\t// This is technically not necessary for setRemoves (we never ask for the length of this block with\n\t\t\t\t\t// respect to a refSeq which this entry would affect), but it's simpler to just add it here.\n\t\t\t\t\t// We already add this entry as part of the accountForInsertion codepath for the client that\n\t\t\t\t\t// actually did insert the segment, hence not doing so [again] here.\n\t\t\t\t\tif (\n\t\t\t\t\t\topstampUtils.greaterThan(segment.insert, minSeqStamp) &&\n\t\t\t\t\t\tid !== segment.insert.clientId\n\t\t\t\t\t) {\n\t\t\t\t\t\tcombinedPartialLengths.addClientAdjustment(\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\tsegment.insert.seq,\n\t\t\t\t\t\t\tsegment.cachedLength,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If incremental update of partial lengths fails, this gets set to the seq of the failed update.\n\t * When higher up blocks attempt to incrementally update, they first check if the seq they are updating for\n\t * matches this value. If it does, they propagate a full refresh instead.\n\t */\n\tprivate lastIncrementalInvalidationSeq = Number.NEGATIVE_INFINITY;\n\n\t// Assume: seq is latest sequence number; no structural change to sub-tree, but this partial lengths\n\t// entry needs to account for the change made by the client with `clientId` at sequence number `seq`.\n\t// (and `update` has been called on all descendant PartialSequenceLengths).\n\t// This implementation does not support overlapping removes: callers should recompute partial lengths\n\t// using `combine` when the change that has just been applied involves such an operation.\n\t// TODO: assert client id matches\n\tpublic update(\n\t\tnode: MergeBlock,\n\t\tseq: number,\n\t\tclientId: number,\n\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\t// In the current implementation, this method gets invoked multiple times for the same sequence number (i.e. mid-operation).\n\t\t// We counter this by first zeroing out existing entries from previous updates, but it isn't ideal.\n\t\t// Even if we fix this at the merge-tree level, the same type of issue can crop up with grouped batching enabled.\n\t\tconst latest = this.partialLengths.latestLeq(seq);\n\t\tif (latest?.seq === seq) {\n\t\t\tthis.partialLengths.addOrUpdate({ seq, len: 0, seglen: -latest.seglen, clientId });\n\t\t}\n\n\t\t// .forEach natively ignores undefined entries.\n\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\tthis.perClientAdjustments.forEach((clientAdjustments) => {\n\t\t\tconst leqPartial = clientAdjustments.latestLeq(seq);\n\t\t\tif (leqPartial && leqPartial.seq === seq) {\n\t\t\t\tthis.addClientAdjustment(clientId, seq, -leqPartial.seglen);\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * If any of the changes made by the client at `seq` necessitate partial length entries at sequence numbers other than `seq`,\n\t\t * this flag is set to true. This propagates upwards when aggregating parents as well.\n\t\t *\n\t\t * Note: it seems feasible to update parents more incrementally by tracking the changes made to child blocks for a given update.\n\t\t * There isn't a great place for this information to flow today.\n\t\t */\n\t\tlet failIncrementalPropagation = false;\n\n\t\tlet seqSeglen = 0;\n\t\tlet segCount = 0;\n\t\t// Compute length for seq across children\n\t\tfor (let i = 0; i < node.childCount; i++) {\n\t\t\tconst child = node.children[i];\n\t\t\tif (child.isLeaf()) {\n\t\t\t\tconst segment = child;\n\t\t\t\tconst removalInfo = toRemovalInfo(segment);\n\t\t\t\tconst firstRemove = removalInfo?.removes[0];\n\t\t\t\tif (seq === segment.insert.seq) {\n\t\t\t\t\t// if this segment was removed on insert, its length should\n\t\t\t\t\t// only be visible to the inserting client\n\t\t\t\t\tif (\n\t\t\t\t\t\tsegment.insert.seq !== undefined &&\n\t\t\t\t\t\tfirstRemove !== undefined &&\n\t\t\t\t\t\twasRemovedOnInsert(segment)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, firstRemove.seq, segment.cachedLength);\n\t\t\t\t\t\tfailIncrementalPropagation = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tseqSeglen += segment.cachedLength;\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, seq, segment.cachedLength);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (opstampUtils.isAcked(segment.insert) && seq === firstRemove?.seq) {\n\t\t\t\t\tseqSeglen -= segment.cachedLength;\n\t\t\t\t\tif (clientId !== collabWindow.clientId) {\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, seq, -segment.cachedLength);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\topstampUtils.greaterThan(segment.insert, getMinSeqStamp(collabWindow)) &&\n\t\t\t\t\t\t\tsegment.insert.clientId !== clientId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.addClientAdjustment(clientId, segment.insert.seq, segment.cachedLength);\n\t\t\t\t\t\t\tfailIncrementalPropagation = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsegCount++;\n\t\t\t} else {\n\t\t\t\tconst childBlock = child;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst branchPartialLengths = childBlock.partialLengths!;\n\t\t\t\tif (branchPartialLengths.lastIncrementalInvalidationSeq === seq) {\n\t\t\t\t\t// Bail out.\n\t\t\t\t\tconst newPartials = PartialSequenceLengths.combine(node, collabWindow, false);\n\t\t\t\t\tnewPartials.lastIncrementalInvalidationSeq = seq;\n\t\t\t\t\tnode.partialLengths = newPartials;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst partialLengths = branchPartialLengths.partialLengths;\n\t\t\t\tconst leqPartial = partialLengths.latestLeq(seq);\n\t\t\t\tif (leqPartial && leqPartial.seq === seq) {\n\t\t\t\t\tseqSeglen += leqPartial.seglen;\n\t\t\t\t}\n\t\t\t\tsegCount += branchPartialLengths.segmentCount;\n\n\t\t\t\t// .forEach natively ignores undefined entries.\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\t\t\tbranchPartialLengths.perClientAdjustments.forEach((clientAdjustments) => {\n\t\t\t\t\tconst leqBranchPartial = clientAdjustments.latestLeq(seq);\n\t\t\t\t\tif (leqBranchPartial && leqBranchPartial.seq === seq) {\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, seq, leqBranchPartial.seglen);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (failIncrementalPropagation) {\n\t\t\tthis.lastIncrementalInvalidationSeq = seq;\n\t\t}\n\t\tthis.segmentCount = segCount;\n\t\tthis.unsequencedRecords = undefined;\n\t\tthis.partialLengths.addOrUpdate({ seq, seglen: seqSeglen, len: 0, clientId });\n\n\t\tif (PartialSequenceLengths.options.zamboni) {\n\t\t\tthis.zamboni(collabWindow);\n\t\t}\n\t\tPartialSequenceLengths.options.verifier?.(this);\n\t}\n\n\t/**\n\t * Returns the length of this block as viewed from the perspective of `clientId` at `refSeq`.\n\t * This is the total length of all segments sequenced at or before refSeq OR submitted by `clientId`.\n\t * If `clientId` is the local client, `localSeq` can also be provided. In that case, it is the total\n\t * length of all segments submitted at or before `refSeq` in addition to any local, unacked segments\n\t * with `segment.localSeq <= localSeq`.\n\t *\n\t * Note: the local case (where `localSeq !== undefined`) is only supported on a PartialSequenceLength object\n\t * constructed with `computeLocalPartials` set to true and not subsequently updated with `update`.\n\t */\n\tpublic getPartialLength(refSeq: number, clientId: number, localSeq?: number): number {\n\t\tlet length = this.minLength;\n\t\tlength += this.partialLengths.latestLeq(refSeq)?.len ?? 0;\n\n\t\tif (localSeq === undefined) {\n\t\t\tconst latestClientEntry = this.latestClientEntry(clientId);\n\t\t\tif (latestClientEntry !== undefined && latestClientEntry.seq > refSeq) {\n\t\t\t\t// The client has local edits after refSeq, add in the length adjustments\n\t\t\t\tlength += latestClientEntry.len;\n\t\t\t\tconst precedingCli = this.latestClientEntryLEQ(clientId, refSeq);\n\t\t\t\tif (precedingCli) {\n\t\t\t\t\t// Subtract out double-counted lengths: segments still in the collab window but before\n\t\t\t\t\t// the refSeq submitted by the client we're querying for were counted in each addition above.\n\t\t\t\t\tlength -= precedingCli.len;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tthis.unsequencedRecords !== undefined,\n\t\t\t\t0x39f /* Local getPartialLength invoked without computing local partials. */,\n\t\t\t);\n\t\t\tconst unsequencedPartialLengths = this.unsequencedRecords.partialLengths;\n\t\t\t// Local segments at or before localSeq should also be included\n\t\t\tlength += unsequencedPartialLengths.latestLeq(localSeq)?.len ?? 0;\n\n\t\t\t// Lastly, we must add in any additional adjustment that should only take effect when both\n\t\t\t// refSeq AND localSeq are above some threshold. This accounts for things like double-counting\n\t\t\t// local+remote removes, or only subtracting the length out of a local remove if we've also seen\n\t\t\t// the insert of the segment it affects. (see addLocalAdjustment usages for examples)\n\t\t\tlength += this.computeOverallRefSeqAdjustment(refSeq, localSeq);\n\t\t}\n\t\treturn length;\n\t}\n\n\t/**\n\t * Computes the seglen for the double-counted removed overlap at (refSeq, localSeq).\n\t *\n\t * Reconnect happens to only need to compute these lengths for two refSeq values: before and\n\t * after the rebase. Since these lists potentially scale with O(collab window * number of local edits)\n\t * and potentially need to be queried for each local op that gets rebased,\n\t * we cache the results for a given refSeq in `this.unsequencedRecords.cachedOverlappingByRefSeq` so\n\t * that they can be binary-searched the same way the usual partialLengths lists are.\n\t */\n\tprivate computeOverallRefSeqAdjustment(refSeq: number, localSeq: number): number {\n\t\tif (this.unsequencedRecords === undefined) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tlet cachedAdjustment = this.unsequencedRecords.cachedAdjustmentByRefSeq.get(refSeq);\n\t\tif (!cachedAdjustment) {\n\t\t\tconst partials: PartialSequenceLengthsSet = new PartialSequenceLengthsSet();\n\t\t\tfor (const [\n\t\t\t\tseq,\n\t\t\t\tadjustments,\n\t\t\t] of this.unsequencedRecords.perRefSeqAdjustments.entries()) {\n\t\t\t\tif (seq > refSeq) {\n\t\t\t\t\t// TODO: Prior code path got away with an early exit here by sorting the entries by refSeq.\n\t\t\t\t\t// We could do the same here if we wanted.\n\t\t\t\t\t// Old codepath basically flattened the 2d array into a 1d array with both dimensions listed.\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfor (const partial of adjustments.items) {\n\t\t\t\t\t// This coalesces entries with the same localSeq as well as computes overall lengths.\n\t\t\t\t\tpartials.addOrUpdate({ ...partial });\n\t\t\t\t}\n\t\t\t}\n\t\t\tcachedAdjustment = partials;\n\t\t\tthis.unsequencedRecords.cachedAdjustmentByRefSeq.set(refSeq, cachedAdjustment);\n\t\t}\n\n\t\tconst overlap = cachedAdjustment.latestLeq(localSeq);\n\t\treturn overlap?.len ?? 0;\n\t}\n\n\tpublic toString(glc?: (id: number) => string, indentCount = 0): string {\n\t\tlet buf = \"\";\n\t\tfor (const partial of this.partialLengths.items) {\n\t\t\tbuf += `(${partial.seq},${partial.len}) `;\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-for-in-array, no-restricted-syntax\n\t\tfor (const clientId in this.perClientAdjustments) {\n\t\t\tif (this.perClientAdjustments[clientId].size > 0) {\n\t\t\t\tbuf += `Client `;\n\t\t\t\tbuf += glc ? `${glc(+clientId)}` : `${clientId}`;\n\t\t\t\tbuf += \"[\";\n\t\t\t\tfor (const partial of this.perClientAdjustments[clientId].items) {\n\t\t\t\t\tbuf += `(${partial.seq},${partial.len})`;\n\t\t\t\t}\n\t\t\t\tbuf += \"]\";\n\t\t\t}\n\t\t}\n\t\tbuf = `min(seq ${this.minSeq}): ${this.minLength}; sc: ${this.segmentCount};${buf}`;\n\t\treturn buf;\n\t}\n\n\t// Clear away partial sums for sequence numbers earlier than the current window\n\n\tprivate zamboni(segmentWindow: CollaborationWindow): void {\n\t\tthis.minLength += this.partialLengths.copyDown(segmentWindow.minSeq);\n\t\tthis.minSeq = segmentWindow.minSeq;\n\t\t// eslint-disable-next-line @typescript-eslint/no-for-in-array, guard-for-in, no-restricted-syntax\n\t\tfor (const clientId in this.perClientAdjustments) {\n\t\t\tconst cliPartials = this.perClientAdjustments[clientId];\n\t\t\tif (cliPartials) {\n\t\t\t\tcliPartials.copyDown(segmentWindow.minSeq);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addClientAdjustment(clientId: number, seq: number, seglen: number): void {\n\t\tthis.perClientAdjustments[clientId] ??= new PartialSequenceLengthsSet();\n\t\tconst cli = this.perClientAdjustments[clientId];\n\t\tcli.addOrUpdate({ seq, len: 0, seglen });\n\t}\n\n\tprivate addLocalAdjustment({\n\t\trefSeq,\n\t\tlocalSeq,\n\t\tseglen,\n\t}: { refSeq: number; localSeq: number; seglen: number }): void {\n\t\tassert(\n\t\t\tthis.unsequencedRecords !== undefined,\n\t\t\t0xabb /* Local adjustment computed without partials */,\n\t\t);\n\t\tconst adjustments =\n\t\t\tthis.unsequencedRecords.perRefSeqAdjustments.get(refSeq) ??\n\t\t\tnew PartialSequenceLengthsSet();\n\t\tthis.unsequencedRecords.perRefSeqAdjustments.set(refSeq, adjustments);\n\t\tadjustments.addOrUpdate({ seq: localSeq, len: 0, seglen });\n\t}\n\n\t/**\n\t * Returns the partial lengths associated with the latest change associated with `clientId` at or before `refSeq`.\n\t * Returns undefined if no such change exists.\n\t */\n\tprivate latestClientEntryLEQ(\n\t\tclientId: number,\n\t\trefSeq: number,\n\t): PartialSequenceLength | undefined {\n\t\treturn this.perClientAdjustments[clientId]?.latestLeq(refSeq);\n\t}\n\n\t/**\n\t * Get the partial lengths associated with the most recent change received by `clientId`, or undefined\n\t * if this client has made no changes in this block within the collab window.\n\t */\n\tprivate latestClientEntry(clientId: number): PartialSequenceLength | undefined {\n\t\tconst cliSeqs = this.perClientAdjustments[clientId];\n\t\treturn cliSeqs && cliSeqs.size > 0 ? cliSeqs.items[cliSeqs.size - 1] : undefined;\n\t}\n}\n\n/* eslint-disable @typescript-eslint/dot-notation */\nfunction verifyPartialLengthsInner(\n\tpartialSeqLengths: PartialSequenceLengths,\n\tpartialLengths: PartialSequenceLengthsSet,\n\tclientPartials: boolean,\n): number {\n\tif (partialLengths.size === 0) {\n\t\treturn 0;\n\t}\n\n\tlet lastSeqNum = 0;\n\tlet accumSegLen = 0;\n\tlet count = 0;\n\n\tfor (const partialLength of partialLengths.items) {\n\t\t// Count total number of partial length entries\n\t\tcount++;\n\n\t\t// Sequence number should be larger or equal to minseq\n\t\tassert(\n\t\t\tpartialSeqLengths.minSeq <= partialLength.seq,\n\t\t\t0x054 /* \"Sequence number less than minSeq!\" */,\n\t\t);\n\n\t\t// Sequence number should be sorted\n\t\tassert(lastSeqNum < partialLength.seq, 0x055 /* \"Sequence number is not sorted!\" */);\n\t\tlastSeqNum = partialLength.seq;\n\n\t\t// Len is a accumulation of all the seglen adjustments\n\t\taccumSegLen += partialLength.seglen;\n\t\tif (accumSegLen !== partialLength.len) {\n\t\t\tassert(\n\t\t\t\tfalse,\n\t\t\t\t0x056 /* \"Unexpected total for accumulation of all seglen adjustments!\" */,\n\t\t\t);\n\t\t}\n\n\t\tif (clientPartials) {\n\t\t\t// Client partials used to track local edits so we can account for them some refSeq.\n\t\t\t// But the information we keep track of are since minSeq, so we keep track of more history\n\t\t\t// then needed, and some of them doesn't make sense to be used for length calculations\n\t\t\t// e.g. if you have this sequence, where the minSeq is #5 because of other clients\n\t\t\t// seq 10: client 1: insert seg #1\n\t\t\t// seq 11: client 2: delete seg #2 refseq: 10\n\t\t\t// minLength is 0, we would have keep a record of seglen: -1 for clientPartialLengths for client 2\n\t\t\t// So if you ask for partial length for client 2 @ seq 5, we will have return -1.\n\t\t\t// However, that combination is invalid, since we should never see any ops with refseq < 10 for\n\t\t\t// client 2 after seq 11.\n\t\t} else {\n\t\t\t// Len adjustment should not make length negative\n\t\t\tif (partialSeqLengths[\"minLength\"] + partialLength.len < 0) {\n\t\t\t\tassert(false, 0x057 /* \"Negative length after length adjustment!\" */);\n\t\t\t}\n\t\t}\n\t}\n\treturn count;\n}\n\nexport function verifyExpectedPartialLengths(\n\tmergeTree: MergeTree,\n\tnode: MergeBlock,\n\trefSeq: number,\n\tclientId: number,\n\tlocalSeq?: number,\n): void {\n\tif (\n\t\t(!mergeTree.collabWindow.collaborating || mergeTree.collabWindow.clientId === clientId) &&\n\t\t(node.isLeaf() || localSeq === undefined)\n\t) {\n\t\treturn;\n\t}\n\n\tconst partialLen = node.partialLengths?.getPartialLength(refSeq, clientId, localSeq);\n\n\tlet expected = 0;\n\tconst nodesToVisit: IMergeNode[] = [node];\n\tconst perspective =\n\t\tclientId === mergeTree.collabWindow.clientId\n\t\t\t? localSeq === undefined\n\t\t\t\t? new LocalDefaultPerspective(clientId)\n\t\t\t\t: new LocalReconnectingPerspective(refSeq, clientId, localSeq)\n\t\t\t: new PriorPerspective(refSeq, clientId);\n\n\twhile (nodesToVisit.length > 0) {\n\t\tconst thisNode = nodesToVisit.pop();\n\t\tif (!thisNode) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (thisNode.isLeaf()) {\n\t\t\texpected += mergeTree[\"nodeLength\"](thisNode, perspective) ?? 0;\n\t\t} else {\n\t\t\tnodesToVisit.push(...thisNode.children.slice(0, thisNode.childCount));\n\t\t}\n\t}\n\n\tif (expected !== partialLen) {\n\t\tconst nonIncrementalPartials = PartialSequenceLengths.combine(\n\t\t\tnode,\n\t\t\tmergeTree.collabWindow,\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t);\n\t\tconst nonIncrementalLength = nonIncrementalPartials.getPartialLength(\n\t\t\trefSeq,\n\t\t\tclientId,\n\t\t\tlocalSeq,\n\t\t);\n\t\tnode.partialLengths?.getPartialLength(refSeq, clientId, localSeq);\n\n\t\tthrow new Error(\n\t\t\t`expected partial length of ${expected} but found ${partialLen}. refSeq: ${refSeq}, clientId: ${clientId}. (non-incremental codepath returned ${nonIncrementalLength})`,\n\t\t);\n\t}\n}\n\nexport function verifyPartialLengths(partialSeqLengths: PartialSequenceLengths): void {\n\tif (partialSeqLengths[\"perClientAdjustments\"]) {\n\t\tfor (const cliSeq of partialSeqLengths[\"perClientAdjustments\"]) {\n\t\t\tif (cliSeq) {\n\t\t\t\tverifyPartialLengthsInner(partialSeqLengths, cliSeq, true);\n\t\t\t}\n\t\t}\n\n\t\t// If we have client view, we should have the flat view\n\t\tassert(\n\t\t\t!!partialSeqLengths[\"partialLengths\"],\n\t\t\t0x059 /* \"Client view exists but flat view does not!\" */,\n\t\t);\n\n\t\tverifyPartialLengthsInner(partialSeqLengths, partialSeqLengths[\"partialLengths\"], false);\n\t} else {\n\t\t// If we don't have a client view, we shouldn't have the flat view either\n\t\tassert(\n\t\t\t!partialSeqLengths[\"partialLengths\"],\n\t\t\t0x05b /* \"Flat view exists but client view does not!\" */,\n\t\t);\n\t}\n}\n/* eslint-enable @typescript-eslint/dot-notation */\n\n/**\n * Given a number of seq-sorted `partialLength` lists, merges them into a combined seq-sorted `partialLength`\n * list. This merge includes coalescing `PartialSequenceLength` entries at the same seq.\n *\n * Ex: merging the following two lists (some information omitted on each PartialSequenceLength):\n * ```typescript\n * [{ seq: 1, seglen: 5 }, { seq: 3, seglen: -1 }]\n * [{ seq: 1, seglen: -3 }, { seq: 2: seglen: 4 }]\n * ```\n * would produce\n * ```typescript\n * [{ seq: 1, seglen: 2 }, { seq: 2, seglen: 4 }, { seq: 3, seglen: -1 }]\n * ```\n */\nfunction mergePartialLengths(\n\tchildPartialLengths: PartialSequenceLength[][],\n\tmergedLengths: PartialSequenceLengthsSet = new PartialSequenceLengthsSet(),\n): PartialSequenceLengthsSet {\n\tfor (const partialLength of mergeSortedListsBySeq(childPartialLengths)) {\n\t\tmergedLengths.addOrUpdate({\n\t\t\t...partialLength,\n\t\t});\n\t}\n\treturn mergedLengths;\n}\n\n/**\n * Given a collection of PartialSequenceLength lists--each sorted by sequence number--returns an iterable that yields\n * each PartialSequenceLength in sequence order.\n *\n * This is equivalent to flattening the input list and sorting it by sequence number. If the number of lists to merge is\n * a constant, however, this approach is advantageous asymptotically.\n */\nfunction mergeSortedListsBySeq<T extends PartialSequenceLength>(lists: T[][]): Iterable<T> {\n\tclass PartialSequenceLengthIterator {\n\t\t/**\n\t\t * nextSmallestIndex[i] is the next element of sublists[i] to check.\n\t\t * In other words, the iterator has already yielded elements of sublists[i] *up through*\n\t\t * sublists[i][nextSmallestIndex[i] - 1].\n\t\t */\n\t\tprivate readonly nextSmallestIndex: number[];\n\n\t\tconstructor(private readonly sublists: T[][]) {\n\t\t\tthis.nextSmallestIndex = Array.from({ length: sublists.length });\n\t\t\tfor (let i = 0; i < sublists.length; i++) {\n\t\t\t\tthis.nextSmallestIndex[i] = 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic next(): { value: T; done: false } | { value: undefined; done: true } {\n\t\t\tconst len = this.sublists.length;\n\t\t\tlet currentMin: T | undefined;\n\t\t\tlet currentMinIndex: number | undefined;\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tconst candidateIndex = this.nextSmallestIndex[i];\n\t\t\t\tif (candidateIndex < this.sublists[i].length) {\n\t\t\t\t\tconst candidate = this.sublists[i][candidateIndex];\n\t\t\t\t\tif (!currentMin || candidate.seq < currentMin.seq) {\n\t\t\t\t\t\tcurrentMin = candidate;\n\t\t\t\t\t\tcurrentMinIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentMin) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tthis.nextSmallestIndex[currentMinIndex!]++;\n\t\t\t\treturn { value: currentMin, done: false };\n\t\t\t} else {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { [Symbol.iterator]: () => new PartialSequenceLengthIterator(lists) };\n}\n"]}
1
+ {"version":3,"file":"partialLengths.js","sourceRoot":"","sources":["../src/partialLengths.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert } from \"@fluidframework/core-utils/internal\";\n\nimport type { MergeTree } from \"./mergeTree.js\";\nimport {\n\ttype CollaborationWindow,\n\tgetMinSeqStamp,\n\ttype IMergeNode,\n\ttype ISegmentPrivate,\n\ttype MergeBlock,\n} from \"./mergeTreeNodes.js\";\nimport {\n\tLocalDefaultPerspective,\n\tLocalReconnectingPerspective,\n\tPriorPerspective,\n} from \"./perspective.js\";\nimport { toRemovalInfo, assertInserted, wasRemovedOnInsert } from \"./segmentInfos.js\";\nimport { SortedSet } from \"./sortedSet.js\";\nimport * as opstampUtils from \"./stamps.js\";\n\nclass PartialSequenceLengthsSet extends SortedSet<PartialSequenceLength> {\n\tprotected compare(a: PartialSequenceLength, b: PartialSequenceLength): number {\n\t\treturn a.seq - b.seq;\n\t}\n\n\tpublic addOrUpdate(\n\t\tnewItem: PartialSequenceLength,\n\t\tupdate?: (existingItem: PartialSequenceLength, newItem: PartialSequenceLength) => void,\n\t): void {\n\t\tif (newItem.seglen === 0) {\n\t\t\t// Don't bother doing any updates for deltas of 0.\n\t\t\treturn;\n\t\t}\n\t\tconst prev = this.latestLeq(newItem.seq);\n\n\t\tif (prev?.seq !== newItem.seq) {\n\t\t\t// new element, update len\n\t\t\tnewItem.len = (prev?.len ?? 0) + newItem.seglen;\n\t\t}\n\n\t\t// update the len of all following elements\n\t\tfor (let i = this.sortedItems.length - 1; i >= 0; i--) {\n\t\t\tconst element = this.sortedItems[i];\n\t\t\tif (!element || element.seq <= newItem.seq) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\telement.len += newItem.seglen;\n\t\t}\n\n\t\tsuper.addOrUpdate(newItem, (currentPartial, partialLength) => {\n\t\t\tassert(\n\t\t\t\tpartialLength.clientId === currentPartial.clientId,\n\t\t\t\t0xab6 /* clientId mismatch */,\n\t\t\t);\n\t\t\tcurrentPartial.seglen += partialLength.seglen;\n\t\t\tcurrentPartial.len += partialLength.seglen;\n\t\t});\n\t}\n\n\t/**\n\t * Returns the partial length whose sequence number is the greatest sequence\n\t * number that is less than or equal to key.\n\t * @param key - sequence number\n\t */\n\tlatestLeq(key: number): PartialSequenceLength | undefined {\n\t\treturn this.sortedItems[this.latestLeqIndex(key)];\n\t}\n\n\t/**\n\t * Returns the partial length whose sequence number is the lowest sequence\n\t * number that is greater than or equal to key.\n\t * @param key - sequence number\n\t */\n\tfirstGte(key: number): PartialSequenceLength | undefined {\n\t\tconst { index } = this.findItemPosition({ seq: key, len: 0, seglen: 0 });\n\t\treturn this.sortedItems[index];\n\t}\n\n\tprivate latestLeqIndex(key: number): number {\n\t\tconst { exists, index } = this.findItemPosition({ seq: key, len: 0, seglen: 0 });\n\t\treturn exists ? index : index - 1;\n\t}\n\n\tcopyDown(minSeq: number): number {\n\t\tconst mindex = this.latestLeqIndex(minSeq);\n\t\tlet minLength = 0;\n\t\tif (mindex >= 0) {\n\t\t\tminLength = this.sortedItems[mindex].len;\n\t\t\tconst seqCount = this.size;\n\t\t\tif (mindex <= seqCount - 1) {\n\t\t\t\t// Still some entries remaining\n\t\t\t\tconst remainingCount = seqCount - mindex - 1;\n\t\t\t\t// Copy down\n\t\t\t\tfor (let i = 0; i < remainingCount; i++) {\n\t\t\t\t\tthis.sortedItems[i] = this.sortedItems[i + mindex + 1];\n\t\t\t\t\tthis.sortedItems[i].len -= minLength;\n\t\t\t\t}\n\t\t\t\tthis.sortedItems.length = remainingCount;\n\t\t\t}\n\t\t}\n\t\treturn minLength;\n\t}\n}\n\n/**\n * Tracks length information for a part of a MergeTree (block) at a given time (seq).\n * These objects are associated with internal nodes (i.e. blocks).\n */\nexport interface PartialSequenceLength {\n\t/**\n\t * Sequence number\n\t */\n\tseq: number;\n\t/**\n\t * The length of the associated block.\n\t */\n\tlen: number;\n\t/**\n\t * The delta between the current length of the associated block and its length at the previous seq number.\n\t */\n\tseglen: number;\n\t/**\n\t * clientId for the client that submitted the op with sequence number `seq`.\n\t */\n\tclientId?: number;\n}\n\ninterface UnsequencedPartialLengthInfo {\n\t/**\n\t * Contains entries for all local operations.\n\t * The \"seq\" field of each entry actually corresponds to the delta at that localSeq on the local client.\n\t *\n\t * The length entries in this set are analogous to `PartialSequenceLengths.partialLengths` in that they represent the delta over the min seq\n\t * that an observer client would see if they were to observe the local client's edits performed from the minSeq.\n\t */\n\tpartialLengths: PartialSequenceLengthsSet;\n\n\t/**\n\t * Like PerClientAdjustments, except we store one set of PartialSequenceLengthsSet for each refSeq. The \"seq\" keys in these sets\n\t * are all local seqs.\n\t *\n\t * These entries are aggregated by {@link PartialSequenceLengths.computeOverallRefSeqAdjustment} when a local perspective for a\n\t * given refSeq is requested.\n\t *\n\t * In general, adjustments in this map are added to avoid double-counting an operation performed by both the local client and some\n\t * remote client, and an adjustment at (refSeq = A, clientSeq = B) takes effect for all perspectives (refSeq = C, clientSeq = D) where\n\t * A \\<= C and B \\<= D.\n\t */\n\tperRefSeqAdjustments: Map<number, PartialSequenceLengthsSet>;\n\n\t/**\n\t * Cache keyed on refSeq which stores length information for the total overlap of removed segments at\n\t * that refSeq.\n\t * This information is derivable from the entries of `perRefSeqAdjustments`.\n\t *\n\t * Like the `partialLengths` field, `seq` on each entry is actually the local seq.\n\t * See `computeOverallRefSeqAdjustment` for more information.\n\t */\n\tcachedAdjustmentByRefSeq: Map<number, PartialSequenceLengthsSet>;\n}\n\nexport interface PartialSequenceLengthsOptions {\n\tverifier?: (partialLengths: PartialSequenceLengths) => void;\n\tverifyExpected?: (\n\t\tmergeTree: MergeTree,\n\t\tnode: MergeBlock,\n\t\trefSeq: number,\n\t\tclientId: number,\n\t\tlocalSeq?: number,\n\t) => void;\n\tzamboni: boolean;\n}\n\n/**\n * Keeps track of partial sums of segment lengths for all sequence numbers in the current collaboration window.\n * Only used during active collaboration.\n *\n * This class is associated with an internal node (block) of a MergeTree. It efficiently answers queries of the form\n * \"What is the length of `block` from the perspective of some particular seq and clientId?\".\n *\n * It also supports incremental updating of state for newly-sequenced ops that don't affect the structure of the\n * MergeTree (in most cases--see AB#31003 or comments on {@link PartialSequenceLengths.update}).\n *\n * To answer these queries, it pre-builds several lists which track the length of the block at a per-sequence-number\n * level. These lists are:\n *\n * 1. (`partialLengths`): Stores the total length of the block.\n * 2. (`perClientAdjustments[clientId]`): Stores adjustments to the base length which account for all changes submitted by `clientId`. [see footnote]\n *\n * The reason both lists are necessary is that resolving the length of the block from the perspective of\n * (clientId, refSeq) requires including both of the following types of segments:\n * 1. Segments sequenced before `refSeq`\n * 2. Segments submitted by `clientId`\n *\n * This is possible with the above bookkeeping, using:\n *\n * (length of the block at the minimum sequence number)\n * + (partialLengths total length at refSeq)\n * + (clientSeqNumbers total length at most recent op)\n * - (clientSeqNumbers total length at refSeq)\n *\n * where the subtraction avoids double-counting segments submitted by clientId sequenced within the collab window.\n *\n * To enable reconnect, if constructed with `computeLocalPartials === true` it also supports querying for the length of\n * the block from the perspective of the local client at a particular `refSeq` and `localSeq`. This computation is\n * similar to the above:\n *\n * (length of the block at the minimum sequence number)\n * + (partialLengths total length at refSeq)\n * + (unsequenced edits' total length submitted before localSeq)\n * + (adjustments for changes double-counted by happening at or before both localSeq and refSeq)\n *\n * This algorithm scales roughly linearly with number of editing clients and the size of the collab window.\n * (certain unlikely sequences of operations may introduce log factors on those variables)\n *\n * @privateRemarks\n * If you are looking to understand this class in more detail, a suggested order of internalization is:\n *\n * 1. The above description and how it relates to the implementation of `getPartialLength` (which implements the above high-level description\n * 2. `PartialSequenceLengthsSet`, which allows binary searching for overall length deltas at a given sequence number and handles updates.\n * 3. The `fromLeaves` method, which is the base case for the [potential] recursion in `combine`\n * 4. The logic in `combine` to aggregate smaller block entries into larger ones\n * 5. The incremental code path of `update`\n */\nexport class PartialSequenceLengths {\n\tpublic static options: PartialSequenceLengthsOptions = {\n\t\tzamboni: true,\n\t};\n\n\t/**\n\t * Length of the block this PartialSequenceLength corresponds to when viewed at `minSeq`.\n\t */\n\tprivate minLength = 0;\n\n\t/**\n\t * Total number of segments in the subtree rooted at the block this PartialSequenceLength corresponds to.\n\t */\n\tprivate segmentCount = 0;\n\n\t/**\n\t * List of PartialSequenceLength objects--ordered by increasing seq--giving length information about\n\t * the block associated with this PartialSequenceLengths object.\n\t *\n\t * `minLength + partialLengths[i].len` gives the length of this block when considering the perspective of an observer\n\t * client who has received edits up to (and including) sequence number `i`.\n\t */\n\tprivate readonly partialLengths: PartialSequenceLengthsSet = new PartialSequenceLengthsSet();\n\n\t/**\n\t * perClientAdjustments[clientId] contains a PartialSequenceLengthsSet of adjustments to the observer client's\n\t * perspective (see {@link PartialSequenceLengths.partialLengths}) necessary to account for changes made by\n\t * that client.\n\t *\n\t * As per doc comment on {@link PartialSequenceLengths}, the overall adjustment performed for the perspective of\n\t * (clientId, refSeq) is given by the sum of length deltas in `perClientAdjustments[clientId]`\n\t * for all sequence numbers S such that S \\>= refSeq.\n\t *\n\t * (since these are ordered by sequence number and we cache cumulative sums, this is implemented using two lookups and a subtraction).\n\t *\n\t * The specific adjustments are roughly categorized as follows:\n\t *\n\t * - Ops submitted by a given client generally receive a partial lengths entry corresponding to their sequence number.\n\t * e.g. insert of \"ABC\" at seq 5 will have a per-client adjustment entry of \\{ seq: 5, seglen: 3 \\}.\n\t *\n\t * - When client A deletes a segment concurrently with client B and loses the race (B's delete is sequenced first),\n\t * A's per-client adjustments will contain an entry with a negative `seglen` corresponding to the length of the segment\n\t * and a sequence number corresponding to that of B's delete. It will *not* receive a per-client adjustment for its own delete.\n\t * This ensures that for perspectives (A, refSeq), the deleted segment will show up as a negative delta for all values of refSeq, since:\n\t * 1. For refSeq \\< B's delete, the per-client adjustment will apply and be added to the total length\n\t * 2. For refSeq \\>= B's delete, B's partial length entry in the overall set will apply, and the per-client adjustment will not apply\n\t *\n\t * - When client A attempts to insert a segment into a location that is concurrently obliterated by client B immediately upon insertion,\n\t * A's per-client adjustments will again not include an entry for its own insert.\n\t * Instead, the entry which would normally contain `seq` equal to that of A's insert would instead have `seq` equal to that of B's obliterate.\n\t * This gives the overall correct behavior: for any perspective which isn't client A, there is no adjustment necessary anywhere (it's as if\n\t * the segment never existed). For client A's perspective, the segment should be considered visible until A has acked B's obliterate.\n\t * This is accomplished as for the perspective (A, refSeq):\n\t * 1. For refSeq \\< B's obliterate, the segment length will be included as part of the per-client adjustment for A\n\t * 2. For refSeq \\>= B's obliterate, the segment will be omitted from the per-client adjustment for A\n\t *\n\t * Note that the special-casing for inserting segments that are immediately obliterated is only necessary for segments that never were visible\n\t * in the tree. If an insert and obliterate are concurrent but the insert is sequenced first, the normal per-client adjustment is fine.\n\t *\n\t * The second case (overlapping removal) applies to any combination of remove / obliterate operations.\n\t */\n\tprivate readonly perClientAdjustments: PartialSequenceLengthsSet[] = [];\n\n\t/**\n\t * Contains information required to answer queries for the length of this segment from the perspective of\n\t * the local client but not including all local segments (i.e., `localSeq !== collabWindow.localSeq`).\n\t * This field is only computed if requested in the constructor (i.e. `computeLocalPartials === true`).\n\t *\n\t * Note that the usage pattern for this list is a bit different from perClientAdjustments: when dealing with perspectives of remote clients,\n\t * we generally want to know what their view of the block was accounting for all changes made by that client as well as all \\<= some refSeq.\n\t *\n\t * However, when dealing with perspectives relevant to the local client, we are still interested in changes made \\<= some refSeq, but instead\n\t * of caring about all changes made by the local client, we additionally want the subset of them that were made \\<= some localSeq.\n\t *\n\t * The PartialSequenceLengthsSets stored in this field therefore track localSeqs rather than seqs (it's still named seq for ease of implementation).\n\t * Furthermore, when computing the length of the block at a given refSeq/localSeq perspective,\n\t * rather than add something like `perClientAdjustments[clientId].latestLeq(latestSeq) - perClientAdjustments[clientId].latestLeq(refSeq)` [to\n\t * get the tail end of adjustments necessary for a remote client client], we instead add `unsequencedRecords.partialLengths.latestLeq(localSeq)`\n\t * [to get the head end of adjustments necessary for the local client].\n\t */\n\tprivate unsequencedRecords: UnsequencedPartialLengthInfo | undefined;\n\n\tconstructor(\n\t\t/**\n\t\t * The minimumSequenceNumber as defined by the collab window used in the last call to `update`,\n\t\t * or if no such calls have been made, the one used on construction.\n\t\t */\n\t\tpublic minSeq: number,\n\t\tcomputeLocalPartials: boolean,\n\t) {\n\t\tif (computeLocalPartials) {\n\t\t\tthis.unsequencedRecords = {\n\t\t\t\tpartialLengths: new PartialSequenceLengthsSet(),\n\t\t\t\tperRefSeqAdjustments: new Map(),\n\t\t\t\tcachedAdjustmentByRefSeq: new Map(),\n\t\t\t};\n\t\t}\n\t}\n\n\t/**\n\t * Combine the partial lengths of block's children\n\t * @param block - an interior node. If `recur` is false, it is assumed that each interior node child of this block\n\t * has its partials up to date.\n\t * @param collabWindow - segment window of the segment tree containing `block`.\n\t * @param recur - whether to recursively compute partial lengths for internal children of `block`.\n\t * This incurs more work, but gives correct bookkeeping in the case that a descendant in the merge tree has been\n\t * modified without bubbling up the resulting partial length change to this block's partials.\n\t * @param computeLocalPartials - whether to compute partial length information about local unsequenced ops.\n\t * This enables querying for the length of the block at a given localSeq, but incurs extra work.\n\t * Local partial information doesn't support `update`.\n\t */\n\tpublic static combine(\n\t\tblock: MergeBlock,\n\t\tcollabWindow: CollaborationWindow,\n\t\trecur = false,\n\t\tcomputeLocalPartials = false,\n\t): PartialSequenceLengths {\n\t\tconst leafPartialLengths = PartialSequenceLengths.fromLeaves(\n\t\t\tblock,\n\t\t\tcollabWindow,\n\t\t\tcomputeLocalPartials,\n\t\t);\n\n\t\tlet hasInternalChild = false;\n\t\tconst childPartials: PartialSequenceLengths[] = [];\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tif (!child.isLeaf()) {\n\t\t\t\thasInternalChild = true;\n\t\t\t\tif (recur) {\n\t\t\t\t\tchild.partialLengths = PartialSequenceLengths.combine(\n\t\t\t\t\t\tchild,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t\ttrue,\n\t\t\t\t\t\tcomputeLocalPartials,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tchildPartials.push(child.partialLengths!);\n\t\t\t}\n\t\t}\n\n\t\t// If there are no internal children, the PartialSequenceLengths returns from `fromLeaves` is exactly correct.\n\t\t// Otherwise, we must additively combine all of the children partial lengths to get this block's totals.\n\t\tconst combinedPartialLengths = hasInternalChild\n\t\t\t? new PartialSequenceLengths(collabWindow.minSeq, computeLocalPartials)\n\t\t\t: leafPartialLengths;\n\t\tif (hasInternalChild) {\n\t\t\tif (leafPartialLengths.partialLengths.size > 0) {\n\t\t\t\t// Some children were leaves; add combined partials from these segments\n\t\t\t\tchildPartials.push(leafPartialLengths);\n\t\t\t}\n\n\t\t\tconst childPartialsLen = childPartials.length;\n\n\t\t\tconst childPartialLengths: PartialSequenceLength[][] = [];\n\t\t\tconst childUnsequencedPartialLengths: PartialSequenceLength[][] = [];\n\t\t\tconst childPerRefSeqAdjustments: Map<number, PartialSequenceLengthsSet>[] = [];\n\t\t\tfor (let i = 0; i < childPartialsLen; i++) {\n\t\t\t\tconst { segmentCount, minLength, partialLengths, unsequencedRecords } =\n\t\t\t\t\tchildPartials[i];\n\t\t\t\tcombinedPartialLengths.segmentCount += segmentCount;\n\t\t\t\tcombinedPartialLengths.minLength += minLength;\n\t\t\t\tchildPartialLengths.push(partialLengths.items as PartialSequenceLength[]);\n\t\t\t\tif (unsequencedRecords) {\n\t\t\t\t\tchildUnsequencedPartialLengths.push(\n\t\t\t\t\t\tunsequencedRecords.partialLengths.items as PartialSequenceLength[],\n\t\t\t\t\t);\n\t\t\t\t\tchildPerRefSeqAdjustments.push(unsequencedRecords.perRefSeqAdjustments);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmergePartialLengths(childPartialLengths, combinedPartialLengths.partialLengths);\n\n\t\t\tif (computeLocalPartials) {\n\t\t\t\tcombinedPartialLengths.unsequencedRecords = {\n\t\t\t\t\tpartialLengths: mergePartialLengths(childUnsequencedPartialLengths),\n\t\t\t\t\tcachedAdjustmentByRefSeq: new Map(),\n\t\t\t\t\tperRefSeqAdjustments: new Map(),\n\t\t\t\t};\n\n\t\t\t\tfor (const perRefSeq of childPerRefSeqAdjustments) {\n\t\t\t\t\tfor (const [refSeq, partials] of perRefSeq) {\n\t\t\t\t\t\tlet combinedPartials =\n\t\t\t\t\t\t\tcombinedPartialLengths.unsequencedRecords.perRefSeqAdjustments.get(refSeq);\n\t\t\t\t\t\tif (combinedPartials === undefined) {\n\t\t\t\t\t\t\tcombinedPartials = new PartialSequenceLengthsSet();\n\t\t\t\t\t\t\tcombinedPartialLengths.unsequencedRecords.perRefSeqAdjustments.set(\n\t\t\t\t\t\t\t\trefSeq,\n\t\t\t\t\t\t\t\tcombinedPartials,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const item of partials.items) {\n\t\t\t\t\t\t\tcombinedPartials.addOrUpdate({ ...item });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// could merge these like we do above rather than do out of order like this\n\t\t\tfor (let i = 0; i < childPartialsLen; i++) {\n\t\t\t\tconst { perClientAdjustments } = childPartials[i];\n\t\t\t\tif (perClientAdjustments.length > 0) {\n\t\t\t\t\tfor (let clientId = 0; clientId < perClientAdjustments.length; clientId++) {\n\t\t\t\t\t\tconst clientAdjustment = perClientAdjustments[clientId];\n\t\t\t\t\t\tif (clientAdjustment === undefined) {\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (const partial of perClientAdjustments[clientId].items) {\n\t\t\t\t\t\t\tcombinedPartialLengths.addClientAdjustment(\n\t\t\t\t\t\t\t\tclientId,\n\t\t\t\t\t\t\t\tpartial.seq,\n\t\t\t\t\t\t\t\tpartial.seglen,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// TODO: incremental zamboni during build\n\t\tif (PartialSequenceLengths.options.zamboni) {\n\t\t\tcombinedPartialLengths.zamboni(collabWindow);\n\t\t}\n\n\t\tPartialSequenceLengths.options.verifier?.(combinedPartialLengths);\n\t\treturn combinedPartialLengths;\n\t}\n\n\t/**\n\t * Create a `PartialSequenceLengths` which tracks only changes incurred by direct child leaves of `block`.\n\t */\n\tprivate static fromLeaves(\n\t\tblock: MergeBlock,\n\n\t\tcollabWindow: CollaborationWindow,\n\t\tcomputeLocalPartials: boolean,\n\t\tretry = true,\n\t): PartialSequenceLengths {\n\t\tconst combinedPartialLengths = new PartialSequenceLengths(\n\t\t\tcollabWindow.minSeq,\n\t\t\tcomputeLocalPartials,\n\t\t);\n\t\tcombinedPartialLengths.segmentCount = block.childCount;\n\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tif (child.isLeaf()) {\n\t\t\t\t// Leaf segment\n\t\t\t\tconst segment = child;\n\t\t\t\tif (wasRemovedOnInsert(segment)) {\n\t\t\t\t\tPartialSequenceLengths.accountForRemoveOnInsert(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tPartialSequenceLengths.accountForInsertion(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t);\n\n\t\t\t\t\tPartialSequenceLengths.accountForRemoval(\n\t\t\t\t\t\tcombinedPartialLengths,\n\t\t\t\t\t\tsegment,\n\t\t\t\t\t\tcollabWindow,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tPartialSequenceLengths.options.verifier?.(combinedPartialLengths);\n\t\treturn combinedPartialLengths;\n\t}\n\n\t/**\n\t * Assuming this segment was removed on insertion, inserts length information about that operation\n\t * into the appropriate per-client adjustments (the overall view needs no such adjustment since\n\t * from an observing client's perspective, the segment never exists).\n\t */\n\tprivate static accountForRemoveOnInsert(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tassertInserted(segment);\n\t\tconst removeInfo = toRemovalInfo(segment);\n\t\tassert(\n\t\t\tremoveInfo !== undefined && wasRemovedOnInsert(segment),\n\t\t\t0xab7 /* Segment was not removed on insert */,\n\t\t);\n\t\tconst firstRemove = removeInfo?.removes[0];\n\t\tif (opstampUtils.lte(firstRemove, getMinSeqStamp(collabWindow))) {\n\t\t\t// This segment was obliterated as soon as it was inserted, and everyone was aware of the obliterate.\n\t\t\t// Thus every single client treats this segment as length 0 from every perspective, and no adjustments\n\t\t\t// are necessary.\n\t\t\treturn;\n\t\t}\n\n\t\tconst { insert, cachedLength } = segment;\n\t\tconst isLocal = opstampUtils.isLocal(insert);\n\t\tconst { clientId } = insert;\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (partials === undefined) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\t// Implication -> this is a local segment which will be obliterated as soon as it is acked.\n\t\t\t// For refSeqs preceding that removedSeq and localSeqs following the localSeq, it will be visible.\n\t\t\t// For the rest, it will not be visible.\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\tconst localSeq = insert.localSeq!;\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: localSeq,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: cachedLength,\n\t\t\t\tclientId,\n\t\t\t});\n\n\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\trefSeq: firstRemove.seq,\n\t\t\t\tlocalSeq,\n\t\t\t\tseglen: -cachedLength,\n\t\t\t});\n\n\t\t\tconst lastRemove = removeInfo.removes[removeInfo.removes.length - 1];\n\t\t\tif (opstampUtils.isLocal(lastRemove)) {\n\t\t\t\t// In addition to a remote sliceRemove causing this segment to be removed as soon as its insertion is acked,\n\t\t\t\t// the local client has also removed it before its insertion was acked.\n\t\t\t\t// It will therefore not be visible for a local reconnecting perspective beyond the removed localSeq.\n\t\t\t\tpartials.addOrUpdate({\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tseq: lastRemove.localSeq!,\n\t\t\t\t\tlen: 0,\n\t\t\t\t\tseglen: -cachedLength,\n\t\t\t\t\tclientId,\n\t\t\t\t});\n\n\t\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\t\trefSeq: firstRemove.seq,\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\t\tlocalSeq: lastRemove.localSeq!,\n\t\t\t\t\tseglen: cachedLength,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\t// Segment was obliterated on insert. Generally this means it should be visible only to the\n\t\t\t// inserting client (in which case we add an adjustment to only that client's perspective),\n\t\t\t// but if that client has also removed it, we don't need to add anything.\n\t\t\tconst wasRemovedByInsertingClient = removeInfo?.removes.some(\n\t\t\t\t(remove) => remove.clientId === clientId,\n\t\t\t);\n\n\t\t\tif (!wasRemovedByInsertingClient) {\n\t\t\t\tconst removeSeq = firstRemove?.seq;\n\t\t\t\tassert(\n\t\t\t\t\tremoveSeq !== undefined,\n\t\t\t\t\t0xab8 /* ObliterateOnInsertion implies removeSeq is defined */,\n\t\t\t\t);\n\t\t\t\tcombinedPartialLengths.addClientAdjustment(clientId, removeSeq, cachedLength);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Inserts length information about the insertion of `segment` into\n\t * `combinedPartialLengths.partialLengths` and the appropriate per-client adjustments.\n\t */\n\tprivate static accountForInsertion(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tassertInserted(segment);\n\t\tif (opstampUtils.lte(segment.insert, getMinSeqStamp(collabWindow))) {\n\t\t\tcombinedPartialLengths.minLength += segment.cachedLength;\n\t\t\treturn;\n\t\t}\n\n\t\tconst { insert, cachedLength: segmentLen } = segment;\n\n\t\tconst isLocal = opstampUtils.isLocal(insert);\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst seqOrLocalSeq = isLocal ? insert.localSeq! : insert.seq;\n\t\tconst clientId = insert.clientId;\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (!partials) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: segmentLen,\n\t\t\t});\n\t\t} else {\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: segmentLen,\n\t\t\t});\n\t\t\tcombinedPartialLengths.addClientAdjustment(clientId, seqOrLocalSeq, segmentLen);\n\t\t}\n\t}\n\n\t/**\n\t * Inserts length information about the removal or obliteration of `segment` into\n\t * `combinedPartialLengths.partialLengths` and the appropriate per-client adjustments.\n\t */\n\tprivate static accountForRemoval(\n\t\tcombinedPartialLengths: PartialSequenceLengths,\n\t\tsegment: ISegmentPrivate,\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\tassertInserted(segment);\n\n\t\tconst removalInfo = toRemovalInfo(segment);\n\t\tif (!removalInfo) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst firstRemove = removalInfo?.removes[0];\n\t\tconst minSeqStamp = getMinSeqStamp(collabWindow);\n\t\tif (firstRemove !== undefined && opstampUtils.lte(firstRemove, minSeqStamp)) {\n\t\t\tcombinedPartialLengths.minLength -= segment.cachedLength;\n\t\t\treturn;\n\t\t}\n\n\t\tconst removalIsLocal = !!firstRemove && opstampUtils.isLocal(firstRemove);\n\t\tconst isLocalInsertion = opstampUtils.isLocal(segment.insert);\n\t\tconst isOnlyLocalRemoval = removalIsLocal;\n\t\tconst isLocal = isLocalInsertion || isOnlyLocalRemoval;\n\n\t\tif (isLocalInsertion && !removalIsLocal) {\n\t\t\tthrow new Error(\"Should have handled this codepath in wasRemovedOnInsertion\");\n\t\t}\n\n\t\tconst lenDelta = -segment.cachedLength;\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst seqOrLocalSeq = removalIsLocal ? firstRemove.localSeq! : firstRemove.seq;\n\t\tconst clientId = firstRemove.clientId;\n\n\t\tconst clientsWithRemoveOrObliterate = new Set<number>(\n\t\t\tremovalInfo?.removes.map((stamp) => stamp.clientId),\n\t\t);\n\n\t\tconst partials = isLocal\n\t\t\t? combinedPartialLengths.unsequencedRecords?.partialLengths\n\t\t\t: combinedPartialLengths.partialLengths;\n\t\tif (partials === undefined) {\n\t\t\t// Local partial but its computation isn't required\n\t\t\treturn;\n\t\t}\n\n\t\tif (isLocal) {\n\t\t\t// The segment is either inserted only locally or removed only locally.\n\t\t\t// We already accounted for the insertion in the accountForInsertion codepath.\n\t\t\t// Only thing left to do is account for the removal in local partial lengths.\n\t\t\t// One thing to be careful about is that the removal should only apply to perspectives that saw\n\t\t\t// the segment's insertion in the first place.\n\t\t\t// When the segment's insertion was common knowledge (at or below minSeq) or also by the local client,\n\t\t\t// all possible perspectives will have seen it.\n\t\t\tif (\n\t\t\t\topstampUtils.lte(segment.insert, minSeqStamp) ||\n\t\t\t\tcollabWindow.clientId === segment.insert.clientId\n\t\t\t) {\n\t\t\t\tpartials.addOrUpdate({\n\t\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\t\tclientId,\n\t\t\t\t\tlen: 0,\n\t\t\t\t\tseglen: lenDelta,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// ... otherwise, it's only visible to reconnecting perspectives above the seq of the insert.\n\t\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\t\tlocalSeq: seqOrLocalSeq,\n\t\t\t\t\trefSeq: segment.insert.seq,\n\t\t\t\t\tseglen: lenDelta,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tpartials.addOrUpdate({\n\t\t\t\tseq: seqOrLocalSeq,\n\t\t\t\tclientId,\n\t\t\t\tlen: 0,\n\t\t\t\tseglen: lenDelta,\n\t\t\t});\n\n\t\t\tfor (const id of clientsWithRemoveOrObliterate) {\n\t\t\t\tif (id === collabWindow.clientId) {\n\t\t\t\t\t// The local client also removed or obliterated this segment.\n\t\t\t\t\tconst { localSeq } = removalInfo.removes[removalInfo.removes.length - 1];\n\t\t\t\t\tif (localSeq === undefined) {\n\t\t\t\t\t\t// Sure, the local client did it--but that change was already acked.\n\t\t\t\t\t\t// No need to account for it in the unsequenced records.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tconst { unsequencedRecords } = combinedPartialLengths;\n\t\t\t\t\tif (!unsequencedRecords) {\n\t\t\t\t\t\t// Local partial but its computation isn't required.\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tassert(\n\t\t\t\t\t\tlocalSeq !== undefined,\n\t\t\t\t\t\t0xaba /* Local client was in removed client ids but segment has no local seq for either */,\n\t\t\t\t\t);\n\n\t\t\t\t\t// Here...\n\t\t\t\t\t// - The segment was removed locally at `localSeq`\n\t\t\t\t\t// - The segment was also removed remotely at `seqOrLocalSeq`\n\t\t\t\t\t// - We're ensuring that partial lengths works for arbitrary `LocalReconnectingPerspective`s.\n\t\t\t\t\t//\n\t\t\t\t\t// Visualize an arbitrary local reconnecting perspective in 2d space, where the x-axis is `seq` and the y-axis is `localSeq`.\n\t\t\t\t\t// The events that have occurred to this segment divide the space into up to 6 regions:\n\t\t\t\t\t//\n\t\t\t\t\t// (localSeq)\n\t\t\t\t\t// | | |\n\t\t\t\t\t// | 1 | 2 | 3\n\t\t\t\t\t// local remove |-----------------------------\n\t\t\t\t\t// | | |\n\t\t\t\t\t// | 4 | 5 | 6\n\t\t\t\t\t// |----------------------------- (seq)\n\t\t\t\t\t// insert remove\n\t\t\t\t\t// In all regions but region 5, the segment has length 0 (it was not inserted yet in regions 1 or 4, and removed locally and/or remotely\n\t\t\t\t\t// in regions 2, 3, and 6).\n\t\t\t\t\t// `accountForInsertion` already added a partial lengths adjustment of +segment.cachedLength for regions 2, 3, 5, and 6.\n\t\t\t\t\t// Above in this function, we've added a partial lengths adjustment of -segment.cachedLength for regions 3 and 6.\n\t\t\t\t\t//\n\t\t\t\t\t// Note that in this picture:\n\t\t\t\t\t// - Adding entries to `unsequencedRecords.partialLengths` is like adding adjustments that affect anything above a given Y value\n\t\t\t\t\t// - Adding entries to `combinedPartialLengths.partialLengths` is like adding adjustments that affect anything above a given X value\n\t\t\t\t\t// - Adding entries with `addLocalAdjustment` is like adding adjustments that affect anything above a given X *and* Y value\n\t\t\t\t\t// The remainder this block adds the necessary adjustments to make the length appear 0 in region 2 as well, keeping in mind that\n\t\t\t\t\t// region 1 may or may not exist depending on if the insertion is in the collab window.\n\t\t\t\t\tif (\n\t\t\t\t\t\topstampUtils.isAcked(segment.insert) &&\n\t\t\t\t\t\topstampUtils.greaterThan(segment.insert, minSeqStamp)\n\t\t\t\t\t) {\n\t\t\t\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\t\t\t\trefSeq: segment.insert.seq,\n\t\t\t\t\t\t\tlocalSeq,\n\t\t\t\t\t\t\tseglen: lenDelta,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tunsequencedRecords.partialLengths.addOrUpdate({\n\t\t\t\t\t\t\tseq: localSeq,\n\t\t\t\t\t\t\tclientId: collabWindow.clientId,\n\t\t\t\t\t\t\tseglen: lenDelta,\n\t\t\t\t\t\t\tlen: 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Because we've included deltas which take effect when either of localSeq or refSeq are high enough,\n\t\t\t\t\t// we need to offset this with an adjustment that takes effect when both are high enough.\n\t\t\t\t\tcombinedPartialLengths.addLocalAdjustment({\n\t\t\t\t\t\trefSeq: seqOrLocalSeq,\n\t\t\t\t\t\tlocalSeq,\n\t\t\t\t\t\t// combinedPartialLengths.partialLengths has an entry removing this segment from a perspective >= seqOrLocalSeq.\n\t\t\t\t\t\t// combinedPartialLengths.unsequencedRecords.partialLengths now has an entry removing this segment from a perspective\n\t\t\t\t\t\t// with local seq >= `localSeq`.\n\t\t\t\t\t\t// In order to only remove this segment once, we add back in the length (where this entry only takes effect when\n\t\t\t\t\t\t// both above are true due to logic in computeOverallRefSeqAdjustment).\n\t\t\t\t\t\tseglen: segment.cachedLength,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Note that all clients that have a remove or obliterate operation on this segment\n\t\t\t\t\t// use the seq of the winning obliterate in their per-client adjustments!\n\t\t\t\t\tcombinedPartialLengths.addClientAdjustment(id, seqOrLocalSeq, lenDelta);\n\n\t\t\t\t\t// Also ensure that all these clients have seen the segment as inserted before being removed\n\t\t\t\t\t// This is technically not necessary for setRemoves (we never ask for the length of this block with\n\t\t\t\t\t// respect to a refSeq which this entry would affect), but it's simpler to just add it here.\n\t\t\t\t\t// We already add this entry as part of the accountForInsertion codepath for the client that\n\t\t\t\t\t// actually did insert the segment, hence not doing so [again] here.\n\t\t\t\t\tif (\n\t\t\t\t\t\topstampUtils.greaterThan(segment.insert, minSeqStamp) &&\n\t\t\t\t\t\tid !== segment.insert.clientId\n\t\t\t\t\t) {\n\t\t\t\t\t\tcombinedPartialLengths.addClientAdjustment(\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\tsegment.insert.seq,\n\t\t\t\t\t\t\tsegment.cachedLength,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * If incremental update of partial lengths fails, this gets set to the seq of the failed update.\n\t * When higher up blocks attempt to incrementally update, they first check if the seq they are updating for\n\t * matches this value. If it does, they propagate a full refresh instead.\n\t */\n\tprivate lastIncrementalInvalidationSeq = Number.NEGATIVE_INFINITY;\n\n\t// Assume: seq is latest sequence number; no structural change to sub-tree, but this partial lengths\n\t// entry needs to account for the change made by the client with `clientId` at sequence number `seq`.\n\t// (and `update` has been called on all descendant PartialSequenceLengths).\n\t// This implementation does not support overlapping removes: callers should recompute partial lengths\n\t// using `combine` when the change that has just been applied involves such an operation.\n\t// TODO: assert client id matches\n\tpublic update(\n\t\tnode: MergeBlock,\n\t\tseq: number,\n\t\tclientId: number,\n\n\t\tcollabWindow: CollaborationWindow,\n\t): void {\n\t\t// In the current implementation, this method gets invoked multiple times for the same sequence number (i.e. mid-operation).\n\t\t// We counter this by first zeroing out existing entries from previous updates, but it isn't ideal.\n\t\t// Even if we fix this at the merge-tree level, the same type of issue can crop up with grouped batching enabled.\n\t\tconst latest = this.partialLengths.latestLeq(seq);\n\t\tif (latest?.seq === seq) {\n\t\t\tthis.partialLengths.addOrUpdate({ seq, len: 0, seglen: -latest.seglen, clientId });\n\t\t}\n\n\t\t// .forEach natively ignores undefined entries.\n\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\tthis.perClientAdjustments.forEach((clientAdjustments) => {\n\t\t\tconst leqPartial = clientAdjustments.latestLeq(seq);\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- using ?. could change behavior\n\t\t\tif (leqPartial && leqPartial.seq === seq) {\n\t\t\t\tthis.addClientAdjustment(clientId, seq, -leqPartial.seglen);\n\t\t\t}\n\t\t});\n\n\t\t/**\n\t\t * If any of the changes made by the client at `seq` necessitate partial length entries at sequence numbers other than `seq`,\n\t\t * this flag is set to true. This propagates upwards when aggregating parents as well.\n\t\t *\n\t\t * Note: it seems feasible to update parents more incrementally by tracking the changes made to child blocks for a given update.\n\t\t * There isn't a great place for this information to flow today.\n\t\t */\n\t\tlet failIncrementalPropagation = false;\n\n\t\tlet seqSeglen = 0;\n\t\tlet segCount = 0;\n\t\t// Compute length for seq across children\n\t\tfor (let i = 0; i < node.childCount; i++) {\n\t\t\tconst child = node.children[i];\n\t\t\tif (child.isLeaf()) {\n\t\t\t\tconst segment = child;\n\t\t\t\tconst removalInfo = toRemovalInfo(segment);\n\t\t\t\tconst firstRemove = removalInfo?.removes[0];\n\t\t\t\tif (seq === segment.insert.seq) {\n\t\t\t\t\t// if this segment was removed on insert, its length should\n\t\t\t\t\t// only be visible to the inserting client\n\t\t\t\t\tif (\n\t\t\t\t\t\tsegment.insert.seq !== undefined &&\n\t\t\t\t\t\tfirstRemove !== undefined &&\n\t\t\t\t\t\twasRemovedOnInsert(segment)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, firstRemove.seq, segment.cachedLength);\n\t\t\t\t\t\tfailIncrementalPropagation = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tseqSeglen += segment.cachedLength;\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, seq, segment.cachedLength);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (opstampUtils.isAcked(segment.insert) && seq === firstRemove?.seq) {\n\t\t\t\t\tseqSeglen -= segment.cachedLength;\n\t\t\t\t\tif (clientId !== collabWindow.clientId) {\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, seq, -segment.cachedLength);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\topstampUtils.greaterThan(segment.insert, getMinSeqStamp(collabWindow)) &&\n\t\t\t\t\t\t\tsegment.insert.clientId !== clientId\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthis.addClientAdjustment(clientId, segment.insert.seq, segment.cachedLength);\n\t\t\t\t\t\t\tfailIncrementalPropagation = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsegCount++;\n\t\t\t} else {\n\t\t\t\tconst childBlock = child;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tconst branchPartialLengths = childBlock.partialLengths!;\n\t\t\t\tif (branchPartialLengths.lastIncrementalInvalidationSeq === seq) {\n\t\t\t\t\t// Bail out.\n\t\t\t\t\tconst newPartials = PartialSequenceLengths.combine(node, collabWindow, false);\n\t\t\t\t\tnewPartials.lastIncrementalInvalidationSeq = seq;\n\t\t\t\t\tnode.partialLengths = newPartials;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst partialLengths = branchPartialLengths.partialLengths;\n\t\t\t\tconst leqPartial = partialLengths.latestLeq(seq);\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- using ?. could change behavior\n\t\t\t\tif (leqPartial && leqPartial.seq === seq) {\n\t\t\t\t\tseqSeglen += leqPartial.seglen;\n\t\t\t\t}\n\t\t\t\tsegCount += branchPartialLengths.segmentCount;\n\n\t\t\t\t// .forEach natively ignores undefined entries.\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-for-each\n\t\t\t\tbranchPartialLengths.perClientAdjustments.forEach((clientAdjustments) => {\n\t\t\t\t\tconst leqBranchPartial = clientAdjustments.latestLeq(seq);\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-optional-chain -- using ?. could change behavior\n\t\t\t\t\tif (leqBranchPartial && leqBranchPartial.seq === seq) {\n\t\t\t\t\t\tthis.addClientAdjustment(clientId, seq, leqBranchPartial.seglen);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (failIncrementalPropagation) {\n\t\t\tthis.lastIncrementalInvalidationSeq = seq;\n\t\t}\n\t\tthis.segmentCount = segCount;\n\t\tthis.unsequencedRecords = undefined;\n\t\tthis.partialLengths.addOrUpdate({ seq, seglen: seqSeglen, len: 0, clientId });\n\n\t\tif (PartialSequenceLengths.options.zamboni) {\n\t\t\tthis.zamboni(collabWindow);\n\t\t}\n\t\tPartialSequenceLengths.options.verifier?.(this);\n\t}\n\n\t/**\n\t * Returns the length of this block as viewed from the perspective of `clientId` at `refSeq`.\n\t * This is the total length of all segments sequenced at or before refSeq OR submitted by `clientId`.\n\t * If `clientId` is the local client, `localSeq` can also be provided. In that case, it is the total\n\t * length of all segments submitted at or before `refSeq` in addition to any local, unacked segments\n\t * with `segment.localSeq <= localSeq`.\n\t *\n\t * Note: the local case (where `localSeq !== undefined`) is only supported on a PartialSequenceLength object\n\t * constructed with `computeLocalPartials` set to true and not subsequently updated with `update`.\n\t */\n\tpublic getPartialLength(refSeq: number, clientId: number, localSeq?: number): number {\n\t\tlet length = this.minLength;\n\t\tlength += this.partialLengths.latestLeq(refSeq)?.len ?? 0;\n\n\t\tif (localSeq === undefined) {\n\t\t\tconst latestClientEntry = this.latestClientEntry(clientId);\n\t\t\tif (latestClientEntry !== undefined && latestClientEntry.seq > refSeq) {\n\t\t\t\t// The client has local edits after refSeq, add in the length adjustments\n\t\t\t\tlength += latestClientEntry.len;\n\t\t\t\tconst precedingCli = this.latestClientEntryLEQ(clientId, refSeq);\n\t\t\t\tif (precedingCli) {\n\t\t\t\t\t// Subtract out double-counted lengths: segments still in the collab window but before\n\t\t\t\t\t// the refSeq submitted by the client we're querying for were counted in each addition above.\n\t\t\t\t\tlength -= precedingCli.len;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tassert(\n\t\t\t\tthis.unsequencedRecords !== undefined,\n\t\t\t\t0x39f /* Local getPartialLength invoked without computing local partials. */,\n\t\t\t);\n\t\t\tconst unsequencedPartialLengths = this.unsequencedRecords.partialLengths;\n\t\t\t// Local segments at or before localSeq should also be included\n\t\t\tlength += unsequencedPartialLengths.latestLeq(localSeq)?.len ?? 0;\n\n\t\t\t// Lastly, we must add in any additional adjustment that should only take effect when both\n\t\t\t// refSeq AND localSeq are above some threshold. This accounts for things like double-counting\n\t\t\t// local+remote removes, or only subtracting the length out of a local remove if we've also seen\n\t\t\t// the insert of the segment it affects. (see addLocalAdjustment usages for examples)\n\t\t\tlength += this.computeOverallRefSeqAdjustment(refSeq, localSeq);\n\t\t}\n\t\treturn length;\n\t}\n\n\t/**\n\t * Computes the seglen for the double-counted removed overlap at (refSeq, localSeq).\n\t *\n\t * Reconnect happens to only need to compute these lengths for two refSeq values: before and\n\t * after the rebase. Since these lists potentially scale with O(collab window * number of local edits)\n\t * and potentially need to be queried for each local op that gets rebased,\n\t * we cache the results for a given refSeq in `this.unsequencedRecords.cachedOverlappingByRefSeq` so\n\t * that they can be binary-searched the same way the usual partialLengths lists are.\n\t */\n\tprivate computeOverallRefSeqAdjustment(refSeq: number, localSeq: number): number {\n\t\tif (this.unsequencedRecords === undefined) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tlet cachedAdjustment = this.unsequencedRecords.cachedAdjustmentByRefSeq.get(refSeq);\n\t\tif (!cachedAdjustment) {\n\t\t\tconst partials: PartialSequenceLengthsSet = new PartialSequenceLengthsSet();\n\t\t\tfor (const [\n\t\t\t\tseq,\n\t\t\t\tadjustments,\n\t\t\t] of this.unsequencedRecords.perRefSeqAdjustments.entries()) {\n\t\t\t\tif (seq > refSeq) {\n\t\t\t\t\t// TODO: Prior code path got away with an early exit here by sorting the entries by refSeq.\n\t\t\t\t\t// We could do the same here if we wanted.\n\t\t\t\t\t// Old codepath basically flattened the 2d array into a 1d array with both dimensions listed.\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tfor (const partial of adjustments.items) {\n\t\t\t\t\t// This coalesces entries with the same localSeq as well as computes overall lengths.\n\t\t\t\t\tpartials.addOrUpdate({ ...partial });\n\t\t\t\t}\n\t\t\t}\n\t\t\tcachedAdjustment = partials;\n\t\t\tthis.unsequencedRecords.cachedAdjustmentByRefSeq.set(refSeq, cachedAdjustment);\n\t\t}\n\n\t\tconst overlap = cachedAdjustment.latestLeq(localSeq);\n\t\treturn overlap?.len ?? 0;\n\t}\n\n\tpublic toString(glc?: (id: number) => string, indentCount = 0): string {\n\t\tlet buf = \"\";\n\t\tfor (const partial of this.partialLengths.items) {\n\t\t\tbuf += `(${partial.seq},${partial.len}) `;\n\t\t}\n\n\t\t// eslint-disable-next-line @typescript-eslint/no-for-in-array, no-restricted-syntax\n\t\tfor (const clientId in this.perClientAdjustments) {\n\t\t\tif (this.perClientAdjustments[clientId].size > 0) {\n\t\t\t\tbuf += `Client `;\n\t\t\t\tbuf += glc ? `${glc(+clientId)}` : `${clientId}`;\n\t\t\t\tbuf += \"[\";\n\t\t\t\tfor (const partial of this.perClientAdjustments[clientId].items) {\n\t\t\t\t\tbuf += `(${partial.seq},${partial.len})`;\n\t\t\t\t}\n\t\t\t\tbuf += \"]\";\n\t\t\t}\n\t\t}\n\t\tbuf = `min(seq ${this.minSeq}): ${this.minLength}; sc: ${this.segmentCount};${buf}`;\n\t\treturn buf;\n\t}\n\n\t// Clear away partial sums for sequence numbers earlier than the current window\n\n\tprivate zamboni(segmentWindow: CollaborationWindow): void {\n\t\tthis.minLength += this.partialLengths.copyDown(segmentWindow.minSeq);\n\t\tthis.minSeq = segmentWindow.minSeq;\n\t\t// eslint-disable-next-line @typescript-eslint/no-for-in-array, guard-for-in, no-restricted-syntax\n\t\tfor (const clientId in this.perClientAdjustments) {\n\t\t\tconst cliPartials = this.perClientAdjustments[clientId];\n\t\t\tif (cliPartials) {\n\t\t\t\tcliPartials.copyDown(segmentWindow.minSeq);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate addClientAdjustment(clientId: number, seq: number, seglen: number): void {\n\t\tthis.perClientAdjustments[clientId] ??= new PartialSequenceLengthsSet();\n\t\tconst cli = this.perClientAdjustments[clientId];\n\t\tcli.addOrUpdate({ seq, len: 0, seglen });\n\t}\n\n\tprivate addLocalAdjustment({\n\t\trefSeq,\n\t\tlocalSeq,\n\t\tseglen,\n\t}: { refSeq: number; localSeq: number; seglen: number }): void {\n\t\tassert(\n\t\t\tthis.unsequencedRecords !== undefined,\n\t\t\t0xabb /* Local adjustment computed without partials */,\n\t\t);\n\t\tconst adjustments =\n\t\t\tthis.unsequencedRecords.perRefSeqAdjustments.get(refSeq) ??\n\t\t\tnew PartialSequenceLengthsSet();\n\t\tthis.unsequencedRecords.perRefSeqAdjustments.set(refSeq, adjustments);\n\t\tadjustments.addOrUpdate({ seq: localSeq, len: 0, seglen });\n\t}\n\n\t/**\n\t * Returns the partial lengths associated with the latest change associated with `clientId` at or before `refSeq`.\n\t * Returns undefined if no such change exists.\n\t */\n\tprivate latestClientEntryLEQ(\n\t\tclientId: number,\n\t\trefSeq: number,\n\t): PartialSequenceLength | undefined {\n\t\treturn this.perClientAdjustments[clientId]?.latestLeq(refSeq);\n\t}\n\n\t/**\n\t * Get the partial lengths associated with the most recent change received by `clientId`, or undefined\n\t * if this client has made no changes in this block within the collab window.\n\t */\n\tprivate latestClientEntry(clientId: number): PartialSequenceLength | undefined {\n\t\tconst cliSeqs = this.perClientAdjustments[clientId];\n\t\treturn cliSeqs && cliSeqs.size > 0 ? cliSeqs.items[cliSeqs.size - 1] : undefined;\n\t}\n}\n\n/* eslint-disable @typescript-eslint/dot-notation */\nfunction verifyPartialLengthsInner(\n\tpartialSeqLengths: PartialSequenceLengths,\n\tpartialLengths: PartialSequenceLengthsSet,\n\tclientPartials: boolean,\n): number {\n\tif (partialLengths.size === 0) {\n\t\treturn 0;\n\t}\n\n\tlet lastSeqNum = 0;\n\tlet accumSegLen = 0;\n\tlet count = 0;\n\n\tfor (const partialLength of partialLengths.items) {\n\t\t// Count total number of partial length entries\n\t\tcount++;\n\n\t\t// Sequence number should be larger or equal to minseq\n\t\tassert(\n\t\t\tpartialSeqLengths.minSeq <= partialLength.seq,\n\t\t\t0x054 /* \"Sequence number less than minSeq!\" */,\n\t\t);\n\n\t\t// Sequence number should be sorted\n\t\tassert(lastSeqNum < partialLength.seq, 0x055 /* \"Sequence number is not sorted!\" */);\n\t\tlastSeqNum = partialLength.seq;\n\n\t\t// Len is a accumulation of all the seglen adjustments\n\t\taccumSegLen += partialLength.seglen;\n\t\tif (accumSegLen !== partialLength.len) {\n\t\t\tassert(\n\t\t\t\tfalse,\n\t\t\t\t0x056 /* \"Unexpected total for accumulation of all seglen adjustments!\" */,\n\t\t\t);\n\t\t}\n\n\t\tif (clientPartials) {\n\t\t\t// Client partials used to track local edits so we can account for them some refSeq.\n\t\t\t// But the information we keep track of are since minSeq, so we keep track of more history\n\t\t\t// then needed, and some of them doesn't make sense to be used for length calculations\n\t\t\t// e.g. if you have this sequence, where the minSeq is #5 because of other clients\n\t\t\t// seq 10: client 1: insert seg #1\n\t\t\t// seq 11: client 2: delete seg #2 refseq: 10\n\t\t\t// minLength is 0, we would have keep a record of seglen: -1 for clientPartialLengths for client 2\n\t\t\t// So if you ask for partial length for client 2 @ seq 5, we will have return -1.\n\t\t\t// However, that combination is invalid, since we should never see any ops with refseq < 10 for\n\t\t\t// client 2 after seq 11.\n\t\t} else {\n\t\t\t// Len adjustment should not make length negative\n\t\t\tif (partialSeqLengths[\"minLength\"] + partialLength.len < 0) {\n\t\t\t\tassert(false, 0x057 /* \"Negative length after length adjustment!\" */);\n\t\t\t}\n\t\t}\n\t}\n\treturn count;\n}\n\nexport function verifyExpectedPartialLengths(\n\tmergeTree: MergeTree,\n\tnode: MergeBlock,\n\trefSeq: number,\n\tclientId: number,\n\tlocalSeq?: number,\n): void {\n\tif (\n\t\t(!mergeTree.collabWindow.collaborating || mergeTree.collabWindow.clientId === clientId) &&\n\t\t(node.isLeaf() || localSeq === undefined)\n\t) {\n\t\treturn;\n\t}\n\n\tconst partialLen = node.partialLengths?.getPartialLength(refSeq, clientId, localSeq);\n\n\tlet expected = 0;\n\tconst nodesToVisit: IMergeNode[] = [node];\n\tconst perspective =\n\t\tclientId === mergeTree.collabWindow.clientId\n\t\t\t? localSeq === undefined\n\t\t\t\t? new LocalDefaultPerspective(clientId)\n\t\t\t\t: new LocalReconnectingPerspective(refSeq, clientId, localSeq)\n\t\t\t: new PriorPerspective(refSeq, clientId);\n\n\twhile (nodesToVisit.length > 0) {\n\t\tconst thisNode = nodesToVisit.pop();\n\t\tif (!thisNode) {\n\t\t\tcontinue;\n\t\t}\n\t\tif (thisNode.isLeaf()) {\n\t\t\texpected += mergeTree[\"nodeLength\"](thisNode, perspective) ?? 0;\n\t\t} else {\n\t\t\tnodesToVisit.push(...thisNode.children.slice(0, thisNode.childCount));\n\t\t}\n\t}\n\n\tif (expected !== partialLen) {\n\t\tconst nonIncrementalPartials = PartialSequenceLengths.combine(\n\t\t\tnode,\n\t\t\tmergeTree.collabWindow,\n\t\t\tfalse,\n\t\t\ttrue,\n\t\t);\n\t\tconst nonIncrementalLength = nonIncrementalPartials.getPartialLength(\n\t\t\trefSeq,\n\t\t\tclientId,\n\t\t\tlocalSeq,\n\t\t);\n\t\tnode.partialLengths?.getPartialLength(refSeq, clientId, localSeq);\n\n\t\tthrow new Error(\n\t\t\t`expected partial length of ${expected} but found ${partialLen}. refSeq: ${refSeq}, clientId: ${clientId}. (non-incremental codepath returned ${nonIncrementalLength})`,\n\t\t);\n\t}\n}\n\nexport function verifyPartialLengths(partialSeqLengths: PartialSequenceLengths): void {\n\tif (partialSeqLengths[\"perClientAdjustments\"]) {\n\t\tfor (const cliSeq of partialSeqLengths[\"perClientAdjustments\"]) {\n\t\t\tif (cliSeq) {\n\t\t\t\tverifyPartialLengthsInner(partialSeqLengths, cliSeq, true);\n\t\t\t}\n\t\t}\n\n\t\t// If we have client view, we should have the flat view\n\t\tassert(\n\t\t\t!!partialSeqLengths[\"partialLengths\"],\n\t\t\t0x059 /* \"Client view exists but flat view does not!\" */,\n\t\t);\n\n\t\tverifyPartialLengthsInner(partialSeqLengths, partialSeqLengths[\"partialLengths\"], false);\n\t} else {\n\t\t// If we don't have a client view, we shouldn't have the flat view either\n\t\tassert(\n\t\t\t!partialSeqLengths[\"partialLengths\"],\n\t\t\t0x05b /* \"Flat view exists but client view does not!\" */,\n\t\t);\n\t}\n}\n/* eslint-enable @typescript-eslint/dot-notation */\n\n/**\n * Given a number of seq-sorted `partialLength` lists, merges them into a combined seq-sorted `partialLength`\n * list. This merge includes coalescing `PartialSequenceLength` entries at the same seq.\n *\n * Ex: merging the following two lists (some information omitted on each PartialSequenceLength):\n * ```typescript\n * [{ seq: 1, seglen: 5 }, { seq: 3, seglen: -1 }]\n * [{ seq: 1, seglen: -3 }, { seq: 2: seglen: 4 }]\n * ```\n * would produce\n * ```typescript\n * [{ seq: 1, seglen: 2 }, { seq: 2, seglen: 4 }, { seq: 3, seglen: -1 }]\n * ```\n */\nfunction mergePartialLengths(\n\tchildPartialLengths: PartialSequenceLength[][],\n\tmergedLengths: PartialSequenceLengthsSet = new PartialSequenceLengthsSet(),\n): PartialSequenceLengthsSet {\n\tfor (const partialLength of mergeSortedListsBySeq(childPartialLengths)) {\n\t\tmergedLengths.addOrUpdate({\n\t\t\t...partialLength,\n\t\t});\n\t}\n\treturn mergedLengths;\n}\n\n/**\n * Given a collection of PartialSequenceLength lists--each sorted by sequence number--returns an iterable that yields\n * each PartialSequenceLength in sequence order.\n *\n * This is equivalent to flattening the input list and sorting it by sequence number. If the number of lists to merge is\n * a constant, however, this approach is advantageous asymptotically.\n */\nfunction mergeSortedListsBySeq<T extends PartialSequenceLength>(lists: T[][]): Iterable<T> {\n\tclass PartialSequenceLengthIterator {\n\t\t/**\n\t\t * nextSmallestIndex[i] is the next element of sublists[i] to check.\n\t\t * In other words, the iterator has already yielded elements of sublists[i] *up through*\n\t\t * sublists[i][nextSmallestIndex[i] - 1].\n\t\t */\n\t\tprivate readonly nextSmallestIndex: number[];\n\n\t\tconstructor(private readonly sublists: T[][]) {\n\t\t\tthis.nextSmallestIndex = Array.from({ length: sublists.length });\n\t\t\tfor (let i = 0; i < sublists.length; i++) {\n\t\t\t\tthis.nextSmallestIndex[i] = 0;\n\t\t\t}\n\t\t}\n\n\t\tpublic next(): { value: T; done: false } | { value: undefined; done: true } {\n\t\t\tconst len = this.sublists.length;\n\t\t\tlet currentMin: T | undefined;\n\t\t\tlet currentMinIndex: number | undefined;\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\tconst candidateIndex = this.nextSmallestIndex[i];\n\t\t\t\tif (candidateIndex < this.sublists[i].length) {\n\t\t\t\t\tconst candidate = this.sublists[i][candidateIndex];\n\t\t\t\t\tif (!currentMin || candidate.seq < currentMin.seq) {\n\t\t\t\t\t\tcurrentMin = candidate;\n\t\t\t\t\t\tcurrentMinIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (currentMin) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tthis.nextSmallestIndex[currentMinIndex!]++;\n\t\t\t\treturn { value: currentMin, done: false };\n\t\t\t} else {\n\t\t\t\treturn { value: undefined, done: true };\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { [Symbol.iterator]: () => new PartialSequenceLengthIterator(lists) };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC;IACzB,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;CACnB;AAED;;;;;;;;;GASG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,CAAC,EAAE,WAAW,GAAG,SAAS,EAC1B,CAAC,EAAE,WAAW,GAAG,SAAS,GACxB,OAAO,CA0BT;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,CAczF;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAMlF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,QAAQ,EAAE,WAAW,GACnB,WAAW,CAEb;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAClC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAChB,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAC/B,OAAO,CAAC,CAAC,CAAC,CASZ;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAEzC"}
1
+ {"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,WAAW,OAAO,CAAC,CAAC;IACzB,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC;CACnB;AAED;;;;;;;;;GASG;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;AAEvC;;;;GAIG;AACH,wBAAgB,eAAe,CAC9B,CAAC,EAAE,WAAW,GAAG,SAAS,EAC1B,CAAC,EAAE,WAAW,GAAG,SAAS,GACxB,OAAO,CA0BT;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,CAczF;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAMlF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,WAAW,GAAG,SAAS,EACjC,QAAQ,EAAE,WAAW,GACnB,WAAW,CAEb;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAClC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAChB,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,GAC/B,OAAO,CAAC,CAAC,CAAC,CAUZ;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAEzC"}
@@ -90,6 +90,7 @@ exports.addProperties = addProperties;
90
90
  function extendIfUndefined(base, extension) {
91
91
  if (extension !== undefined) {
92
92
  for (const [key, value] of Object.entries(extension)) {
93
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
93
94
  if (base[key] === undefined) {
94
95
  base[key] = value;
95
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"properties.js","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Any mapping from a string to values of type `T`\n * @legacy @beta\n */\nexport interface MapLike<T> {\n\t[index: string]: T;\n}\n\n/**\n * A loosely-typed mapping from strings to any value.\n *\n * @remarks Property sets are expected to be JSON-stringify-able.\n *\n * @privateRemarks PropertySet is typed using `any` because when you include\n * custom methods such as toJSON(), JSON.stringify accepts most types other than\n * functions\n * @legacy @beta\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PropertySet = MapLike<any>;\n\n/**\n * Compares two PropertySets for equality.\n *\n * @internal\n */\nexport function matchProperties(\n\ta: PropertySet | undefined,\n\tb: PropertySet | undefined,\n): boolean {\n\tif (!a && !b) {\n\t\treturn true;\n\t}\n\n\tconst keysA = a ? Object.keys(a) : [];\n\tconst keysB = b ? Object.keys(b) : [];\n\n\tif (keysA.length !== keysB.length) {\n\t\treturn false;\n\t}\n\n\tfor (const key of keysA) {\n\t\tif (b?.[key] === undefined) {\n\t\t\treturn false;\n\t\t} else if (typeof b[key] === \"object\") {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tif (!matchProperties(a?.[key], b[key])) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if (b[key] !== a?.[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Adds properties from one PropertySet to another.\n *\n * @internal\n */\nexport function extend<T>(base: MapLike<T>, extension: MapLike<T> | undefined): MapLike<T> {\n\tif (extension !== undefined) {\n\t\tfor (const [key, v] of Object.entries(extension)) {\n\t\t\tif (v === undefined) {\n\t\t\t\tcontinue;\n\t\t\t} else if (v === null) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete base[key];\n\t\t\t} else {\n\t\t\t\tbase[key] = v;\n\t\t\t}\n\t\t}\n\t}\n\treturn base;\n}\n\n/**\n * Clones properties in a given PropertySet into a new PropertySet.\n *\n * @internal\n */\nexport function clone<T>(extension: MapLike<T> | undefined): MapLike<T> | undefined {\n\tif (extension === undefined) {\n\t\treturn undefined;\n\t}\n\tconst cloneMap = createMap<T>();\n\treturn extend(cloneMap, extension);\n}\n\n/**\n * Add properties in one PropertySet to another PropertySet. If the PropertySet we are adding\n * to does not exist, create one.\n *\n * @internal\n */\nexport function addProperties(\n\toldProps: PropertySet | undefined,\n\tnewProps: PropertySet,\n): PropertySet {\n\treturn extend(oldProps ?? createMap<unknown>(), newProps);\n}\n\n/**\n * Replace values of undefined in one PropertySet with values for the same key from another PropertySet.\n *\n * @internal\n */\nexport function extendIfUndefined<T>(\n\tbase: MapLike<T>,\n\textension: MapLike<T> | undefined,\n): MapLike<T> {\n\tif (extension !== undefined) {\n\t\tfor (const [key, value] of Object.entries(extension)) {\n\t\t\tif (base[key] === undefined) {\n\t\t\t\tbase[key] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn base;\n}\n\n/**\n * Create a MapLike with good performance.\n *\n * @internal\n */\nexport function createMap<T>(): MapLike<T> {\n\treturn Object.create(null) as MapLike<T>;\n}\n"]}
1
+ {"version":3,"file":"properties.js","sourceRoot":"","sources":["../src/properties.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/**\n * Any mapping from a string to values of type `T`\n * @legacy @beta\n */\nexport interface MapLike<T> {\n\t[index: string]: T;\n}\n\n/**\n * A loosely-typed mapping from strings to any value.\n *\n * @remarks Property sets are expected to be JSON-stringify-able.\n *\n * @privateRemarks PropertySet is typed using `any` because when you include\n * custom methods such as toJSON(), JSON.stringify accepts most types other than\n * functions\n * @legacy @beta\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type PropertySet = MapLike<any>;\n\n/**\n * Compares two PropertySets for equality.\n *\n * @internal\n */\nexport function matchProperties(\n\ta: PropertySet | undefined,\n\tb: PropertySet | undefined,\n): boolean {\n\tif (!a && !b) {\n\t\treturn true;\n\t}\n\n\tconst keysA = a ? Object.keys(a) : [];\n\tconst keysB = b ? Object.keys(b) : [];\n\n\tif (keysA.length !== keysB.length) {\n\t\treturn false;\n\t}\n\n\tfor (const key of keysA) {\n\t\tif (b?.[key] === undefined) {\n\t\t\treturn false;\n\t\t} else if (typeof b[key] === \"object\") {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\tif (!matchProperties(a?.[key], b[key])) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if (b[key] !== a?.[key]) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\n/**\n * Adds properties from one PropertySet to another.\n *\n * @internal\n */\nexport function extend<T>(base: MapLike<T>, extension: MapLike<T> | undefined): MapLike<T> {\n\tif (extension !== undefined) {\n\t\tfor (const [key, v] of Object.entries(extension)) {\n\t\t\tif (v === undefined) {\n\t\t\t\tcontinue;\n\t\t\t} else if (v === null) {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n\t\t\t\tdelete base[key];\n\t\t\t} else {\n\t\t\t\tbase[key] = v;\n\t\t\t}\n\t\t}\n\t}\n\treturn base;\n}\n\n/**\n * Clones properties in a given PropertySet into a new PropertySet.\n *\n * @internal\n */\nexport function clone<T>(extension: MapLike<T> | undefined): MapLike<T> | undefined {\n\tif (extension === undefined) {\n\t\treturn undefined;\n\t}\n\tconst cloneMap = createMap<T>();\n\treturn extend(cloneMap, extension);\n}\n\n/**\n * Add properties in one PropertySet to another PropertySet. If the PropertySet we are adding\n * to does not exist, create one.\n *\n * @internal\n */\nexport function addProperties(\n\toldProps: PropertySet | undefined,\n\tnewProps: PropertySet,\n): PropertySet {\n\treturn extend(oldProps ?? createMap<unknown>(), newProps);\n}\n\n/**\n * Replace values of undefined in one PropertySet with values for the same key from another PropertySet.\n *\n * @internal\n */\nexport function extendIfUndefined<T>(\n\tbase: MapLike<T>,\n\textension: MapLike<T> | undefined,\n): MapLike<T> {\n\tif (extension !== undefined) {\n\t\tfor (const [key, value] of Object.entries(extension)) {\n\t\t\t// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy\n\t\t\tif (base[key] === undefined) {\n\t\t\t\tbase[key] = value;\n\t\t\t}\n\t\t}\n\t}\n\treturn base;\n}\n\n/**\n * Create a MapLike with good performance.\n *\n * @internal\n */\nexport function createMap<T>(): MapLike<T> {\n\treturn Object.create(null) as MapLike<T>;\n}\n"]}
@@ -9,7 +9,7 @@ const snapshot_utils_js_1 = require("./snapshot.utils.js");
9
9
  describe("MergeTree snapshots", () => {
10
10
  let summary;
11
11
  for (const summarySize of [10, 50, 100, 500, 1000, 5000, 10_000]) {
12
- (0, benchmark_1.benchmark)({
12
+ const test = (0, benchmark_1.benchmark)({
13
13
  type: benchmark_1.BenchmarkType.Measurement,
14
14
  title: `load snapshot with ${summarySize} segments`,
15
15
  category: "snapshot loading",
@@ -29,6 +29,11 @@ describe("MergeTree snapshots", () => {
29
29
  summary = undefined;
30
30
  },
31
31
  });
32
+ if (summarySize > 5000) {
33
+ const currentTimeout = test.timeout();
34
+ // Default value of 2 seconds causes failure around P95 for large snapshot sizes.
35
+ test.timeout(currentTimeout === 0 ? 0 : Math.max(5000, currentTimeout));
36
+ }
32
37
  }
33
38
  });
34
39
  //# sourceMappingURL=Snapshot.perf.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Snapshot.perf.spec.js","sourceRoot":"","sources":["../../src/test/Snapshot.perf.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,sDAAkE;AAGlE,2DAA+D;AAE/D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACpC,IAAI,OAAiC,CAAC;IAEtC,KAAK,MAAM,WAAW,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAClE,IAAA,qBAAS,EAAC;YACT,IAAI,EAAE,yBAAa,CAAC,WAAW;YAC/B,KAAK,EAAE,sBAAsB,WAAW,WAAW;YACnD,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,GAAG,EAAE;gBACZ,MAAM,GAAG,GAAG,IAAI,8BAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACxB,CAAC;gBAED,GAAG,CAAC,eAAe,EAAE,CAAC;gBACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YAC5B,CAAC;YACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;gBAC5B,oEAAoE;gBACpE,MAAM,IAAA,gCAAY,EAAC,OAAQ,CAAC,CAAC;YAC9B,CAAC;YACD,KAAK,EAAE,GAAG,EAAE;gBACX,OAAO,GAAG,SAAS,CAAC;YACrB,CAAC;SACD,CAAC,CAAC;IACJ,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmark } from \"@fluid-tools/benchmark\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\n\nimport { TestString, loadSnapshot } from \"./snapshot.utils.js\";\n\ndescribe(\"MergeTree snapshots\", () => {\n\tlet summary: ISummaryTree | undefined;\n\n\tfor (const summarySize of [10, 50, 100, 500, 1000, 5000, 10_000]) {\n\t\tbenchmark({\n\t\t\ttype: BenchmarkType.Measurement,\n\t\t\ttitle: `load snapshot with ${summarySize} segments`,\n\t\t\tcategory: \"snapshot loading\",\n\t\t\tbefore: () => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < summarySize; i++) {\n\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t}\n\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tsummary = str.getSummary();\n\t\t\t},\n\t\t\tbenchmarkFnAsync: async () => {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tawait loadSnapshot(summary!);\n\t\t\t},\n\t\t\tafter: () => {\n\t\t\t\tsummary = undefined;\n\t\t\t},\n\t\t});\n\t}\n});\n"]}
1
+ {"version":3,"file":"Snapshot.perf.spec.js","sourceRoot":"","sources":["../../src/test/Snapshot.perf.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,sDAAkE;AAGlE,2DAA+D;AAE/D,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACpC,IAAI,OAAiC,CAAC;IAEtC,KAAK,MAAM,WAAW,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,IAAA,qBAAS,EAAC;YACtB,IAAI,EAAE,yBAAa,CAAC,WAAW;YAC/B,KAAK,EAAE,sBAAsB,WAAW,WAAW;YACnD,QAAQ,EAAE,kBAAkB;YAC5B,MAAM,EAAE,GAAG,EAAE;gBACZ,MAAM,GAAG,GAAG,IAAI,8BAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACxB,CAAC;gBAED,GAAG,CAAC,eAAe,EAAE,CAAC;gBACtB,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YAC5B,CAAC;YACD,gBAAgB,EAAE,KAAK,IAAI,EAAE;gBAC5B,oEAAoE;gBACpE,MAAM,IAAA,gCAAY,EAAC,OAAQ,CAAC,CAAC;YAC9B,CAAC;YACD,KAAK,EAAE,GAAG,EAAE;gBACX,OAAO,GAAG,SAAS,CAAC;YACrB,CAAC;SACD,CAAC,CAAC;QAEH,IAAI,WAAW,GAAG,IAAI,EAAE,CAAC;YACxB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACtC,iFAAiF;YACjF,IAAI,CAAC,OAAO,CAAC,cAAc,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;QACzE,CAAC;IACF,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { BenchmarkType, benchmark } from \"@fluid-tools/benchmark\";\nimport type { ISummaryTree } from \"@fluidframework/driver-definitions\";\n\nimport { TestString, loadSnapshot } from \"./snapshot.utils.js\";\n\ndescribe(\"MergeTree snapshots\", () => {\n\tlet summary: ISummaryTree | undefined;\n\n\tfor (const summarySize of [10, 50, 100, 500, 1000, 5000, 10_000]) {\n\t\tconst test = benchmark({\n\t\t\ttype: BenchmarkType.Measurement,\n\t\t\ttitle: `load snapshot with ${summarySize} segments`,\n\t\t\tcategory: \"snapshot loading\",\n\t\t\tbefore: () => {\n\t\t\t\tconst str = new TestString(\"id\", {});\n\t\t\t\tfor (let i = 0; i < summarySize; i++) {\n\t\t\t\t\tstr.append(\"a\", false);\n\t\t\t\t}\n\n\t\t\t\tstr.applyPendingOps();\n\t\t\t\tsummary = str.getSummary();\n\t\t\t},\n\t\t\tbenchmarkFnAsync: async () => {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tawait loadSnapshot(summary!);\n\t\t\t},\n\t\t\tafter: () => {\n\t\t\t\tsummary = undefined;\n\t\t\t},\n\t\t});\n\n\t\tif (summarySize > 5000) {\n\t\t\tconst currentTimeout = test.timeout();\n\t\t\t// Default value of 2 seconds causes failure around P95 for large snapshot sizes.\n\t\t\ttest.timeout(currentTimeout === 0 ? 0 : Math.max(5000, currentTimeout));\n\t\t}\n\t}\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"beastTest.spec.d.ts","sourceRoot":"","sources":["../../src/test/beastTest.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,sCAAsC,CAAC;AAoChF,OAAO,EAAE,UAAU,EAA2B,MAAM,iBAAiB,CAAC;AAmHtE,wBAAgB,UAAU,IAAI,IAAI,CAYjC;AAcD,wBAAgB,YAAY,IAAI,MAAM,CAsCrC;AAED,wBAAgB,SAAS,IAAI,IAAI,CAoDhC;AAwED,wBAAgB,cAAc,IAAI,IAAI,CAwBrC;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CA8EzC;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAgM7C;AAID,wBAAgB,QAAQ,CAAC,OAAO,UAAO,GAAG;IACzC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,YAAY,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClE,cAAc,EAAE,MAAM,IAAI,CAAC;CAC3B,CAqpBA;AAYD,qBAAa,UAAU;IACtB,MAAM,EAAE,OAAO,CAAC;;IAKhB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAI7C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CA+BrC;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,YAAY,CAAC;AACjD;;;;;;;GAOG;AACH,qBAAa,YAAY;IAOhB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,YAAY,EAAE;IAPhC,GAAG,SAAK;IACR,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAsB;IACjD,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IACvB,MAAM,CAAC,QAAQ,aAAoB;gBAG3B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,YAAY,EAAE;IAGhC,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IA2C/D,MAAM,CAAC,gBAAgB,IAAI,YAAY;IAKvC,MAAM,CAAC,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY,EAAE;IAuB9D,MAAM,CAAC,iBAAiB,IAAI,YAAY;IAOxC,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY;IAUxD,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY;CAGxD"}
1
+ {"version":3,"file":"beastTest.spec.d.ts","sourceRoot":"","sources":["../../src/test/beastTest.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,sCAAsC,CAAC;AAoChF,OAAO,EAAE,UAAU,EAA2B,MAAM,iBAAiB,CAAC;AAqHtE,wBAAgB,UAAU,IAAI,IAAI,CAYjC;AAcD,wBAAgB,YAAY,IAAI,MAAM,CAsCrC;AAED,wBAAgB,SAAS,IAAI,IAAI,CAoDhC;AAwED,wBAAgB,cAAc,IAAI,IAAI,CAwBrC;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CA8EzC;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAgM7C;AAID,wBAAgB,QAAQ,CAAC,OAAO,UAAO,GAAG;IACzC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,YAAY,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClE,cAAc,EAAE,MAAM,IAAI,CAAC;CAC3B,CAqpBA;AAYD,qBAAa,UAAU;IACtB,MAAM,EAAE,OAAO,CAAC;;IAKhB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM;IAI7C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CA+BrC;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,YAAY,CAAC;AACjD;;;;;;;GAOG;AACH,qBAAa,YAAY;IAOhB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,YAAY,EAAE;IAPhC,GAAG,SAAK;IACR,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAsB;IACjD,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IACvB,MAAM,CAAC,QAAQ,aAAoB;gBAG3B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,YAAY,EAAE;IAGhC,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI;IA2C/D,MAAM,CAAC,gBAAgB,IAAI,YAAY;IAKvC,MAAM,CAAC,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY,EAAE;IAuB9D,MAAM,CAAC,iBAAiB,IAAI,YAAY;IAOxC,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY;IAUxD,MAAM,CAAC,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,YAAY;CAGxD"}
@@ -43,9 +43,11 @@ function LinearDictionary(compareKeys) {
43
43
  if (props.length > 0) {
44
44
  return;
45
45
  }
46
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
46
47
  if (_start === undefined) {
47
48
  _start = min().key;
48
49
  }
50
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- using ??= could change behavior if value is falsy
49
51
  if (_end === undefined) {
50
52
  _end = max().key;
51
53
  }