@fluidframework/merge-tree 0.58.2000 → 0.58.3000-61081

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 (59) hide show
  1. package/dist/client.d.ts.map +1 -1
  2. package/dist/client.js +2 -0
  3. package/dist/client.js.map +1 -1
  4. package/dist/collections.d.ts.map +1 -1
  5. package/dist/collections.js +1 -0
  6. package/dist/collections.js.map +1 -1
  7. package/dist/localReference.d.ts.map +1 -1
  8. package/dist/localReference.js +7 -0
  9. package/dist/localReference.js.map +1 -1
  10. package/dist/mergeTree.d.ts +0 -1
  11. package/dist/mergeTree.d.ts.map +1 -1
  12. package/dist/mergeTree.js +1 -11
  13. package/dist/mergeTree.js.map +1 -1
  14. package/dist/partialLengths.d.ts.map +1 -1
  15. package/dist/partialLengths.js +2 -0
  16. package/dist/partialLengths.js.map +1 -1
  17. package/dist/snapshotChunks.d.ts +4 -0
  18. package/dist/snapshotChunks.d.ts.map +1 -1
  19. package/dist/snapshotChunks.js.map +1 -1
  20. package/dist/snapshotLoader.d.ts.map +1 -1
  21. package/dist/snapshotLoader.js +10 -0
  22. package/dist/snapshotLoader.js.map +1 -1
  23. package/dist/snapshotV1.d.ts.map +1 -1
  24. package/dist/snapshotV1.js +7 -0
  25. package/dist/snapshotV1.js.map +1 -1
  26. package/lib/client.d.ts.map +1 -1
  27. package/lib/client.js +2 -0
  28. package/lib/client.js.map +1 -1
  29. package/lib/collections.d.ts.map +1 -1
  30. package/lib/collections.js +1 -0
  31. package/lib/collections.js.map +1 -1
  32. package/lib/localReference.d.ts.map +1 -1
  33. package/lib/localReference.js +7 -0
  34. package/lib/localReference.js.map +1 -1
  35. package/lib/mergeTree.d.ts +0 -1
  36. package/lib/mergeTree.d.ts.map +1 -1
  37. package/lib/mergeTree.js +1 -11
  38. package/lib/mergeTree.js.map +1 -1
  39. package/lib/partialLengths.d.ts.map +1 -1
  40. package/lib/partialLengths.js +2 -0
  41. package/lib/partialLengths.js.map +1 -1
  42. package/lib/snapshotChunks.d.ts +4 -0
  43. package/lib/snapshotChunks.d.ts.map +1 -1
  44. package/lib/snapshotChunks.js.map +1 -1
  45. package/lib/snapshotLoader.d.ts.map +1 -1
  46. package/lib/snapshotLoader.js +10 -0
  47. package/lib/snapshotLoader.js.map +1 -1
  48. package/lib/snapshotV1.d.ts.map +1 -1
  49. package/lib/snapshotV1.js +7 -0
  50. package/lib/snapshotV1.js.map +1 -1
  51. package/package.json +16 -10
  52. package/src/client.ts +2 -0
  53. package/src/collections.ts +2 -0
  54. package/src/localReference.ts +7 -0
  55. package/src/mergeTree.ts +1 -10
  56. package/src/partialLengths.ts +2 -0
  57. package/src/snapshotChunks.ts +4 -0
  58. package/src/snapshotLoader.ts +11 -0
  59. package/src/snapshotV1.ts +9 -0
@@ -1 +1 @@
1
- {"version":3,"file":"partialLengths.d.ts","sourceRoot":"","sources":["../src/partialLengths.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EACH,mBAAmB,EAEnB,WAAW,EAGX,SAAS,EACZ,MAAM,aAAa,CAAC;AAErB,UAAU,cAAc;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAClB;AA2BD,MAAM,WAAW,qBAAqB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC/D;AAED;;;;GAIG;AACH,qBAAa,sBAAsB;IAwUZ,MAAM,EAAE,MAAM;IAvUjC,OAAc,OAAO;;;MAGnB;WAEY,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,KAAK,UAAQ;IAIhH;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAqI5B,OAAO,CAAC,MAAM,CAAC,UAAU;IAsDzB,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAQhC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAmB5C,OAAO,CAAC,MAAM,CAAC,aAAa;IA4D5B,OAAO,CAAC,MAAM,CAAC,MAAM;IAiCd,SAAS,SAAK;IACd,YAAY,SAAK;IACjB,cAAc,EAAE,qBAAqB,EAAE,CAAM;IAC7C,gBAAgB,EAAE,qBAAqB,EAAE,EAAE,CAAM;gBAErC,MAAM,EAAE,MAAM;IAM1B,MAAM,CACT,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,mBAAmB;IAkD9B,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAgCjD,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,EAAE,WAAW,SAAI;IA2B7D,OAAO,CAAC,OAAO;IA8Bf,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,6BAA6B;IAWrC,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,oBAAoB;IAqD5B,OAAO,CAAC,MAAM;CAqBjB"}
1
+ {"version":3,"file":"partialLengths.d.ts","sourceRoot":"","sources":["../src/partialLengths.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,EACH,mBAAmB,EAEnB,WAAW,EAGX,SAAS,EACZ,MAAM,aAAa,CAAC;AAErB,UAAU,cAAc;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAClB;AA2BD,MAAM,WAAW,qBAAqB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC/D;AAED;;;;GAIG;AACH,qBAAa,sBAAsB;IA0UZ,MAAM,EAAE,MAAM;IAzUjC,OAAc,OAAO;;;MAGnB;WAEY,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,KAAK,UAAQ;IAIhH;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAqI5B,OAAO,CAAC,MAAM,CAAC,UAAU;IAsDzB,OAAO,CAAC,MAAM,CAAC,iBAAiB;IAQhC,OAAO,CAAC,MAAM,CAAC,6BAA6B;IAmB5C,OAAO,CAAC,MAAM,CAAC,aAAa;IA4D5B,OAAO,CAAC,MAAM,CAAC,MAAM;IAmCd,SAAS,SAAK;IACd,YAAY,SAAK;IACjB,cAAc,EAAE,qBAAqB,EAAE,CAAM;IAC7C,gBAAgB,EAAE,qBAAqB,EAAE,EAAE,CAAM;gBAErC,MAAM,EAAE,MAAM;IAM1B,MAAM,CACT,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,mBAAmB;IAkD9B,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;IAgCjD,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,EAAE,WAAW,SAAI;IA2B7D,OAAO,CAAC,OAAO;IA8Bf,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,6BAA6B;IAWrC,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,oBAAoB;IAqD5B,OAAO,CAAC,MAAM;CAqBjB"}
@@ -320,6 +320,8 @@ export class PartialSequenceLengths {
320
320
  }
321
321
  }
322
322
  if (seqPartialLen === undefined) {
323
+ // len will be assigned below, making this assertion true.
324
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
323
325
  seqPartialLen = {
324
326
  clientId,
325
327
  seglen: seqSeglen,
@@ -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/common-utils\";\nimport { Property } from \"./base\";\nimport { RedBlackTree } from \"./collections\";\nimport { UnassignedSequenceNumber } from \"./constants\";\nimport {\n CollaborationWindow,\n compareNumbers,\n IMergeBlock,\n IRemovalInfo,\n ISegment,\n MergeTree,\n} from \"./mergeTree\";\n\ninterface IOverlapClient {\n clientId: number;\n seglen: number;\n}\n\n/**\n * Returns the partial length whose sequence number is\n * the greatest sequence number within a that is\n * less than or equal to key.\n * @param a - array of partial segment lengths\n * @param key - sequence number\n */\nfunction latestLEQ(a: PartialSequenceLength[], key: number) {\n let best = -1;\n let lo = 0;\n let hi = a.length - 1;\n while (lo <= hi) {\n const mid = lo + Math.floor((hi - lo) / 2);\n if (a[mid].seq <= key) {\n if ((best < 0) || (a[best].seq < a[mid].seq)) {\n best = mid;\n }\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n return best;\n}\n\nexport interface PartialSequenceLength {\n seq: number;\n len: number;\n seglen: number;\n clientId?: number;\n overlapRemoveClients?: RedBlackTree<number, IOverlapClient>;\n}\n\n/**\n * Keep track of partial sums of segment lengths for all sequence numbers\n * in the current collaboration window (if any). Only used during active\n * collaboration.\n */\nexport class PartialSequenceLengths {\n public static options = {\n verify: false,\n zamboni: true,\n };\n\n public static combine(mergeTree: MergeTree, block: IMergeBlock, collabWindow: CollaborationWindow, recur = false) {\n return PartialSequenceLengths.combineBranch(mergeTree, block, collabWindow, recur);\n }\n\n /**\n * Combine the partial lengths of block's children\n * @param block - an interior node; it is assumed that each interior node child of this block\n * has its partials up to date\n * @param collabWindow - segment window of the segment tree containing textSegmentBlock\n */\n private static combineBranch(\n mergeTree: MergeTree,\n block: IMergeBlock,\n collabWindow: CollaborationWindow,\n recur = false) {\n let combinedPartialLengths = new PartialSequenceLengths(collabWindow.minSeq);\n PartialSequenceLengths.fromLeaves(mergeTree, combinedPartialLengths, block, collabWindow);\n let prevPartial: PartialSequenceLength | undefined;\n\n function cloneOverlapRemoveClients(oldTree: RedBlackTree<number, IOverlapClient> | undefined) {\n if (!oldTree) { return undefined; }\n const newTree = new RedBlackTree<number, IOverlapClient>(compareNumbers);\n oldTree.map((bProp: Property<number, IOverlapClient>) => {\n newTree.put(bProp.data.clientId, { ...bProp.data });\n return true;\n });\n return newTree;\n }\n\n function combineOverlapClients(a: PartialSequenceLength, b: PartialSequenceLength) {\n const overlapRemoveClientsA = a.overlapRemoveClients;\n if (overlapRemoveClientsA) {\n if (b.overlapRemoveClients) {\n b.overlapRemoveClients.map((bProp: Property<number, IOverlapClient>) => {\n const aProp = overlapRemoveClientsA.get(bProp.key);\n if (aProp) {\n aProp.data.seglen += bProp.data.seglen;\n } else {\n overlapRemoveClientsA.put(bProp.data.clientId, { ...bProp.data });\n }\n return true;\n });\n }\n } else {\n a.overlapRemoveClients = cloneOverlapRemoveClients(b.overlapRemoveClients);\n }\n }\n\n function addNext(partialLength: PartialSequenceLength) {\n const seq = partialLength.seq;\n let pLen = 0;\n\n if (prevPartial) {\n if (prevPartial.seq === partialLength.seq) {\n prevPartial.seglen += partialLength.seglen;\n prevPartial.len += partialLength.seglen;\n combineOverlapClients(prevPartial, partialLength);\n return;\n } else {\n pLen = prevPartial.len;\n // Previous sequence number is finished\n combinedPartialLengths.addClientSeqNumberFromPartial(prevPartial);\n }\n }\n prevPartial = {\n clientId: partialLength.clientId,\n len: pLen + partialLength.seglen,\n overlapRemoveClients: cloneOverlapRemoveClients(partialLength.overlapRemoveClients),\n seglen: partialLength.seglen,\n seq,\n };\n combinedPartialLengths.partialLengths.push(prevPartial);\n }\n\n const childPartials: PartialSequenceLengths[] = [];\n for (let i = 0; i < block.childCount; i++) {\n const child = block.children[i];\n if (!child.isLeaf()) {\n const childBlock = child;\n if (recur) {\n childBlock.partialLengths =\n PartialSequenceLengths.combine(mergeTree, childBlock, collabWindow, true);\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n childPartials.push(childBlock.partialLengths!);\n }\n }\n let childPartialsLen = childPartials.length;\n if (childPartialsLen !== 0) {\n // Some children are interior nodes\n if (combinedPartialLengths.partialLengths.length > 0) {\n // Some children were leaves; add combined partials from these segments\n childPartials.push(combinedPartialLengths);\n childPartialsLen++;\n combinedPartialLengths = new PartialSequenceLengths(collabWindow.minSeq);\n }\n const indices = new Array<number>(childPartialsLen);\n const childPartialsCounts = new Array<number>(childPartialsLen);\n for (let i = 0; i < childPartialsLen; i++) {\n indices[i] = 0;\n childPartialsCounts[i] = childPartials[i].partialLengths.length;\n combinedPartialLengths.minLength += childPartials[i].minLength;\n combinedPartialLengths.segmentCount += childPartials[i].segmentCount;\n }\n let outerIndexOfEarliest = 0;\n let earliestPartialLength: PartialSequenceLength;\n while (outerIndexOfEarliest >= 0) {\n outerIndexOfEarliest = -1;\n for (let k = 0; k < childPartialsLen; k++) {\n // Find next earliest sequence number\n if (indices[k] < childPartialsCounts[k]) {\n const cpLen = childPartials[k].partialLengths[indices[k]];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if ((outerIndexOfEarliest < 0) || (cpLen.seq < earliestPartialLength!.seq)) {\n outerIndexOfEarliest = k;\n earliestPartialLength = cpLen;\n }\n }\n }\n if (outerIndexOfEarliest >= 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n addNext(earliestPartialLength!);\n indices[outerIndexOfEarliest]++;\n }\n }\n // Add client entry for last partial, if any\n if (prevPartial) {\n combinedPartialLengths.addClientSeqNumberFromPartial(prevPartial);\n }\n }\n // TODO: incremental zamboni during build\n if (PartialSequenceLengths.options.zamboni) {\n combinedPartialLengths.zamboni(collabWindow);\n }\n\n if (PartialSequenceLengths.options.verify) {\n combinedPartialLengths.verify();\n }\n\n return combinedPartialLengths;\n }\n\n private static fromLeaves(\n mergeTree: MergeTree, combinedPartialLengths: PartialSequenceLengths,\n block: IMergeBlock, collabWindow: CollaborationWindow) {\n combinedPartialLengths.minLength = 0;\n combinedPartialLengths.segmentCount = block.childCount;\n\n function seqLTE(seq: number, minSeq: number) {\n return (seq !== UnassignedSequenceNumber) && (seq <= minSeq);\n }\n\n for (let i = 0; i < block.childCount; i++) {\n const child = block.children[i];\n if (child.isLeaf()) {\n // Leaf segment\n const segment = child;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (seqLTE(segment.seq!, collabWindow.minSeq)) {\n combinedPartialLengths.minLength += segment.cachedLength;\n } else {\n if (segment.seq !== UnassignedSequenceNumber) {\n PartialSequenceLengths.insertSegment(combinedPartialLengths, segment);\n }\n }\n const removalInfo: IRemovalInfo = segment;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (seqLTE(removalInfo.removedSeq!, collabWindow.minSeq)) {\n combinedPartialLengths.minLength -= segment.cachedLength;\n } else {\n if ((removalInfo.removedSeq !== undefined) &&\n (removalInfo.removedSeq !== UnassignedSequenceNumber)) {\n PartialSequenceLengths.insertSegment(\n combinedPartialLengths,\n segment,\n removalInfo);\n }\n }\n }\n }\n // Post-process correctly-ordered partials computing sums and creating\n // lists for each present client id\n const seqPartials = combinedPartialLengths.partialLengths;\n const seqPartialsLen = seqPartials.length;\n\n let prevLen = 0;\n for (let i = 0; i < seqPartialsLen; i++) {\n seqPartials[i].len = prevLen + seqPartials[i].seglen;\n prevLen = seqPartials[i].len;\n combinedPartialLengths.addClientSeqNumberFromPartial(seqPartials[i]);\n }\n if (PartialSequenceLengths.options.verify) {\n combinedPartialLengths.verify();\n }\n }\n\n private static getOverlapClients(overlapClientIds: number[], seglen: number) {\n const bst = new RedBlackTree<number, IOverlapClient>(compareNumbers);\n for (const clientId of overlapClientIds) {\n bst.put(clientId, { clientId, seglen });\n }\n return bst;\n }\n\n private static accumulateRemoveClientOverlap(\n partialLength: PartialSequenceLength,\n overlapRemoveClientIds: number[],\n seglen: number) {\n if (partialLength.overlapRemoveClients) {\n for (const clientId of overlapRemoveClientIds) {\n const overlapClientNode = partialLength.overlapRemoveClients.get(clientId);\n if (!overlapClientNode) {\n partialLength.overlapRemoveClients.put(clientId, { clientId, seglen });\n } else {\n overlapClientNode.data.seglen += seglen;\n }\n }\n } else {\n partialLength.overlapRemoveClients =\n PartialSequenceLengths.getOverlapClients(overlapRemoveClientIds, seglen);\n }\n }\n\n private static insertSegment(\n combinedPartialLengths: PartialSequenceLengths,\n segment: ISegment,\n removalInfo?: IRemovalInfo) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n let seq = segment.seq!;\n let segmentLen = segment.cachedLength;\n let clientId = segment.clientId;\n let removeClientOverlap: number[] | undefined;\n\n if (removalInfo) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n seq = removalInfo.removedSeq!;\n segmentLen = -segmentLen;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n clientId = removalInfo.removedClientId!;\n if (removalInfo.removedClientOverlap) {\n removeClientOverlap = removalInfo.removedClientOverlap;\n }\n }\n\n const seqPartials = combinedPartialLengths.partialLengths;\n const seqPartialsLen = seqPartials.length;\n // Find the first entry with sequence number greater or equal to seq\n let indexFirstGTE = 0;\n for (; indexFirstGTE < seqPartialsLen; indexFirstGTE++) {\n if (seqPartials[indexFirstGTE].seq >= seq) {\n break;\n }\n }\n if ((indexFirstGTE < seqPartialsLen) && (seqPartials[indexFirstGTE].seq === seq)) {\n seqPartials[indexFirstGTE].seglen += segmentLen;\n if (removeClientOverlap) {\n PartialSequenceLengths.accumulateRemoveClientOverlap(\n seqPartials[indexFirstGTE],\n removeClientOverlap,\n segmentLen);\n }\n } else {\n let pLen: PartialSequenceLength;\n if (removeClientOverlap) {\n const overlapClients = PartialSequenceLengths.getOverlapClients(removeClientOverlap, segmentLen);\n pLen = { seq, clientId, len: 0, seglen: segmentLen, overlapRemoveClients: overlapClients };\n } else {\n pLen = { seq, clientId, len: 0, seglen: segmentLen };\n }\n\n if (indexFirstGTE < seqPartialsLen) {\n // Shift entries with greater sequence numbers\n // TODO: investigate performance improvement using BST\n for (let k = seqPartialsLen; k > indexFirstGTE; k--) {\n seqPartials[k] = seqPartials[k - 1];\n }\n seqPartials[indexFirstGTE] = pLen;\n } else {\n seqPartials.push(pLen);\n }\n }\n }\n\n private static addSeq(partialLengths: PartialSequenceLength[], seq: number, seqSeglen: number, clientId?: number) {\n let seqPartialLen: PartialSequenceLength | undefined;\n let penultPartialLen: PartialSequenceLength | undefined;\n let leqIndex = latestLEQ(partialLengths, seq);\n if (leqIndex >= 0) {\n const pLen = partialLengths[leqIndex];\n if (pLen.seq === seq) {\n seqPartialLen = pLen;\n leqIndex = latestLEQ(partialLengths, seq - 1);\n if (leqIndex >= 0) {\n penultPartialLen = partialLengths[leqIndex];\n }\n } else {\n penultPartialLen = pLen;\n }\n }\n if (seqPartialLen === undefined) {\n seqPartialLen = {\n clientId,\n seglen: seqSeglen,\n seq,\n } as PartialSequenceLength;\n partialLengths.push(seqPartialLen);\n } else {\n seqPartialLen.seglen = seqSeglen;\n // Assert client id matches\n }\n if (penultPartialLen !== undefined) {\n seqPartialLen.len = seqPartialLen.seglen + penultPartialLen.len;\n } else {\n seqPartialLen.len = seqPartialLen.seglen;\n }\n }\n public minLength = 0;\n public segmentCount = 0;\n public partialLengths: PartialSequenceLength[] = [];\n public clientSeqNumbers: PartialSequenceLength[][] = [];\n\n constructor(public minSeq: number) {\n }\n\n // Assume: seq is latest sequence number; no structural change to sub-tree, but a segment\n // with sequence number seq has been added within the sub-tree\n // TODO: assert client id matches\n public update(\n mergeTree: MergeTree,\n node: IMergeBlock,\n seq: number,\n clientId: number,\n collabWindow: CollaborationWindow) {\n let seqSeglen = 0;\n let segCount = 0;\n // Compute length for seq across children\n for (let i = 0; i < node.childCount; i++) {\n const child = node.children[i];\n if (!child.isLeaf()) {\n const childBlock = child;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const branchPartialLengths = childBlock.partialLengths!;\n const partialLengths = branchPartialLengths.partialLengths;\n const seqIndex = latestLEQ(partialLengths, seq);\n if (seqIndex >= 0) {\n const leqPartial = partialLengths[seqIndex];\n if (leqPartial.seq === seq) {\n seqSeglen += leqPartial.seglen;\n }\n }\n segCount += branchPartialLengths.segmentCount;\n } else {\n const segment = child;\n const removalInfo: IRemovalInfo = segment;\n\n if (segment.seq === seq) {\n if (removalInfo.removedSeq !== seq) {\n seqSeglen += segment.cachedLength;\n }\n } else {\n if (removalInfo.removedSeq === seq) {\n seqSeglen -= segment.cachedLength;\n }\n }\n segCount++;\n }\n }\n this.segmentCount = segCount;\n\n PartialSequenceLengths.addSeq(this.partialLengths, seq, seqSeglen, clientId);\n if (this.clientSeqNumbers[clientId] === undefined) {\n this.clientSeqNumbers[clientId] = [];\n }\n PartialSequenceLengths.addSeq(this.clientSeqNumbers[clientId], seq, seqSeglen);\n if (PartialSequenceLengths.options.zamboni) {\n this.zamboni(collabWindow);\n }\n if (PartialSequenceLengths.options.verify) {\n this.verify();\n }\n }\n\n public getPartialLength(refSeq: number, clientId: number) {\n let pLen = this.minLength;\n const seqIndex = latestLEQ(this.partialLengths, refSeq);\n const cliLatestIndex = this.cliLatest(clientId);\n const cliSeq = this.clientSeqNumbers[clientId];\n if (seqIndex >= 0) {\n // Add the partial length up to refSeq\n pLen += this.partialLengths[seqIndex].len;\n\n if (cliLatestIndex >= 0) {\n const cliLatest = cliSeq[cliLatestIndex];\n\n if (cliLatest.seq > refSeq) {\n // The client has local edits after refSeq, add in the length adjustments\n pLen += cliLatest.len;\n const precedingCliIndex = this.cliLatestLEQ(clientId, refSeq);\n if (precedingCliIndex >= 0) {\n pLen -= cliSeq[precedingCliIndex].len;\n }\n }\n }\n } else {\n // RefSeq is before any of the partial lengths\n // so just add in all local edits of that client (which should all be after the refSeq)\n if (cliLatestIndex >= 0) {\n const cliLatest = cliSeq[cliLatestIndex];\n pLen += cliLatest.len;\n }\n }\n return pLen;\n }\n\n public toString(glc?: (id: number) => string, indentCount = 0) {\n let buf = \"\";\n for (const partial of this.partialLengths) {\n buf += `(${partial.seq},${partial.len}) `;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-for-in-array, no-restricted-syntax\n for (const clientId in this.clientSeqNumbers) {\n if (this.clientSeqNumbers[clientId].length > 0) {\n buf += `Client `;\n if (glc) {\n buf += `${glc(+clientId)}`;\n } else {\n buf += `${clientId}`;\n }\n buf += \"[\";\n for (const partial of this.clientSeqNumbers[clientId]) {\n buf += `(${partial.seq},${partial.len})`;\n }\n buf += \"]\";\n }\n }\n buf = `min(seq ${this.minSeq}): ${this.minLength}; sc: ${this.segmentCount};${buf}`;\n return buf;\n }\n\n // Clear away partial sums for sequence numbers earlier than the current window\n private zamboni(segmentWindow: CollaborationWindow) {\n function copyDown(partialLengths: PartialSequenceLength[]) {\n const mindex = latestLEQ(partialLengths, segmentWindow.minSeq);\n let minLength = 0;\n if (mindex >= 0) {\n minLength = partialLengths[mindex].len;\n const seqCount = partialLengths.length;\n if (mindex <= (seqCount - 1)) {\n // Still some entries remaining\n const remainingCount = (seqCount - mindex) - 1;\n // Copy down\n for (let i = 0; i < remainingCount; i++) {\n partialLengths[i] = partialLengths[i + mindex + 1];\n partialLengths[i].len -= minLength;\n }\n partialLengths.length = remainingCount;\n }\n }\n return minLength;\n }\n this.minLength += copyDown(this.partialLengths);\n // eslint-disable-next-line @typescript-eslint/no-for-in-array, guard-for-in, no-restricted-syntax\n for (const clientId in this.clientSeqNumbers) {\n const cliPartials = this.clientSeqNumbers[clientId];\n if (cliPartials) {\n copyDown(cliPartials);\n }\n }\n }\n\n private addClientSeqNumber(clientId: number, seq: number, seglen: number) {\n if (this.clientSeqNumbers[clientId] === undefined) {\n this.clientSeqNumbers[clientId] = [];\n }\n const cli = this.clientSeqNumbers[clientId];\n let pLen = seglen;\n if (cli.length > 0) {\n pLen += cli[cli.length - 1].len;\n }\n cli.push({ seq, len: pLen, seglen });\n }\n\n // Assumes sequence number already coalesced\n private addClientSeqNumberFromPartial(partialLength: PartialSequenceLength) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.addClientSeqNumber(partialLength.clientId!, partialLength.seq, partialLength.seglen);\n if (partialLength.overlapRemoveClients) {\n partialLength.overlapRemoveClients.map((oc: Property<number, IOverlapClient>) => {\n this.addClientSeqNumber(oc.data.clientId, partialLength.seq, oc.data.seglen);\n return true;\n });\n }\n }\n\n private cliLatestLEQ(clientId: number, refSeq: number) {\n const cliSeqs = this.clientSeqNumbers[clientId];\n if (cliSeqs) {\n return latestLEQ(cliSeqs, refSeq);\n } else {\n return -1;\n }\n }\n\n private cliLatest(clientId: number) {\n const cliSeqs = this.clientSeqNumbers[clientId];\n if (cliSeqs && (cliSeqs.length > 0)) {\n return cliSeqs.length - 1;\n } else {\n return -1;\n }\n }\n\n // Debug only\n private verifyPartialLengths(partialLengths: PartialSequenceLength[], clientPartials: boolean) {\n if (partialLengths.length === 0) { return 0; }\n\n let lastSeqNum = 0;\n let accumSegLen = 0;\n let count = 0;\n\n for (const partialLength of partialLengths) {\n // Count total number of partial length\n count++;\n\n // Sequence number should be larger or equal to minseq\n assert(this.minSeq <= partialLength.seq, 0x054 /* \"Sequence number less than minSeq!\" */);\n\n // Sequence number should be sorted\n assert(lastSeqNum < partialLength.seq, 0x055 /* \"Sequence number is not sorted!\" */);\n lastSeqNum = partialLength.seq;\n\n // Len is a accumulation of all the seglen adjustments\n accumSegLen += partialLength.seglen;\n if (accumSegLen !== partialLength.len) {\n assert(false, 0x056 /* \"Unexpected total for accumulation of all seglen adjustments!\" */);\n }\n\n if (clientPartials) {\n // Client partials used to track local edits so we can account for them some refSeq.\n // But the information we keep track of are since minSeq, so we keep track of more history\n // then needed, and some of them doesn't make sense to be used for length calculations\n // e.g. if you have this sequence, where the minSeq is #5 because of other clients\n // seq 10: client 1: insert seg #1\n // seq 11: client 2: delete seg #2 refseq: 10\n // minLength is 0, we would have keep a record of seglen: -1 for clientPartialLengths for client 2\n // So if you ask for partial length for client 2 @ seq 5, we will have return -1.\n // However, that combination is invalid, since we should never see any ops with refseq < 10 for\n // client 2 after seq 11.\n } else {\n // Len adjustment should not make length negative\n if (this.minLength + partialLength.len < 0) {\n assert(false, 0x057 /* \"Negative length after length adjustment!\" */);\n }\n }\n\n if (partialLength.overlapRemoveClients) {\n // Only the flat partialLengths can have overlapRemoveClients, the per client view shouldn't\n assert(!clientPartials, 0x058 /* \"Both overlapRemoveClients and clientPartials are set!\" */);\n\n // Each overlap client count as one\n count += partialLength.overlapRemoveClients.size();\n }\n }\n return count;\n }\n\n private verify() {\n if (this.clientSeqNumbers) {\n let cliCount = 0;\n for (const cliSeq of this.clientSeqNumbers) {\n if (cliSeq) {\n cliCount += this.verifyPartialLengths(cliSeq, true);\n }\n }\n\n // If we have client view, we should have the flat view\n assert(!!this.partialLengths, 0x059 /* \"Client view exists but flat view does not!\" */);\n const flatCount = this.verifyPartialLengths(this.partialLengths, false);\n\n // The number of partial lengths on the client view and flat view should be the same\n assert(flatCount === cliCount,\n 0x05a /* \"Mismatch between number of partial lengths on client and flat views!\" */);\n } else {\n // If we don't have a client view, we shouldn't have the flat view either\n assert(!this.partialLengths, 0x05b /* \"Flat view exists but client view does not!\" */);\n }\n }\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/common-utils\";\nimport { Property } from \"./base\";\nimport { RedBlackTree } from \"./collections\";\nimport { UnassignedSequenceNumber } from \"./constants\";\nimport {\n CollaborationWindow,\n compareNumbers,\n IMergeBlock,\n IRemovalInfo,\n ISegment,\n MergeTree,\n} from \"./mergeTree\";\n\ninterface IOverlapClient {\n clientId: number;\n seglen: number;\n}\n\n/**\n * Returns the partial length whose sequence number is\n * the greatest sequence number within a that is\n * less than or equal to key.\n * @param a - array of partial segment lengths\n * @param key - sequence number\n */\nfunction latestLEQ(a: PartialSequenceLength[], key: number) {\n let best = -1;\n let lo = 0;\n let hi = a.length - 1;\n while (lo <= hi) {\n const mid = lo + Math.floor((hi - lo) / 2);\n if (a[mid].seq <= key) {\n if ((best < 0) || (a[best].seq < a[mid].seq)) {\n best = mid;\n }\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n return best;\n}\n\nexport interface PartialSequenceLength {\n seq: number;\n len: number;\n seglen: number;\n clientId?: number;\n overlapRemoveClients?: RedBlackTree<number, IOverlapClient>;\n}\n\n/**\n * Keep track of partial sums of segment lengths for all sequence numbers\n * in the current collaboration window (if any). Only used during active\n * collaboration.\n */\nexport class PartialSequenceLengths {\n public static options = {\n verify: false,\n zamboni: true,\n };\n\n public static combine(mergeTree: MergeTree, block: IMergeBlock, collabWindow: CollaborationWindow, recur = false) {\n return PartialSequenceLengths.combineBranch(mergeTree, block, collabWindow, recur);\n }\n\n /**\n * Combine the partial lengths of block's children\n * @param block - an interior node; it is assumed that each interior node child of this block\n * has its partials up to date\n * @param collabWindow - segment window of the segment tree containing textSegmentBlock\n */\n private static combineBranch(\n mergeTree: MergeTree,\n block: IMergeBlock,\n collabWindow: CollaborationWindow,\n recur = false) {\n let combinedPartialLengths = new PartialSequenceLengths(collabWindow.minSeq);\n PartialSequenceLengths.fromLeaves(mergeTree, combinedPartialLengths, block, collabWindow);\n let prevPartial: PartialSequenceLength | undefined;\n\n function cloneOverlapRemoveClients(oldTree: RedBlackTree<number, IOverlapClient> | undefined) {\n if (!oldTree) { return undefined; }\n const newTree = new RedBlackTree<number, IOverlapClient>(compareNumbers);\n oldTree.map((bProp: Property<number, IOverlapClient>) => {\n newTree.put(bProp.data.clientId, { ...bProp.data });\n return true;\n });\n return newTree;\n }\n\n function combineOverlapClients(a: PartialSequenceLength, b: PartialSequenceLength) {\n const overlapRemoveClientsA = a.overlapRemoveClients;\n if (overlapRemoveClientsA) {\n if (b.overlapRemoveClients) {\n b.overlapRemoveClients.map((bProp: Property<number, IOverlapClient>) => {\n const aProp = overlapRemoveClientsA.get(bProp.key);\n if (aProp) {\n aProp.data.seglen += bProp.data.seglen;\n } else {\n overlapRemoveClientsA.put(bProp.data.clientId, { ...bProp.data });\n }\n return true;\n });\n }\n } else {\n a.overlapRemoveClients = cloneOverlapRemoveClients(b.overlapRemoveClients);\n }\n }\n\n function addNext(partialLength: PartialSequenceLength) {\n const seq = partialLength.seq;\n let pLen = 0;\n\n if (prevPartial) {\n if (prevPartial.seq === partialLength.seq) {\n prevPartial.seglen += partialLength.seglen;\n prevPartial.len += partialLength.seglen;\n combineOverlapClients(prevPartial, partialLength);\n return;\n } else {\n pLen = prevPartial.len;\n // Previous sequence number is finished\n combinedPartialLengths.addClientSeqNumberFromPartial(prevPartial);\n }\n }\n prevPartial = {\n clientId: partialLength.clientId,\n len: pLen + partialLength.seglen,\n overlapRemoveClients: cloneOverlapRemoveClients(partialLength.overlapRemoveClients),\n seglen: partialLength.seglen,\n seq,\n };\n combinedPartialLengths.partialLengths.push(prevPartial);\n }\n\n const childPartials: PartialSequenceLengths[] = [];\n for (let i = 0; i < block.childCount; i++) {\n const child = block.children[i];\n if (!child.isLeaf()) {\n const childBlock = child;\n if (recur) {\n childBlock.partialLengths =\n PartialSequenceLengths.combine(mergeTree, childBlock, collabWindow, true);\n }\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n childPartials.push(childBlock.partialLengths!);\n }\n }\n let childPartialsLen = childPartials.length;\n if (childPartialsLen !== 0) {\n // Some children are interior nodes\n if (combinedPartialLengths.partialLengths.length > 0) {\n // Some children were leaves; add combined partials from these segments\n childPartials.push(combinedPartialLengths);\n childPartialsLen++;\n combinedPartialLengths = new PartialSequenceLengths(collabWindow.minSeq);\n }\n const indices = new Array<number>(childPartialsLen);\n const childPartialsCounts = new Array<number>(childPartialsLen);\n for (let i = 0; i < childPartialsLen; i++) {\n indices[i] = 0;\n childPartialsCounts[i] = childPartials[i].partialLengths.length;\n combinedPartialLengths.minLength += childPartials[i].minLength;\n combinedPartialLengths.segmentCount += childPartials[i].segmentCount;\n }\n let outerIndexOfEarliest = 0;\n let earliestPartialLength: PartialSequenceLength;\n while (outerIndexOfEarliest >= 0) {\n outerIndexOfEarliest = -1;\n for (let k = 0; k < childPartialsLen; k++) {\n // Find next earliest sequence number\n if (indices[k] < childPartialsCounts[k]) {\n const cpLen = childPartials[k].partialLengths[indices[k]];\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if ((outerIndexOfEarliest < 0) || (cpLen.seq < earliestPartialLength!.seq)) {\n outerIndexOfEarliest = k;\n earliestPartialLength = cpLen;\n }\n }\n }\n if (outerIndexOfEarliest >= 0) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n addNext(earliestPartialLength!);\n indices[outerIndexOfEarliest]++;\n }\n }\n // Add client entry for last partial, if any\n if (prevPartial) {\n combinedPartialLengths.addClientSeqNumberFromPartial(prevPartial);\n }\n }\n // TODO: incremental zamboni during build\n if (PartialSequenceLengths.options.zamboni) {\n combinedPartialLengths.zamboni(collabWindow);\n }\n\n if (PartialSequenceLengths.options.verify) {\n combinedPartialLengths.verify();\n }\n\n return combinedPartialLengths;\n }\n\n private static fromLeaves(\n mergeTree: MergeTree, combinedPartialLengths: PartialSequenceLengths,\n block: IMergeBlock, collabWindow: CollaborationWindow) {\n combinedPartialLengths.minLength = 0;\n combinedPartialLengths.segmentCount = block.childCount;\n\n function seqLTE(seq: number, minSeq: number) {\n return (seq !== UnassignedSequenceNumber) && (seq <= minSeq);\n }\n\n for (let i = 0; i < block.childCount; i++) {\n const child = block.children[i];\n if (child.isLeaf()) {\n // Leaf segment\n const segment = child;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (seqLTE(segment.seq!, collabWindow.minSeq)) {\n combinedPartialLengths.minLength += segment.cachedLength;\n } else {\n if (segment.seq !== UnassignedSequenceNumber) {\n PartialSequenceLengths.insertSegment(combinedPartialLengths, segment);\n }\n }\n const removalInfo: IRemovalInfo = segment;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (seqLTE(removalInfo.removedSeq!, collabWindow.minSeq)) {\n combinedPartialLengths.minLength -= segment.cachedLength;\n } else {\n if ((removalInfo.removedSeq !== undefined) &&\n (removalInfo.removedSeq !== UnassignedSequenceNumber)) {\n PartialSequenceLengths.insertSegment(\n combinedPartialLengths,\n segment,\n removalInfo);\n }\n }\n }\n }\n // Post-process correctly-ordered partials computing sums and creating\n // lists for each present client id\n const seqPartials = combinedPartialLengths.partialLengths;\n const seqPartialsLen = seqPartials.length;\n\n let prevLen = 0;\n for (let i = 0; i < seqPartialsLen; i++) {\n seqPartials[i].len = prevLen + seqPartials[i].seglen;\n prevLen = seqPartials[i].len;\n combinedPartialLengths.addClientSeqNumberFromPartial(seqPartials[i]);\n }\n if (PartialSequenceLengths.options.verify) {\n combinedPartialLengths.verify();\n }\n }\n\n private static getOverlapClients(overlapClientIds: number[], seglen: number) {\n const bst = new RedBlackTree<number, IOverlapClient>(compareNumbers);\n for (const clientId of overlapClientIds) {\n bst.put(clientId, { clientId, seglen });\n }\n return bst;\n }\n\n private static accumulateRemoveClientOverlap(\n partialLength: PartialSequenceLength,\n overlapRemoveClientIds: number[],\n seglen: number) {\n if (partialLength.overlapRemoveClients) {\n for (const clientId of overlapRemoveClientIds) {\n const overlapClientNode = partialLength.overlapRemoveClients.get(clientId);\n if (!overlapClientNode) {\n partialLength.overlapRemoveClients.put(clientId, { clientId, seglen });\n } else {\n overlapClientNode.data.seglen += seglen;\n }\n }\n } else {\n partialLength.overlapRemoveClients =\n PartialSequenceLengths.getOverlapClients(overlapRemoveClientIds, seglen);\n }\n }\n\n private static insertSegment(\n combinedPartialLengths: PartialSequenceLengths,\n segment: ISegment,\n removalInfo?: IRemovalInfo) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n let seq = segment.seq!;\n let segmentLen = segment.cachedLength;\n let clientId = segment.clientId;\n let removeClientOverlap: number[] | undefined;\n\n if (removalInfo) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n seq = removalInfo.removedSeq!;\n segmentLen = -segmentLen;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n clientId = removalInfo.removedClientId!;\n if (removalInfo.removedClientOverlap) {\n removeClientOverlap = removalInfo.removedClientOverlap;\n }\n }\n\n const seqPartials = combinedPartialLengths.partialLengths;\n const seqPartialsLen = seqPartials.length;\n // Find the first entry with sequence number greater or equal to seq\n let indexFirstGTE = 0;\n for (; indexFirstGTE < seqPartialsLen; indexFirstGTE++) {\n if (seqPartials[indexFirstGTE].seq >= seq) {\n break;\n }\n }\n if ((indexFirstGTE < seqPartialsLen) && (seqPartials[indexFirstGTE].seq === seq)) {\n seqPartials[indexFirstGTE].seglen += segmentLen;\n if (removeClientOverlap) {\n PartialSequenceLengths.accumulateRemoveClientOverlap(\n seqPartials[indexFirstGTE],\n removeClientOverlap,\n segmentLen);\n }\n } else {\n let pLen: PartialSequenceLength;\n if (removeClientOverlap) {\n const overlapClients = PartialSequenceLengths.getOverlapClients(removeClientOverlap, segmentLen);\n pLen = { seq, clientId, len: 0, seglen: segmentLen, overlapRemoveClients: overlapClients };\n } else {\n pLen = { seq, clientId, len: 0, seglen: segmentLen };\n }\n\n if (indexFirstGTE < seqPartialsLen) {\n // Shift entries with greater sequence numbers\n // TODO: investigate performance improvement using BST\n for (let k = seqPartialsLen; k > indexFirstGTE; k--) {\n seqPartials[k] = seqPartials[k - 1];\n }\n seqPartials[indexFirstGTE] = pLen;\n } else {\n seqPartials.push(pLen);\n }\n }\n }\n\n private static addSeq(partialLengths: PartialSequenceLength[], seq: number, seqSeglen: number, clientId?: number) {\n let seqPartialLen: PartialSequenceLength | undefined;\n let penultPartialLen: PartialSequenceLength | undefined;\n let leqIndex = latestLEQ(partialLengths, seq);\n if (leqIndex >= 0) {\n const pLen = partialLengths[leqIndex];\n if (pLen.seq === seq) {\n seqPartialLen = pLen;\n leqIndex = latestLEQ(partialLengths, seq - 1);\n if (leqIndex >= 0) {\n penultPartialLen = partialLengths[leqIndex];\n }\n } else {\n penultPartialLen = pLen;\n }\n }\n if (seqPartialLen === undefined) {\n // len will be assigned below, making this assertion true.\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n seqPartialLen = {\n clientId,\n seglen: seqSeglen,\n seq,\n } as PartialSequenceLength;\n partialLengths.push(seqPartialLen);\n } else {\n seqPartialLen.seglen = seqSeglen;\n // Assert client id matches\n }\n if (penultPartialLen !== undefined) {\n seqPartialLen.len = seqPartialLen.seglen + penultPartialLen.len;\n } else {\n seqPartialLen.len = seqPartialLen.seglen;\n }\n }\n public minLength = 0;\n public segmentCount = 0;\n public partialLengths: PartialSequenceLength[] = [];\n public clientSeqNumbers: PartialSequenceLength[][] = [];\n\n constructor(public minSeq: number) {\n }\n\n // Assume: seq is latest sequence number; no structural change to sub-tree, but a segment\n // with sequence number seq has been added within the sub-tree\n // TODO: assert client id matches\n public update(\n mergeTree: MergeTree,\n node: IMergeBlock,\n seq: number,\n clientId: number,\n collabWindow: CollaborationWindow) {\n let seqSeglen = 0;\n let segCount = 0;\n // Compute length for seq across children\n for (let i = 0; i < node.childCount; i++) {\n const child = node.children[i];\n if (!child.isLeaf()) {\n const childBlock = child;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const branchPartialLengths = childBlock.partialLengths!;\n const partialLengths = branchPartialLengths.partialLengths;\n const seqIndex = latestLEQ(partialLengths, seq);\n if (seqIndex >= 0) {\n const leqPartial = partialLengths[seqIndex];\n if (leqPartial.seq === seq) {\n seqSeglen += leqPartial.seglen;\n }\n }\n segCount += branchPartialLengths.segmentCount;\n } else {\n const segment = child;\n const removalInfo: IRemovalInfo = segment;\n\n if (segment.seq === seq) {\n if (removalInfo.removedSeq !== seq) {\n seqSeglen += segment.cachedLength;\n }\n } else {\n if (removalInfo.removedSeq === seq) {\n seqSeglen -= segment.cachedLength;\n }\n }\n segCount++;\n }\n }\n this.segmentCount = segCount;\n\n PartialSequenceLengths.addSeq(this.partialLengths, seq, seqSeglen, clientId);\n if (this.clientSeqNumbers[clientId] === undefined) {\n this.clientSeqNumbers[clientId] = [];\n }\n PartialSequenceLengths.addSeq(this.clientSeqNumbers[clientId], seq, seqSeglen);\n if (PartialSequenceLengths.options.zamboni) {\n this.zamboni(collabWindow);\n }\n if (PartialSequenceLengths.options.verify) {\n this.verify();\n }\n }\n\n public getPartialLength(refSeq: number, clientId: number) {\n let pLen = this.minLength;\n const seqIndex = latestLEQ(this.partialLengths, refSeq);\n const cliLatestIndex = this.cliLatest(clientId);\n const cliSeq = this.clientSeqNumbers[clientId];\n if (seqIndex >= 0) {\n // Add the partial length up to refSeq\n pLen += this.partialLengths[seqIndex].len;\n\n if (cliLatestIndex >= 0) {\n const cliLatest = cliSeq[cliLatestIndex];\n\n if (cliLatest.seq > refSeq) {\n // The client has local edits after refSeq, add in the length adjustments\n pLen += cliLatest.len;\n const precedingCliIndex = this.cliLatestLEQ(clientId, refSeq);\n if (precedingCliIndex >= 0) {\n pLen -= cliSeq[precedingCliIndex].len;\n }\n }\n }\n } else {\n // RefSeq is before any of the partial lengths\n // so just add in all local edits of that client (which should all be after the refSeq)\n if (cliLatestIndex >= 0) {\n const cliLatest = cliSeq[cliLatestIndex];\n pLen += cliLatest.len;\n }\n }\n return pLen;\n }\n\n public toString(glc?: (id: number) => string, indentCount = 0) {\n let buf = \"\";\n for (const partial of this.partialLengths) {\n buf += `(${partial.seq},${partial.len}) `;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-for-in-array, no-restricted-syntax\n for (const clientId in this.clientSeqNumbers) {\n if (this.clientSeqNumbers[clientId].length > 0) {\n buf += `Client `;\n if (glc) {\n buf += `${glc(+clientId)}`;\n } else {\n buf += `${clientId}`;\n }\n buf += \"[\";\n for (const partial of this.clientSeqNumbers[clientId]) {\n buf += `(${partial.seq},${partial.len})`;\n }\n buf += \"]\";\n }\n }\n buf = `min(seq ${this.minSeq}): ${this.minLength}; sc: ${this.segmentCount};${buf}`;\n return buf;\n }\n\n // Clear away partial sums for sequence numbers earlier than the current window\n private zamboni(segmentWindow: CollaborationWindow) {\n function copyDown(partialLengths: PartialSequenceLength[]) {\n const mindex = latestLEQ(partialLengths, segmentWindow.minSeq);\n let minLength = 0;\n if (mindex >= 0) {\n minLength = partialLengths[mindex].len;\n const seqCount = partialLengths.length;\n if (mindex <= (seqCount - 1)) {\n // Still some entries remaining\n const remainingCount = (seqCount - mindex) - 1;\n // Copy down\n for (let i = 0; i < remainingCount; i++) {\n partialLengths[i] = partialLengths[i + mindex + 1];\n partialLengths[i].len -= minLength;\n }\n partialLengths.length = remainingCount;\n }\n }\n return minLength;\n }\n this.minLength += copyDown(this.partialLengths);\n // eslint-disable-next-line @typescript-eslint/no-for-in-array, guard-for-in, no-restricted-syntax\n for (const clientId in this.clientSeqNumbers) {\n const cliPartials = this.clientSeqNumbers[clientId];\n if (cliPartials) {\n copyDown(cliPartials);\n }\n }\n }\n\n private addClientSeqNumber(clientId: number, seq: number, seglen: number) {\n if (this.clientSeqNumbers[clientId] === undefined) {\n this.clientSeqNumbers[clientId] = [];\n }\n const cli = this.clientSeqNumbers[clientId];\n let pLen = seglen;\n if (cli.length > 0) {\n pLen += cli[cli.length - 1].len;\n }\n cli.push({ seq, len: pLen, seglen });\n }\n\n // Assumes sequence number already coalesced\n private addClientSeqNumberFromPartial(partialLength: PartialSequenceLength) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.addClientSeqNumber(partialLength.clientId!, partialLength.seq, partialLength.seglen);\n if (partialLength.overlapRemoveClients) {\n partialLength.overlapRemoveClients.map((oc: Property<number, IOverlapClient>) => {\n this.addClientSeqNumber(oc.data.clientId, partialLength.seq, oc.data.seglen);\n return true;\n });\n }\n }\n\n private cliLatestLEQ(clientId: number, refSeq: number) {\n const cliSeqs = this.clientSeqNumbers[clientId];\n if (cliSeqs) {\n return latestLEQ(cliSeqs, refSeq);\n } else {\n return -1;\n }\n }\n\n private cliLatest(clientId: number) {\n const cliSeqs = this.clientSeqNumbers[clientId];\n if (cliSeqs && (cliSeqs.length > 0)) {\n return cliSeqs.length - 1;\n } else {\n return -1;\n }\n }\n\n // Debug only\n private verifyPartialLengths(partialLengths: PartialSequenceLength[], clientPartials: boolean) {\n if (partialLengths.length === 0) { return 0; }\n\n let lastSeqNum = 0;\n let accumSegLen = 0;\n let count = 0;\n\n for (const partialLength of partialLengths) {\n // Count total number of partial length\n count++;\n\n // Sequence number should be larger or equal to minseq\n assert(this.minSeq <= partialLength.seq, 0x054 /* \"Sequence number less than minSeq!\" */);\n\n // Sequence number should be sorted\n assert(lastSeqNum < partialLength.seq, 0x055 /* \"Sequence number is not sorted!\" */);\n lastSeqNum = partialLength.seq;\n\n // Len is a accumulation of all the seglen adjustments\n accumSegLen += partialLength.seglen;\n if (accumSegLen !== partialLength.len) {\n assert(false, 0x056 /* \"Unexpected total for accumulation of all seglen adjustments!\" */);\n }\n\n if (clientPartials) {\n // Client partials used to track local edits so we can account for them some refSeq.\n // But the information we keep track of are since minSeq, so we keep track of more history\n // then needed, and some of them doesn't make sense to be used for length calculations\n // e.g. if you have this sequence, where the minSeq is #5 because of other clients\n // seq 10: client 1: insert seg #1\n // seq 11: client 2: delete seg #2 refseq: 10\n // minLength is 0, we would have keep a record of seglen: -1 for clientPartialLengths for client 2\n // So if you ask for partial length for client 2 @ seq 5, we will have return -1.\n // However, that combination is invalid, since we should never see any ops with refseq < 10 for\n // client 2 after seq 11.\n } else {\n // Len adjustment should not make length negative\n if (this.minLength + partialLength.len < 0) {\n assert(false, 0x057 /* \"Negative length after length adjustment!\" */);\n }\n }\n\n if (partialLength.overlapRemoveClients) {\n // Only the flat partialLengths can have overlapRemoveClients, the per client view shouldn't\n assert(!clientPartials, 0x058 /* \"Both overlapRemoveClients and clientPartials are set!\" */);\n\n // Each overlap client count as one\n count += partialLength.overlapRemoveClients.size();\n }\n }\n return count;\n }\n\n private verify() {\n if (this.clientSeqNumbers) {\n let cliCount = 0;\n for (const cliSeq of this.clientSeqNumbers) {\n if (cliSeq) {\n cliCount += this.verifyPartialLengths(cliSeq, true);\n }\n }\n\n // If we have client view, we should have the flat view\n assert(!!this.partialLengths, 0x059 /* \"Client view exists but flat view does not!\" */);\n const flatCount = this.verifyPartialLengths(this.partialLengths, false);\n\n // The number of partial lengths on the client view and flat view should be the same\n assert(flatCount === cliCount,\n 0x05a /* \"Mismatch between number of partial lengths on client and flat views!\" */);\n } else {\n // If we don't have a client view, we shouldn't have the flat view either\n assert(!this.partialLengths, 0x05b /* \"Flat view exists but client view does not!\" */);\n }\n }\n}\n"]}
@@ -51,7 +51,11 @@ export interface IJSONSegmentWithMergeInfo {
51
51
  json: IJSONSegment;
52
52
  client?: string;
53
53
  seq?: number;
54
+ /**
55
+ * @deprecated - use removedClientIds instead. this only exists for back-compat
56
+ */
54
57
  removedClient?: string;
58
+ removedClientIds?: string[];
55
59
  removedSeq?: number;
56
60
  }
57
61
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotChunks.d.ts","sourceRoot":"","sources":["../src/snapshotChunks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,MAAM,WAAW,uBAAuB;IACpC,OAAO,EAAE,SAAS,GAAG,GAAG,CAAC;CAC5B;AAED,oBAAY,gBAAgB,GAAG,YAAY,GAAG,yBAAyB,CAAC;AAExE,MAAM,WAAW,oBAAqB,SAAQ,uBAAuB;IACjE,OAAO,EAAE,SAAS,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,cAAc,CAAC,EAAE,uBAAuB,CAAC;CAC5C;AAED,MAAM,WAAW,4BAA4B;IACzC,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,4BAA4B,EAAE,CAAC;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAiB,SAAQ,uBAAuB;IAC7D,OAAO,EAAE,GAAG,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,cAAc,EAAE,uBAAuB,GAAG,SAAS,CAAC;CACvD;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACtC,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,yBAAyB,GAAG,IAAI,IAAI,yBAAyB,CAE9G;AAED,wBAAgB,8BAA8B,CAC1C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,uBAAuB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE,YAAY,UAuCrB;AAED,wBAAgB,8BAA8B,CAC1C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,uBAAuB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE,YAAY,UAGrB;AAED,wBAAgB,eAAe,CAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,uBAAuB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,gBAAgB,CAmBtD"}
1
+ {"version":3,"file":"snapshotChunks.d.ts","sourceRoot":"","sources":["../src/snapshotChunks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,MAAM,WAAW,uBAAuB;IACpC,OAAO,EAAE,SAAS,GAAG,GAAG,CAAC;CAC5B;AAED,oBAAY,gBAAgB,GAAG,YAAY,GAAG,yBAAyB,CAAC;AAExE,MAAM,WAAW,oBAAqB,SAAQ,uBAAuB;IACjE,OAAO,EAAE,SAAS,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,cAAc,CAAC,EAAE,uBAAuB,CAAC;CAC5C;AAED,MAAM,WAAW,4BAA4B;IACzC,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,uBAAuB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,4BAA4B,EAAE,CAAC;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAiB,SAAQ,uBAAuB;IAC7D,OAAO,EAAE,GAAG,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,cAAc,EAAE,uBAAuB,GAAG,SAAS,CAAC;CACvD;AAED;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACtC,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,yBAAyB,GAAG,IAAI,IAAI,yBAAyB,CAE9G;AAED,wBAAgB,8BAA8B,CAC1C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,uBAAuB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE,YAAY,UAuCrB;AAED,wBAAgB,8BAA8B,CAC1C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,uBAAuB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE,YAAY,UAGrB;AAED,wBAAgB,eAAe,CAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,uBAAuB,EAC9B,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,GAAG,gBAAgB,CAmBtD"}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotChunks.js","sourceRoot":"","sources":["../src/snapshotChunks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAyDlD;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAA8C;IACvE,OAAO,CAAC,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,IAAI,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC1C,IAAY,EACZ,KAA8B,EAC9B,MAAwB,EACxB,OAAgC,EAChC,UAA4B,EAC5B,IAAkB;IAClB,IAAI,WAAiC,CAAC;IAEtC,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE;QAC7B,MAAM,CAAC,IAAI,CAAC;YACR,SAAS,EAAE,+CAA+C;YAC1D,QAAQ,EAAE,SAAS;YACnB,gBAAgB,EAAE,KAAK,CAAC,OAAO;YAC/B,cAAc,EAAE,SAAS;SAC5B,CAAC,CAAC;KACN;IAED,QAAQ,KAAK,CAAC,OAAO,EAAE;QACnB,KAAK,SAAS;YACV,WAAW,GAAG,KAA6B,CAAC;YAC5C,WAAW,CAAC,cAAc,GAAG,iCAAiC,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;YAC3F,MAAM;QAEV,KAAK,GAAG;YACJ,MAAM,OAAO,GAAG,KAAyB,CAAC;YAC1C,MAAM,cAAc,GAAG,IAAI,KAAK,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;YAC3F,WAAW,GAAG;gBACV,OAAO,EAAE,SAAS;gBAClB,sBAAsB,EAAE,OAAO,CAAC,UAAU;gBAC1C,gBAAgB,EAAE,OAAO,CAAC,MAAM;gBAChC,iBAAiB,EAAE,OAAO,CAAC,YAAY;gBACvC,YAAY,EAAE,OAAO,CAAC,QAAQ;gBAC9B,gBAAgB,EAAE,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,WAAW;gBAC7C,iBAAiB,EAAE,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,iBAAiB;gBACpD,mBAAmB,EAAE,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,cAAc;gBACnD,sBAAsB,EAAE,cAAc,aAAd,cAAc,uBAAd,cAAc,CAAE,iBAAiB;gBACzD,cAAc;aACjB,CAAC;YACF,MAAM;QAEV;YACI,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,aAAa,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;KACpF;IACD,OAAO,UAAU,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC1C,IAAY,EACZ,KAA8B,EAC9B,MAAwB,EACxB,OAAgC,EAChC,UAA4B,EAC5B,IAAkB;IAClB,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAClE,OAAO,UAAU,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,eAAe,CAC3B,IAAY,EACZ,KAA8B,EAC9B,MAAwB,EACxB,OAAgC;IAChC,QAAQ,KAAK,CAAC,OAAO,EAAE;QACnB,KAAK,SAAS,CAAC,CAAC;YACZ,MAAM,WAAW,GAAG,KAA6B,CAAC;YAClD,OAAO;gBACH,OAAO,EAAE,GAAG;gBACZ,MAAM,EAAE,WAAW,CAAC,gBAAgB;gBACpC,YAAY,EAAE,WAAW,CAAC,iBAAiB;gBAC3C,cAAc,EAAE,iCAAiC,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC;gBAC7E,QAAQ,EAAE,WAAW,CAAC,YAAY;gBAClC,UAAU,EAAE,WAAW,CAAC,sBAAsB;aACjD,CAAC;SACL;QACD,KAAK,GAAG;YACJ,OAAO,KAAyB,CAAC;QAErC;YACI,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,aAAa,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;KACpF;AACL,CAAC;AAED,SAAS,iCAAiC,CACtC,IAAY,EAAE,KAA2B,EAAE,OAAgC;IAC3E,IAAI,IAAI,KAAK,cAAc,CAAC,MAAM,EAAE;QAChC,IAAI,KAAK,CAAC,cAAc,KAAK,SAAS,EAAE;YACpC,OAAO,KAAK,CAAC,cAAc,CAAC;SAC/B;QACD,MAAM,QAAQ,GAAmC,CAAC,EAAE,EAAE,EAAE,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC;QACjF,IAAI,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAiB,EAAE;YAClD,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;SAC9C;QACD,OAAO;YACH,oBAAoB,EAAE,QAAQ;YAC9B,iBAAiB,EAAE,KAAK,CAAC,sBAAuB;YAChD,cAAc,EAAE,KAAK,CAAC,mBAAoB;YAC1C,WAAW,EAAE,KAAK,CAAC,gBAAiB;YACpC,iBAAiB,EAAE,KAAK,CAAC,iBAAkB;SAC9C,CAAC;KACL;IACD,OAAO,SAAS,CAAC;AACrB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n /* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { PropertySet } from \"./properties\";\nimport { SnapshotLegacy } from \"./snapshotlegacy\";\nimport { IJSONSegment } from \"./ops\";\n\nexport interface VersionedMergeTreeChunk {\n version: undefined | \"1\";\n}\n\nexport type JsonSegmentSpecs = IJSONSegment | IJSONSegmentWithMergeInfo;\n\nexport interface MergeTreeChunkLegacy extends VersionedMergeTreeChunk {\n version: undefined;\n chunkStartSegmentIndex: number,\n chunkSegmentCount: number;\n chunkLengthChars: number;\n totalLengthChars?: number;\n totalSegmentCount?: number;\n chunkSequenceNumber?: number;\n chunkMinSequenceNumber?: number;\n segmentTexts: JsonSegmentSpecs[];\n headerMetadata?: MergeTreeHeaderMetadata;\n}\n\nexport interface MergeTreeHeaderChunkMetadata {\n id: string,\n}\n\nexport interface MergeTreeHeaderMetadata {\n totalLength: number,\n totalSegmentCount: number,\n orderedChunkMetadata: MergeTreeHeaderChunkMetadata[],\n sequenceNumber: number,\n minSequenceNumber: number,\n}\n\nexport interface MergeTreeChunkV1 extends VersionedMergeTreeChunk {\n version: \"1\",\n startIndex: number;\n segmentCount: number;\n length: number;\n segments: JsonSegmentSpecs[];\n headerMetadata: MergeTreeHeaderMetadata | undefined;\n}\n\n/**\n * Used during snapshotting to record the metadata required to merge segments above the MSN\n * to the raw output of `ISegment.toJSONObject()`. (Note that IJSONSegment may be a raw\n * string or array, which is why this interface wraps the original IJSONSegment instead of\n * extending it.)\n */\nexport interface IJSONSegmentWithMergeInfo {\n json: IJSONSegment;\n client?: string;\n seq?: number;\n removedClient?: string;\n removedSeq?: number;\n}\n\n/**\n * Returns true if the given 'spec' is an IJSONSegmentWithMergeInfo.\n */\nexport function hasMergeInfo(spec: IJSONSegment | IJSONSegmentWithMergeInfo): spec is IJSONSegmentWithMergeInfo {\n return !!spec && typeof spec === \"object\" && \"json\" in spec;\n}\n\nexport function serializeAsMinSupportedVersion(\n path: string,\n chunk: VersionedMergeTreeChunk,\n logger: ITelemetryLogger,\n options: PropertySet | undefined,\n serializer: IFluidSerializer,\n bind: IFluidHandle) {\n let targetChuck: MergeTreeChunkLegacy;\n\n if (chunk.version !== undefined) {\n logger.send({\n eventName: \"MergeTreeChunk:serializeAsMinSupportedVersion\",\n category: \"generic\",\n fromChunkVersion: chunk.version,\n toChunkVersion: undefined,\n });\n }\n\n switch (chunk.version) {\n case undefined:\n targetChuck = chunk as MergeTreeChunkLegacy;\n targetChuck.headerMetadata = buildHeaderMetadataForLegacyChunk(path, targetChuck, options);\n break;\n\n case \"1\":\n const chunkV1 = chunk as MergeTreeChunkV1;\n const headerMetadata = path === SnapshotLegacy.header ? chunkV1.headerMetadata : undefined;\n targetChuck = {\n version: undefined,\n chunkStartSegmentIndex: chunkV1.startIndex,\n chunkLengthChars: chunkV1.length,\n chunkSegmentCount: chunkV1.segmentCount,\n segmentTexts: chunkV1.segments,\n totalLengthChars: headerMetadata?.totalLength,\n totalSegmentCount: headerMetadata?.totalSegmentCount,\n chunkSequenceNumber: headerMetadata?.sequenceNumber,\n chunkMinSequenceNumber: headerMetadata?.minSequenceNumber,\n headerMetadata,\n };\n break;\n\n default:\n throw new Error(`Unsupported chunk path: ${path} version: ${chunk.version}`);\n }\n return serializer.stringify(targetChuck, bind);\n}\n\nexport function serializeAsMaxSupportedVersion(\n path: string,\n chunk: VersionedMergeTreeChunk,\n logger: ITelemetryLogger,\n options: PropertySet | undefined,\n serializer: IFluidSerializer,\n bind: IFluidHandle) {\n const targetChuck = toLatestVersion(path, chunk, logger, options);\n return serializer.stringify(targetChuck, bind);\n}\n\nexport function toLatestVersion(\n path: string,\n chunk: VersionedMergeTreeChunk,\n logger: ITelemetryLogger,\n options: PropertySet | undefined): MergeTreeChunkV1 {\n switch (chunk.version) {\n case undefined: {\n const chunkLegacy = chunk as MergeTreeChunkLegacy;\n return {\n version: \"1\",\n length: chunkLegacy.chunkLengthChars,\n segmentCount: chunkLegacy.chunkSegmentCount,\n headerMetadata: buildHeaderMetadataForLegacyChunk(path, chunkLegacy, options),\n segments: chunkLegacy.segmentTexts,\n startIndex: chunkLegacy.chunkStartSegmentIndex,\n };\n }\n case \"1\":\n return chunk as MergeTreeChunkV1;\n\n default:\n throw new Error(`Unsupported chunk path: ${path} version: ${chunk.version}`);\n }\n}\n\nfunction buildHeaderMetadataForLegacyChunk(\n path: string, chunk: MergeTreeChunkLegacy, options: PropertySet | undefined): MergeTreeHeaderMetadata | undefined {\n if (path === SnapshotLegacy.header) {\n if (chunk.headerMetadata !== undefined) {\n return chunk.headerMetadata;\n }\n const chunkIds: MergeTreeHeaderChunkMetadata[] = [{ id: SnapshotLegacy.header }];\n if (chunk.chunkLengthChars < chunk.totalLengthChars!) {\n chunkIds.push({ id: SnapshotLegacy.body });\n }\n return {\n orderedChunkMetadata: chunkIds,\n minSequenceNumber: chunk.chunkMinSequenceNumber!,\n sequenceNumber: chunk.chunkSequenceNumber!,\n totalLength: chunk.totalLengthChars!,\n totalSegmentCount: chunk.totalSegmentCount!,\n };\n }\n return undefined;\n}\n"]}
1
+ {"version":3,"file":"snapshotChunks.js","sourceRoot":"","sources":["../src/snapshotChunks.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 /* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { PropertySet } from \"./properties\";\nimport { SnapshotLegacy } from \"./snapshotlegacy\";\nimport { IJSONSegment } from \"./ops\";\n\nexport interface VersionedMergeTreeChunk {\n version: undefined | \"1\";\n}\n\nexport type JsonSegmentSpecs = IJSONSegment | IJSONSegmentWithMergeInfo;\n\nexport interface MergeTreeChunkLegacy extends VersionedMergeTreeChunk {\n version: undefined;\n chunkStartSegmentIndex: number,\n chunkSegmentCount: number;\n chunkLengthChars: number;\n totalLengthChars?: number;\n totalSegmentCount?: number;\n chunkSequenceNumber?: number;\n chunkMinSequenceNumber?: number;\n segmentTexts: JsonSegmentSpecs[];\n headerMetadata?: MergeTreeHeaderMetadata;\n}\n\nexport interface MergeTreeHeaderChunkMetadata {\n id: string,\n}\n\nexport interface MergeTreeHeaderMetadata {\n totalLength: number,\n totalSegmentCount: number,\n orderedChunkMetadata: MergeTreeHeaderChunkMetadata[],\n sequenceNumber: number,\n minSequenceNumber: number,\n}\n\nexport interface MergeTreeChunkV1 extends VersionedMergeTreeChunk {\n version: \"1\",\n startIndex: number;\n segmentCount: number;\n length: number;\n segments: JsonSegmentSpecs[];\n headerMetadata: MergeTreeHeaderMetadata | undefined;\n}\n\n/**\n * Used during snapshotting to record the metadata required to merge segments above the MSN\n * to the raw output of `ISegment.toJSONObject()`. (Note that IJSONSegment may be a raw\n * string or array, which is why this interface wraps the original IJSONSegment instead of\n * extending it.)\n */\nexport interface IJSONSegmentWithMergeInfo {\n json: IJSONSegment;\n client?: string;\n seq?: number;\n /**\n * @deprecated - use removedClientIds instead. this only exists for back-compat\n */\n removedClient?: string;\n removedClientIds?: string[];\n removedSeq?: number;\n}\n\n/**\n * Returns true if the given 'spec' is an IJSONSegmentWithMergeInfo.\n */\nexport function hasMergeInfo(spec: IJSONSegment | IJSONSegmentWithMergeInfo): spec is IJSONSegmentWithMergeInfo {\n return !!spec && typeof spec === \"object\" && \"json\" in spec;\n}\n\nexport function serializeAsMinSupportedVersion(\n path: string,\n chunk: VersionedMergeTreeChunk,\n logger: ITelemetryLogger,\n options: PropertySet | undefined,\n serializer: IFluidSerializer,\n bind: IFluidHandle) {\n let targetChuck: MergeTreeChunkLegacy;\n\n if (chunk.version !== undefined) {\n logger.send({\n eventName: \"MergeTreeChunk:serializeAsMinSupportedVersion\",\n category: \"generic\",\n fromChunkVersion: chunk.version,\n toChunkVersion: undefined,\n });\n }\n\n switch (chunk.version) {\n case undefined:\n targetChuck = chunk as MergeTreeChunkLegacy;\n targetChuck.headerMetadata = buildHeaderMetadataForLegacyChunk(path, targetChuck, options);\n break;\n\n case \"1\":\n const chunkV1 = chunk as MergeTreeChunkV1;\n const headerMetadata = path === SnapshotLegacy.header ? chunkV1.headerMetadata : undefined;\n targetChuck = {\n version: undefined,\n chunkStartSegmentIndex: chunkV1.startIndex,\n chunkLengthChars: chunkV1.length,\n chunkSegmentCount: chunkV1.segmentCount,\n segmentTexts: chunkV1.segments,\n totalLengthChars: headerMetadata?.totalLength,\n totalSegmentCount: headerMetadata?.totalSegmentCount,\n chunkSequenceNumber: headerMetadata?.sequenceNumber,\n chunkMinSequenceNumber: headerMetadata?.minSequenceNumber,\n headerMetadata,\n };\n break;\n\n default:\n throw new Error(`Unsupported chunk path: ${path} version: ${chunk.version}`);\n }\n return serializer.stringify(targetChuck, bind);\n}\n\nexport function serializeAsMaxSupportedVersion(\n path: string,\n chunk: VersionedMergeTreeChunk,\n logger: ITelemetryLogger,\n options: PropertySet | undefined,\n serializer: IFluidSerializer,\n bind: IFluidHandle) {\n const targetChuck = toLatestVersion(path, chunk, logger, options);\n return serializer.stringify(targetChuck, bind);\n}\n\nexport function toLatestVersion(\n path: string,\n chunk: VersionedMergeTreeChunk,\n logger: ITelemetryLogger,\n options: PropertySet | undefined): MergeTreeChunkV1 {\n switch (chunk.version) {\n case undefined: {\n const chunkLegacy = chunk as MergeTreeChunkLegacy;\n return {\n version: \"1\",\n length: chunkLegacy.chunkLengthChars,\n segmentCount: chunkLegacy.chunkSegmentCount,\n headerMetadata: buildHeaderMetadataForLegacyChunk(path, chunkLegacy, options),\n segments: chunkLegacy.segmentTexts,\n startIndex: chunkLegacy.chunkStartSegmentIndex,\n };\n }\n case \"1\":\n return chunk as MergeTreeChunkV1;\n\n default:\n throw new Error(`Unsupported chunk path: ${path} version: ${chunk.version}`);\n }\n}\n\nfunction buildHeaderMetadataForLegacyChunk(\n path: string, chunk: MergeTreeChunkLegacy, options: PropertySet | undefined): MergeTreeHeaderMetadata | undefined {\n if (path === SnapshotLegacy.header) {\n if (chunk.headerMetadata !== undefined) {\n return chunk.headerMetadata;\n }\n const chunkIds: MergeTreeHeaderChunkMetadata[] = [{ id: SnapshotLegacy.header }];\n if (chunk.chunkLengthChars < chunk.totalLengthChars!) {\n chunkIds.push({ id: SnapshotLegacy.body });\n }\n return {\n orderedChunkMetadata: chunkIds,\n minSequenceNumber: chunk.chunkMinSequenceNumber!,\n sequenceNumber: chunk.chunkSequenceNumber!,\n totalLength: chunk.totalLengthChars!,\n totalSegmentCount: chunk.totalSegmentCount!,\n };\n }\n return undefined;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AACvG,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAY,SAAS,EAAE,MAAM,aAAa,CAAC;AAUlD,qBAAa,cAAc;IAInB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAP/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAGrB,OAAO,EAAE,sBAAsB,EAC/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,gBAAgB,EACP,UAAU,EAAE,gBAAgB;IAIpC,UAAU,CACnB,QAAQ,EAAE,sBAAsB,GACjC,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAkBnD,qBAAqB;IA2BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAgC5B;IAEF,OAAO,CAAC,UAAU;YAoCJ,QAAQ;IAoEtB;;;;;OAKG;YACW,cAAc;CAG/B"}
1
+ {"version":3,"file":"snapshotLoader.d.ts","sourceRoot":"","sources":["../src/snapshotLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AACvG,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAY,SAAS,EAAE,MAAM,aAAa,CAAC;AAUlD,qBAAa,cAAc;IAInB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAP/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAGrB,OAAO,EAAE,sBAAsB,EAC/B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACrC,MAAM,EAAE,gBAAgB,EACP,UAAU,EAAE,gBAAgB;IAIpC,UAAU,CACnB,QAAQ,EAAE,sBAAsB,GACjC,OAAO,CAAC;QAAE,WAAW,EAAE,OAAO,CAAC,yBAAyB,EAAE,CAAC,CAAA;KAAE,CAAC;YAkBnD,qBAAqB;IA2BnC,OAAO,CAAC,QAAQ,CAAC,aAAa,CA2C5B;IAEF,OAAO,CAAC,UAAU;YAoCJ,QAAQ;IAoEtB;;;;;OAKG;YACW,cAAc;CAG/B"}
@@ -31,9 +31,19 @@ export class SnapshotLoader {
31
31
  if (spec.removedSeq !== undefined) {
32
32
  seg.removedSeq = spec.removedSeq;
33
33
  }
34
+ // this format had a bug where it didn't store all the overlap clients
35
+ // this is for back compat, so we change the singular id to an array
36
+ // this will only cause problems if there is an overlapping delete
37
+ // spanning the snapshot, which should be rare
34
38
  if (spec.removedClient !== undefined) {
35
39
  seg.removedClientId = this.client.getOrAddShortClientId(spec.removedClient);
36
40
  }
41
+ if (spec.removedClientIds !== undefined) {
42
+ seg.removedClientId = this.client.getOrAddShortClientId(spec.removedClientIds[0]);
43
+ if (spec.removedClientIds.length > 1) {
44
+ seg.removedClientOverlap = spec.removedClientIds.slice(1).map((sid) => this.client.getOrAddShortClientId(sid));
45
+ }
46
+ }
37
47
  }
38
48
  else {
39
49
  seg = this.client.specToSegment(spec);
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotLoader.js","sourceRoot":"","sources":["../src/snapshotLoader.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/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { assert, bufferToString } from \"@fluidframework/common-utils\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { IFluidDataStoreRuntime, IChannelStorageService } from \"@fluidframework/datastore-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { Client } from \"./client\";\nimport { NonCollabClient, UniversalSequenceNumber } from \"./constants\";\nimport { ISegment, MergeTree } from \"./mergeTree\";\nimport { IJSONSegment } from \"./ops\";\nimport {\n IJSONSegmentWithMergeInfo,\n hasMergeInfo,\n MergeTreeChunkV1,\n} from \"./snapshotChunks\";\nimport { SnapshotV1 } from \"./snapshotV1\";\nimport { SnapshotLegacy } from \"./snapshotlegacy\";\n\nexport class SnapshotLoader {\n private readonly logger: ITelemetryLogger;\n\n constructor(\n private readonly runtime: IFluidDataStoreRuntime,\n private readonly client: Client,\n private readonly mergeTree: MergeTree,\n logger: ITelemetryLogger,\n private readonly serializer: IFluidSerializer) {\n this.logger = ChildLogger.create(logger, \"SnapshotLoader\");\n }\n\n public async initialize(\n services: IChannelStorageService,\n ): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]> }> {\n const headerLoadedP =\n services.readBlob(SnapshotLegacy.header).then((header) => {\n assert(!!header, 0x05f /* \"Missing blob header on legacy snapshot!\" */);\n return this.loadHeader(bufferToString(header,\"utf8\"));\n });\n\n const catchupOpsP =\n this.loadBodyAndCatchupOps(headerLoadedP, services);\n\n catchupOpsP.catch(\n (err)=>this.logger.sendErrorEvent({ eventName: \"CatchupOpsLoadFailure\" },err));\n\n await headerLoadedP;\n\n return { catchupOpsP };\n }\n\n private async loadBodyAndCatchupOps(\n headerChunkP: Promise<MergeTreeChunkV1>,\n services: IChannelStorageService,\n ): Promise<ISequencedDocumentMessage[]> {\n const blobsP = services.list(\"\");\n const headerChunk = await headerChunkP;\n\n // TODO we shouldn't need to wait on the body being complete to finish initialization.\n // To fully support this we need to be able to process inbound ops for pending segments.\n await this.loadBody(headerChunk, services);\n\n const blobs = await blobsP;\n if (blobs.length === headerChunk.headerMetadata!.orderedChunkMetadata.length + 1) {\n headerChunk.headerMetadata!.orderedChunkMetadata.forEach(\n (md) => blobs.splice(blobs.indexOf(md.id), 1));\n assert(blobs.length === 1, 0x060 /* `There should be only one blob with catch up ops: ${blobs.length}` */);\n\n // TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.\n // (See https://github.com/microsoft/FluidFramework/issues/84)\n\n return this.loadCatchupOps(services.readBlob(blobs[0]));\n } else if (blobs.length !== headerChunk.headerMetadata!.orderedChunkMetadata.length) {\n throw new Error(\"Unexpected blobs in snapshot\");\n }\n return [];\n }\n\n private readonly specToSegment = (spec: IJSONSegment | IJSONSegmentWithMergeInfo) => {\n let seg: ISegment;\n\n if (hasMergeInfo(spec)) {\n seg = this.client.specToSegment(spec.json);\n\n // `specToSegment()` initializes `seg` with the LocalClientId. Overwrite this with\n // the `spec` client (if specified). Otherwise overwrite with `NonCollabClient`.\n seg.clientId = spec.client !== undefined\n ? this.client.getOrAddShortClientId(spec.client)\n : NonCollabClient;\n\n seg.seq = spec.seq !== undefined\n ? spec.seq\n : UniversalSequenceNumber;\n\n if (spec.removedSeq !== undefined) {\n seg.removedSeq = spec.removedSeq;\n }\n if (spec.removedClient !== undefined) {\n seg.removedClientId = this.client.getOrAddShortClientId(spec.removedClient);\n }\n } else {\n seg = this.client.specToSegment(spec);\n seg.seq = UniversalSequenceNumber;\n\n // `specToSegment()` initializes `seg` with the LocalClientId. We must overwrite this with\n // `NonCollabClient`.\n seg.clientId = NonCollabClient;\n }\n\n return seg;\n };\n\n private loadHeader(header: string): MergeTreeChunkV1 {\n const chunk = SnapshotV1.processChunk(\n SnapshotLegacy.header,\n header,\n this.logger,\n this.mergeTree.options,\n this.serializer);\n const segs = chunk.segments.map(this.specToSegment);\n this.mergeTree.reloadFromSegments(segs);\n\n if (chunk.headerMetadata === undefined) {\n throw new Error(\"header metadata not available\");\n }\n // If we load a detached container from snapshot, then we don't supply a default clientId\n // because we don't want to start collaboration.\n if (this.runtime.attachState !== AttachState.Detached) {\n // specify a default client id, \"snapshot\" here as we\n // should enter collaboration/op sending mode if we load\n // a snapshot in any case (summary or attach message)\n // once we get a client id this will be called with that\n // clientId in the connected event\n this.client.startOrUpdateCollaboration(\n this.runtime.clientId ?? \"snapshot\",\n\n // TODO: Make 'minSeq' non-optional once the new snapshot format becomes the default?\n // (See https://github.com/microsoft/FluidFramework/issues/84)\n /* minSeq: */ chunk.headerMetadata.minSequenceNumber !== undefined\n ? chunk.headerMetadata.minSequenceNumber\n : chunk.headerMetadata.sequenceNumber,\n /* currentSeq: */ chunk.headerMetadata.sequenceNumber,\n );\n }\n\n return chunk;\n }\n\n private async loadBody(chunk1: MergeTreeChunkV1, services: IChannelStorageService): Promise<void> {\n assert(\n chunk1.length <= chunk1.headerMetadata!.totalLength,\n 0x061 /* \"Mismatch in totalLength\" */);\n\n assert(\n chunk1.segmentCount <= chunk1.headerMetadata!.totalSegmentCount,\n 0x062 /* \"Mismatch in totalSegmentCount\" */);\n\n if (chunk1.segmentCount === chunk1.headerMetadata!.totalSegmentCount) {\n return;\n }\n const segs: ISegment[] = [];\n let lengthSofar = chunk1.length;\n for (let chunkIndex = 1; chunkIndex < chunk1.headerMetadata!.orderedChunkMetadata.length; chunkIndex++) {\n const chunk = await SnapshotV1.loadChunk(\n services,\n chunk1.headerMetadata!.orderedChunkMetadata[chunkIndex].id,\n this.logger,\n this.mergeTree.options,\n this.serializer);\n lengthSofar += chunk.length;\n // Deserialize each chunk segment and append it to the end of the MergeTree.\n segs.push(...chunk.segments.map(this.specToSegment));\n }\n assert(\n lengthSofar === chunk1.headerMetadata!.totalLength,\n 0x063 /* \"Mismatch in totalLength\" */);\n\n assert(\n chunk1.segmentCount + segs.length === chunk1.headerMetadata!.totalSegmentCount,\n 0x064 /* \"Mismatch in totalSegmentCount\" */);\n\n // Helper to insert segments at the end of the MergeTree.\n const mergeTree = this.mergeTree;\n const append = (segments: ISegment[], cli: number, seq: number) => {\n mergeTree.insertSegments(\n mergeTree.root.cachedLength,\n segments,\n /* refSeq: */ UniversalSequenceNumber,\n cli,\n seq,\n undefined);\n };\n\n // Helpers to batch-insert segments that are below the min seq\n const batch: ISegment[] = [];\n const flushBatch = () => {\n if (batch.length > 0) { append(batch, NonCollabClient, UniversalSequenceNumber); }\n };\n\n for (const seg of segs) {\n const cli = seg.clientId;\n const seq = seg.seq;\n\n // If the segment can be batch inserted, add it to the 'batch' array. Otherwise, flush\n // any batched segments and then insert the current segment individually.\n if (cli === NonCollabClient && seq === UniversalSequenceNumber) {\n batch.push(seg);\n } else {\n flushBatch();\n append([seg], cli, seq!);\n }\n }\n\n flushBatch();\n }\n\n /**\n * If loading from a snapshot, get the catchup messages.\n * @param rawMessages - The messages in original encoding\n * @returns The decoded messages, but handles aren't parsed. Matches the format that will be passed in\n * SharedObject.processCore.\n */\n private async loadCatchupOps(rawMessages: Promise<ArrayBufferLike>): Promise<ISequencedDocumentMessage[]> {\n return JSON.parse(bufferToString(await rawMessages, \"utf8\")) as ISequencedDocumentMessage[];\n }\n}\n"]}
1
+ {"version":3,"file":"snapshotLoader.js","sourceRoot":"","sources":["../src/snapshotLoader.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/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { assert, bufferToString } from \"@fluidframework/common-utils\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/protocol-definitions\";\nimport { IFluidDataStoreRuntime, IChannelStorageService } from \"@fluidframework/datastore-definitions\";\nimport { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { Client } from \"./client\";\nimport { NonCollabClient, UniversalSequenceNumber } from \"./constants\";\nimport { ISegment, MergeTree } from \"./mergeTree\";\nimport { IJSONSegment } from \"./ops\";\nimport {\n IJSONSegmentWithMergeInfo,\n hasMergeInfo,\n MergeTreeChunkV1,\n} from \"./snapshotChunks\";\nimport { SnapshotV1 } from \"./snapshotV1\";\nimport { SnapshotLegacy } from \"./snapshotlegacy\";\n\nexport class SnapshotLoader {\n private readonly logger: ITelemetryLogger;\n\n constructor(\n private readonly runtime: IFluidDataStoreRuntime,\n private readonly client: Client,\n private readonly mergeTree: MergeTree,\n logger: ITelemetryLogger,\n private readonly serializer: IFluidSerializer) {\n this.logger = ChildLogger.create(logger, \"SnapshotLoader\");\n }\n\n public async initialize(\n services: IChannelStorageService,\n ): Promise<{ catchupOpsP: Promise<ISequencedDocumentMessage[]> }> {\n const headerLoadedP =\n services.readBlob(SnapshotLegacy.header).then((header) => {\n assert(!!header, 0x05f /* \"Missing blob header on legacy snapshot!\" */);\n return this.loadHeader(bufferToString(header,\"utf8\"));\n });\n\n const catchupOpsP =\n this.loadBodyAndCatchupOps(headerLoadedP, services);\n\n catchupOpsP.catch(\n (err)=>this.logger.sendErrorEvent({ eventName: \"CatchupOpsLoadFailure\" },err));\n\n await headerLoadedP;\n\n return { catchupOpsP };\n }\n\n private async loadBodyAndCatchupOps(\n headerChunkP: Promise<MergeTreeChunkV1>,\n services: IChannelStorageService,\n ): Promise<ISequencedDocumentMessage[]> {\n const blobsP = services.list(\"\");\n const headerChunk = await headerChunkP;\n\n // TODO we shouldn't need to wait on the body being complete to finish initialization.\n // To fully support this we need to be able to process inbound ops for pending segments.\n await this.loadBody(headerChunk, services);\n\n const blobs = await blobsP;\n if (blobs.length === headerChunk.headerMetadata!.orderedChunkMetadata.length + 1) {\n headerChunk.headerMetadata!.orderedChunkMetadata.forEach(\n (md) => blobs.splice(blobs.indexOf(md.id), 1));\n assert(blobs.length === 1, 0x060 /* `There should be only one blob with catch up ops: ${blobs.length}` */);\n\n // TODO: The 'Snapshot.catchupOps' tree entry is purely for backwards compatibility.\n // (See https://github.com/microsoft/FluidFramework/issues/84)\n\n return this.loadCatchupOps(services.readBlob(blobs[0]));\n } else if (blobs.length !== headerChunk.headerMetadata!.orderedChunkMetadata.length) {\n throw new Error(\"Unexpected blobs in snapshot\");\n }\n return [];\n }\n\n private readonly specToSegment = (spec: IJSONSegment | IJSONSegmentWithMergeInfo) => {\n let seg: ISegment;\n\n if (hasMergeInfo(spec)) {\n seg = this.client.specToSegment(spec.json);\n\n // `specToSegment()` initializes `seg` with the LocalClientId. Overwrite this with\n // the `spec` client (if specified). Otherwise overwrite with `NonCollabClient`.\n seg.clientId = spec.client !== undefined\n ? this.client.getOrAddShortClientId(spec.client)\n : NonCollabClient;\n\n seg.seq = spec.seq !== undefined\n ? spec.seq\n : UniversalSequenceNumber;\n\n if (spec.removedSeq !== undefined) {\n seg.removedSeq = spec.removedSeq;\n }\n // this format had a bug where it didn't store all the overlap clients\n // this is for back compat, so we change the singular id to an array\n // this will only cause problems if there is an overlapping delete\n // spanning the snapshot, which should be rare\n if (spec.removedClient !== undefined) {\n seg.removedClientId = this.client.getOrAddShortClientId(spec.removedClient);\n }\n if (spec.removedClientIds !== undefined) {\n seg.removedClientId = this.client.getOrAddShortClientId(spec.removedClientIds[0]);\n if(spec.removedClientIds.length > 1) {\n seg.removedClientOverlap = spec.removedClientIds.slice(1).map(\n (sid)=> this.client.getOrAddShortClientId(sid));\n }\n }\n } else {\n seg = this.client.specToSegment(spec);\n seg.seq = UniversalSequenceNumber;\n\n // `specToSegment()` initializes `seg` with the LocalClientId. We must overwrite this with\n // `NonCollabClient`.\n seg.clientId = NonCollabClient;\n }\n\n return seg;\n };\n\n private loadHeader(header: string): MergeTreeChunkV1 {\n const chunk = SnapshotV1.processChunk(\n SnapshotLegacy.header,\n header,\n this.logger,\n this.mergeTree.options,\n this.serializer);\n const segs = chunk.segments.map(this.specToSegment);\n this.mergeTree.reloadFromSegments(segs);\n\n if (chunk.headerMetadata === undefined) {\n throw new Error(\"header metadata not available\");\n }\n // If we load a detached container from snapshot, then we don't supply a default clientId\n // because we don't want to start collaboration.\n if (this.runtime.attachState !== AttachState.Detached) {\n // specify a default client id, \"snapshot\" here as we\n // should enter collaboration/op sending mode if we load\n // a snapshot in any case (summary or attach message)\n // once we get a client id this will be called with that\n // clientId in the connected event\n this.client.startOrUpdateCollaboration(\n this.runtime.clientId ?? \"snapshot\",\n\n // TODO: Make 'minSeq' non-optional once the new snapshot format becomes the default?\n // (See https://github.com/microsoft/FluidFramework/issues/84)\n /* minSeq: */ chunk.headerMetadata.minSequenceNumber !== undefined\n ? chunk.headerMetadata.minSequenceNumber\n : chunk.headerMetadata.sequenceNumber,\n /* currentSeq: */ chunk.headerMetadata.sequenceNumber,\n );\n }\n\n return chunk;\n }\n\n private async loadBody(chunk1: MergeTreeChunkV1, services: IChannelStorageService): Promise<void> {\n assert(\n chunk1.length <= chunk1.headerMetadata!.totalLength,\n 0x061 /* \"Mismatch in totalLength\" */);\n\n assert(\n chunk1.segmentCount <= chunk1.headerMetadata!.totalSegmentCount,\n 0x062 /* \"Mismatch in totalSegmentCount\" */);\n\n if (chunk1.segmentCount === chunk1.headerMetadata!.totalSegmentCount) {\n return;\n }\n const segs: ISegment[] = [];\n let lengthSofar = chunk1.length;\n for (let chunkIndex = 1; chunkIndex < chunk1.headerMetadata!.orderedChunkMetadata.length; chunkIndex++) {\n const chunk = await SnapshotV1.loadChunk(\n services,\n chunk1.headerMetadata!.orderedChunkMetadata[chunkIndex].id,\n this.logger,\n this.mergeTree.options,\n this.serializer);\n lengthSofar += chunk.length;\n // Deserialize each chunk segment and append it to the end of the MergeTree.\n segs.push(...chunk.segments.map(this.specToSegment));\n }\n assert(\n lengthSofar === chunk1.headerMetadata!.totalLength,\n 0x063 /* \"Mismatch in totalLength\" */);\n\n assert(\n chunk1.segmentCount + segs.length === chunk1.headerMetadata!.totalSegmentCount,\n 0x064 /* \"Mismatch in totalSegmentCount\" */);\n\n // Helper to insert segments at the end of the MergeTree.\n const mergeTree = this.mergeTree;\n const append = (segments: ISegment[], cli: number, seq: number) => {\n mergeTree.insertSegments(\n mergeTree.root.cachedLength,\n segments,\n /* refSeq: */ UniversalSequenceNumber,\n cli,\n seq,\n undefined);\n };\n\n // Helpers to batch-insert segments that are below the min seq\n const batch: ISegment[] = [];\n const flushBatch = () => {\n if (batch.length > 0) { append(batch, NonCollabClient, UniversalSequenceNumber); }\n };\n\n for (const seg of segs) {\n const cli = seg.clientId;\n const seq = seg.seq;\n\n // If the segment can be batch inserted, add it to the 'batch' array. Otherwise, flush\n // any batched segments and then insert the current segment individually.\n if (cli === NonCollabClient && seq === UniversalSequenceNumber) {\n batch.push(seg);\n } else {\n flushBatch();\n append([seg], cli, seq!);\n }\n }\n\n flushBatch();\n }\n\n /**\n * If loading from a snapshot, get the catchup messages.\n * @param rawMessages - The messages in original encoding\n * @returns The decoded messages, but handles aren't parsed. Matches the format that will be passed in\n * SharedObject.processCore.\n */\n private async loadCatchupOps(rawMessages: Promise<ArrayBufferLike>): Promise<ISequencedDocumentMessage[]> {\n return JSON.parse(bufferToString(await rawMessages, \"utf8\")) as ISequencedDocumentMessage[];\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotV1.d.ts","sourceRoot":"","sources":["../src/snapshotV1.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,OAAO,EAEH,SAAS,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAEH,WAAW,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,EAEH,gBAAgB,EAEhB,gBAAgB,EAGnB,MAAM,kBAAkB,CAAC;AAG1B,qBAAa,UAAU;IAgBR,SAAS,EAAE,SAAS;IAE3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IACzB,QAAQ,CAAC;IACT,YAAY,CAAC,SAAQ,IAAI;IAbpC,gBAAuB,SAAS,EAAE,MAAM,CAAS;IAEjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAW;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGxB,SAAS,EAAE,SAAS,EAC3B,MAAM,EAAE,gBAAgB,EACP,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,EACjD,QAAQ,CAAC,oBAAQ,EACjB,YAAY,CAAC,SAAQ,IAAI,aAAA;IAkBpC,OAAO,CAAC,gBAAgB;IAwBxB;;;OAGG;IACH,IAAI,CACA,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE,YAAY,GACnB,qBAAqB;IAgDxB,WAAW;WA8FS,SAAS,CACzB,OAAO,EAAE,sBAAsB,EAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,UAAU,CAAC,EAAE,gBAAgB,GAC9B,OAAO,CAAC,gBAAgB,CAAC;WAMd,YAAY,CACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,UAAU,CAAC,EAAE,gBAAgB,GAC9B,gBAAgB;CAItB"}
1
+ {"version":3,"file":"snapshotV1.d.ts","sourceRoot":"","sources":["../src/snapshotV1.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAG5E,OAAO,EAEH,SAAS,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAEH,WAAW,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,EAEH,gBAAgB,EAEhB,gBAAgB,EAGnB,MAAM,kBAAkB,CAAC;AAG1B,qBAAa,UAAU;IAgBR,SAAS,EAAE,SAAS;IAE3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IACzB,QAAQ,CAAC;IACT,YAAY,CAAC,SAAQ,IAAI;IAbpC,gBAAuB,SAAS,EAAE,MAAM,CAAS;IAEjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAW;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGxB,SAAS,EAAE,SAAS,EAC3B,MAAM,EAAE,gBAAgB,EACP,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,EACjD,QAAQ,CAAC,oBAAQ,EACjB,YAAY,CAAC,SAAQ,IAAI,aAAA;IAkBpC,OAAO,CAAC,gBAAgB;IAwBxB;;;OAGG;IACH,IAAI,CACA,UAAU,EAAE,gBAAgB,EAC5B,IAAI,EAAE,YAAY,GACnB,qBAAqB;IAgDxB,WAAW;WAuGS,SAAS,CACzB,OAAO,EAAE,sBAAsB,EAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,UAAU,CAAC,EAAE,gBAAgB,GAC9B,OAAO,CAAC,gBAAgB,CAAC;WAMd,YAAY,CACtB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,gBAAgB,EACxB,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,UAAU,CAAC,EAAE,gBAAgB,GAC9B,gBAAgB;CAItB"}
package/lib/snapshotV1.js CHANGED
@@ -150,8 +150,15 @@ export class SnapshotV1 {
150
150
  if (segment.removedSeq !== undefined) {
151
151
  assert(segment.removedSeq !== UnassignedSequenceNumber && segment.removedSeq > minSeq, 0x065 /* "On removal info preservation, segment has invalid removed sequence number!" */);
152
152
  raw.removedSeq = segment.removedSeq;
153
+ // back compat for when we split overlap and removed client
153
154
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
154
155
  raw.removedClient = this.getLongClientId(segment.removedClientId);
156
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
157
+ const removedClientIds = [segment.removedClientId];
158
+ if (segment.removedClientOverlap !== undefined) {
159
+ removedClientIds.push(...segment.removedClientOverlap);
160
+ }
161
+ raw.removedClientIds = removedClientIds.map((id) => this.getLongClientId(id));
155
162
  }
156
163
  // Sanity check that we are preserving either the seq < minSeq or a removed segment's info.
157
164
  assert(raw.seq !== undefined && raw.client !== undefined
@@ -1 +1 @@
1
- {"version":3,"file":"snapshotV1.js","sourceRoot":"","sources":["../src/snapshotV1.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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport { assert, bufferToString } from \"@fluidframework/common-utils\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { IChannelStorageService } from \"@fluidframework/datastore-definitions\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport { UnassignedSequenceNumber } from \"./constants\";\nimport {\n ISegment,\n MergeTree,\n} from \"./mergeTree\";\nimport {\n matchProperties,\n PropertySet,\n} from \"./properties\";\nimport {\n IJSONSegmentWithMergeInfo,\n JsonSegmentSpecs,\n MergeTreeHeaderMetadata,\n MergeTreeChunkV1,\n toLatestVersion,\n serializeAsMaxSupportedVersion,\n} from \"./snapshotChunks\";\nimport { SnapshotLegacy } from \"./snapshotlegacy\";\n\nexport class SnapshotV1 {\n // Split snapshot into two entries - headers (small) and body (overflow) for faster loading initial content\n // Please note that this number has no direct relationship to anything other than size of raw text (characters).\n // As we produce json for the blob (and then send over the wire compressed), this number\n // is really hard to correlate with any actual metric that matters (like bytes over the wire).\n // For test with small number of chunks it would be closer to blob size,\n // for very chunky text, blob size can easily be 4x-8x of that number.\n public static readonly chunkSize: number = 10000;\n\n private readonly header: MergeTreeHeaderMetadata;\n private readonly segments: JsonSegmentSpecs[];\n private readonly segmentLengths: number[];\n private readonly logger: ITelemetryLogger;\n private readonly chunkSize: number;\n\n constructor(\n public mergeTree: MergeTree,\n logger: ITelemetryLogger,\n private readonly getLongClientId: (id: number) => string,\n public filename?: string,\n public onCompletion?: () => void,\n ) {\n this.logger = ChildLogger.create(logger, \"Snapshot\");\n this.chunkSize = mergeTree?.options?.mergeTreeSnapshotChunkSize ?? SnapshotV1.chunkSize;\n\n const { currentSeq, minSeq } = mergeTree.getCollabWindow();\n this.header = {\n minSequenceNumber: minSeq,\n sequenceNumber: currentSeq,\n orderedChunkMetadata: [],\n totalLength: 0,\n totalSegmentCount: 0,\n };\n\n this.segments = [];\n this.segmentLengths = [];\n }\n\n private getSeqLengthSegs(\n allSegments: JsonSegmentSpecs[],\n allLengths: number[],\n approxSequenceLength: number,\n startIndex = 0): MergeTreeChunkV1 {\n const segments: JsonSegmentSpecs[] = [];\n let length = 0;\n let segmentCount = 0;\n while ((length < approxSequenceLength) && ((startIndex + segmentCount) < allSegments.length)) {\n const pseg = allSegments[startIndex + segmentCount];\n segments.push(pseg);\n length += allLengths[startIndex + segmentCount];\n segmentCount++;\n }\n return {\n version: \"1\",\n segmentCount,\n length,\n segments,\n startIndex,\n headerMetadata: undefined,\n };\n }\n\n /**\n * Emits the snapshot to an ISummarizeResult. If provided the optional IFluidSerializer will be used when\n * serializing the summary data rather than JSON.stringify.\n */\n emit(\n serializer: IFluidSerializer,\n bind: IFluidHandle,\n ): ISummaryTreeWithStats {\n const chunks: MergeTreeChunkV1[] = [];\n this.header.totalSegmentCount = 0;\n this.header.totalLength = 0;\n do {\n const chunk = this.getSeqLengthSegs(\n this.segments,\n this.segmentLengths,\n this.chunkSize,\n this.header.totalSegmentCount);\n chunks.push(chunk);\n this.header.totalSegmentCount += chunk.segmentCount;\n this.header.totalLength += chunk.length;\n } while (this.header.totalSegmentCount < this.segments.length);\n\n // The do while loop should have added at least one chunk\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const headerChunk = chunks.shift()!;\n headerChunk.headerMetadata = this.header;\n headerChunk.headerMetadata.orderedChunkMetadata = [{ id: SnapshotLegacy.header }];\n const blobs: [key: string, content: string][] = [];\n chunks.forEach((chunk, index) => {\n const id = `${SnapshotLegacy.body}_${index}`;\n this.header.orderedChunkMetadata.push({ id });\n blobs.push([id, serializeAsMaxSupportedVersion(\n id,\n chunk,\n this.logger,\n this.mergeTree.options,\n serializer,\n bind)]);\n });\n\n const builder = new SummaryTreeBuilder();\n builder.addBlob(SnapshotLegacy.header, serializeAsMaxSupportedVersion(\n SnapshotLegacy.header,\n headerChunk,\n this.logger,\n this.mergeTree.options,\n serializer,\n bind));\n blobs.forEach((value) => {\n builder.addBlob(value[0], value[1]);\n });\n\n return builder.getSummaryTree();\n }\n\n extractSync() {\n const mergeTree = this.mergeTree;\n const minSeq = this.header.minSequenceNumber;\n\n // Helper to add the given `MergeTreeChunkV0SegmentSpec` to the snapshot.\n const pushSegRaw = (json: JsonSegmentSpecs, length: number) => {\n this.segments.push(json);\n this.segmentLengths.push(length);\n };\n\n // Helper to serialize the given `segment` and add it to the snapshot (if a segment is provided).\n const pushSeg = (segment?: ISegment) => {\n if (segment) { pushSegRaw(segment.toJSONObject(), segment.cachedLength); }\n };\n\n let prev: ISegment | undefined;\n const extractSegment = (segment: ISegment) => {\n // Elide segments that do not need to be included in the snapshot. A segment may be elided if\n // either condition is true:\n // a) The segment has not yet been ACKed. We do not need to snapshot unACKed segments because\n // there is a pending insert op that will deliver the segment on reconnection.\n // b) The segment was removed at or below the MSN. Pending ops can no longer reference this\n // segment, and therefore we can discard it.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (segment.seq === UnassignedSequenceNumber || segment.removedSeq! <= minSeq) {\n return true;\n }\n\n // Next determine if the snapshot needs to preserve information required for merging the segment\n // (seq, client, etc.) This information is only needed if the segment is above the MSN (and doesn't\n // have a pending remove.)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if ((segment.seq! <= minSeq) // Segment is below the MSN, and...\n && (segment.removedSeq === undefined // .. Segment has not been removed, or...\n || segment.removedSeq === UnassignedSequenceNumber) // .. Removal op to be delivered on reconnect\n ) {\n // This segment is below the MSN, which means that future ops will not reference it. Attempt to\n // coalesce the new segment with the previous (if any).\n if (!prev) {\n // We do not have a previous candidate for coalescing. Make the current segment the new candidate.\n prev = segment;\n } else if (prev.canAppend(segment) && matchProperties(prev.properties, segment.properties)) {\n // We have a compatible pair. Replace `prev` with the coalesced segment. Clone to avoid\n // modifying the segment instances currently in the MergeTree.\n prev = prev.clone();\n prev.append(segment.clone());\n } else {\n // The segment pair could not be coalesced. Record the `prev` segment in the snapshot\n // and make the current segment the new candidate for coalescing.\n pushSeg(prev);\n prev = segment;\n }\n } else {\n // This segment needs to preserve it's metadata as it may be referenced by future ops. It's ineligible\n // for coalescing, so emit the 'prev' segment now (if any).\n pushSeg(prev);\n prev = undefined;\n\n const raw: IJSONSegmentWithMergeInfo = { json: segment.toJSONObject() };\n // If the segment insertion is above the MSN, record the insertion merge info.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (segment.seq! > minSeq) {\n raw.seq = segment.seq;\n raw.client = this.getLongClientId(segment.clientId);\n }\n // We have already dispensed with removed segments below the MSN and removed segments with unassigned\n // sequence numbers. Any remaining removal info should be preserved.\n if (segment.removedSeq !== undefined) {\n assert(segment.removedSeq !== UnassignedSequenceNumber && segment.removedSeq > minSeq,\n 0x065 /* \"On removal info preservation, segment has invalid removed sequence number!\" */);\n raw.removedSeq = segment.removedSeq;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n raw.removedClient = this.getLongClientId(segment.removedClientId!);\n }\n\n // Sanity check that we are preserving either the seq < minSeq or a removed segment's info.\n assert(raw.seq !== undefined && raw.client !== undefined\n || raw.removedSeq !== undefined && raw.removedClient !== undefined,\n 0x066 /* \"Corrupted preservation of segment metadata!\" */);\n\n // Record the segment with it's required metadata.\n pushSegRaw(raw, segment.cachedLength);\n }\n return true;\n };\n\n mergeTree.walkAllSegments(mergeTree.root, extractSegment, this);\n\n // If the last segment in the walk was coalescable, push it now.\n pushSeg(prev);\n\n return this.segments;\n }\n\n public static async loadChunk(\n storage: IChannelStorageService,\n path: string,\n logger: ITelemetryLogger,\n options: PropertySet | undefined,\n serializer?: IFluidSerializer,\n ): Promise<MergeTreeChunkV1> {\n const blob = await storage.readBlob(path);\n const chunkAsString = bufferToString(blob, \"utf8\");\n return SnapshotV1.processChunk(path, chunkAsString, logger, options, serializer);\n }\n\n public static processChunk(\n path: string,\n chunk: string,\n logger: ITelemetryLogger,\n options: PropertySet | undefined,\n serializer?: IFluidSerializer,\n ): MergeTreeChunkV1 {\n const chunkObj = serializer ? serializer.parse(chunk) : JSON.parse(chunk);\n return toLatestVersion(path, chunkObj, logger, options);\n }\n}\n"]}
1
+ {"version":3,"file":"snapshotV1.js","sourceRoot":"","sources":["../src/snapshotV1.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 { ITelemetryLogger } from \"@fluidframework/common-definitions\";\nimport { IFluidHandle } from \"@fluidframework/core-interfaces\";\nimport { IFluidSerializer } from \"@fluidframework/shared-object-base\";\nimport { assert, bufferToString } from \"@fluidframework/common-utils\";\nimport { ChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { IChannelStorageService } from \"@fluidframework/datastore-definitions\";\nimport { ISummaryTreeWithStats } from \"@fluidframework/runtime-definitions\";\nimport { SummaryTreeBuilder } from \"@fluidframework/runtime-utils\";\nimport { UnassignedSequenceNumber } from \"./constants\";\nimport {\n ISegment,\n MergeTree,\n} from \"./mergeTree\";\nimport {\n matchProperties,\n PropertySet,\n} from \"./properties\";\nimport {\n IJSONSegmentWithMergeInfo,\n JsonSegmentSpecs,\n MergeTreeHeaderMetadata,\n MergeTreeChunkV1,\n toLatestVersion,\n serializeAsMaxSupportedVersion,\n} from \"./snapshotChunks\";\nimport { SnapshotLegacy } from \"./snapshotlegacy\";\n\nexport class SnapshotV1 {\n // Split snapshot into two entries - headers (small) and body (overflow) for faster loading initial content\n // Please note that this number has no direct relationship to anything other than size of raw text (characters).\n // As we produce json for the blob (and then send over the wire compressed), this number\n // is really hard to correlate with any actual metric that matters (like bytes over the wire).\n // For test with small number of chunks it would be closer to blob size,\n // for very chunky text, blob size can easily be 4x-8x of that number.\n public static readonly chunkSize: number = 10000;\n\n private readonly header: MergeTreeHeaderMetadata;\n private readonly segments: JsonSegmentSpecs[];\n private readonly segmentLengths: number[];\n private readonly logger: ITelemetryLogger;\n private readonly chunkSize: number;\n\n constructor(\n public mergeTree: MergeTree,\n logger: ITelemetryLogger,\n private readonly getLongClientId: (id: number) => string,\n public filename?: string,\n public onCompletion?: () => void,\n ) {\n this.logger = ChildLogger.create(logger, \"Snapshot\");\n this.chunkSize = mergeTree?.options?.mergeTreeSnapshotChunkSize ?? SnapshotV1.chunkSize;\n\n const { currentSeq, minSeq } = mergeTree.getCollabWindow();\n this.header = {\n minSequenceNumber: minSeq,\n sequenceNumber: currentSeq,\n orderedChunkMetadata: [],\n totalLength: 0,\n totalSegmentCount: 0,\n };\n\n this.segments = [];\n this.segmentLengths = [];\n }\n\n private getSeqLengthSegs(\n allSegments: JsonSegmentSpecs[],\n allLengths: number[],\n approxSequenceLength: number,\n startIndex = 0): MergeTreeChunkV1 {\n const segments: JsonSegmentSpecs[] = [];\n let length = 0;\n let segmentCount = 0;\n while ((length < approxSequenceLength) && ((startIndex + segmentCount) < allSegments.length)) {\n const pseg = allSegments[startIndex + segmentCount];\n segments.push(pseg);\n length += allLengths[startIndex + segmentCount];\n segmentCount++;\n }\n return {\n version: \"1\",\n segmentCount,\n length,\n segments,\n startIndex,\n headerMetadata: undefined,\n };\n }\n\n /**\n * Emits the snapshot to an ISummarizeResult. If provided the optional IFluidSerializer will be used when\n * serializing the summary data rather than JSON.stringify.\n */\n emit(\n serializer: IFluidSerializer,\n bind: IFluidHandle,\n ): ISummaryTreeWithStats {\n const chunks: MergeTreeChunkV1[] = [];\n this.header.totalSegmentCount = 0;\n this.header.totalLength = 0;\n do {\n const chunk = this.getSeqLengthSegs(\n this.segments,\n this.segmentLengths,\n this.chunkSize,\n this.header.totalSegmentCount);\n chunks.push(chunk);\n this.header.totalSegmentCount += chunk.segmentCount;\n this.header.totalLength += chunk.length;\n } while (this.header.totalSegmentCount < this.segments.length);\n\n // The do while loop should have added at least one chunk\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const headerChunk = chunks.shift()!;\n headerChunk.headerMetadata = this.header;\n headerChunk.headerMetadata.orderedChunkMetadata = [{ id: SnapshotLegacy.header }];\n const blobs: [key: string, content: string][] = [];\n chunks.forEach((chunk, index) => {\n const id = `${SnapshotLegacy.body}_${index}`;\n this.header.orderedChunkMetadata.push({ id });\n blobs.push([id, serializeAsMaxSupportedVersion(\n id,\n chunk,\n this.logger,\n this.mergeTree.options,\n serializer,\n bind)]);\n });\n\n const builder = new SummaryTreeBuilder();\n builder.addBlob(SnapshotLegacy.header, serializeAsMaxSupportedVersion(\n SnapshotLegacy.header,\n headerChunk,\n this.logger,\n this.mergeTree.options,\n serializer,\n bind));\n blobs.forEach((value) => {\n builder.addBlob(value[0], value[1]);\n });\n\n return builder.getSummaryTree();\n }\n\n extractSync() {\n const mergeTree = this.mergeTree;\n const minSeq = this.header.minSequenceNumber;\n\n // Helper to add the given `MergeTreeChunkV0SegmentSpec` to the snapshot.\n const pushSegRaw = (json: JsonSegmentSpecs, length: number) => {\n this.segments.push(json);\n this.segmentLengths.push(length);\n };\n\n // Helper to serialize the given `segment` and add it to the snapshot (if a segment is provided).\n const pushSeg = (segment?: ISegment) => {\n if (segment) { pushSegRaw(segment.toJSONObject(), segment.cachedLength); }\n };\n\n let prev: ISegment | undefined;\n const extractSegment = (segment: ISegment) => {\n // Elide segments that do not need to be included in the snapshot. A segment may be elided if\n // either condition is true:\n // a) The segment has not yet been ACKed. We do not need to snapshot unACKed segments because\n // there is a pending insert op that will deliver the segment on reconnection.\n // b) The segment was removed at or below the MSN. Pending ops can no longer reference this\n // segment, and therefore we can discard it.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (segment.seq === UnassignedSequenceNumber || segment.removedSeq! <= minSeq) {\n return true;\n }\n\n // Next determine if the snapshot needs to preserve information required for merging the segment\n // (seq, client, etc.) This information is only needed if the segment is above the MSN (and doesn't\n // have a pending remove.)\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if ((segment.seq! <= minSeq) // Segment is below the MSN, and...\n && (segment.removedSeq === undefined // .. Segment has not been removed, or...\n || segment.removedSeq === UnassignedSequenceNumber) // .. Removal op to be delivered on reconnect\n ) {\n // This segment is below the MSN, which means that future ops will not reference it. Attempt to\n // coalesce the new segment with the previous (if any).\n if (!prev) {\n // We do not have a previous candidate for coalescing. Make the current segment the new candidate.\n prev = segment;\n } else if (prev.canAppend(segment) && matchProperties(prev.properties, segment.properties)) {\n // We have a compatible pair. Replace `prev` with the coalesced segment. Clone to avoid\n // modifying the segment instances currently in the MergeTree.\n prev = prev.clone();\n prev.append(segment.clone());\n } else {\n // The segment pair could not be coalesced. Record the `prev` segment in the snapshot\n // and make the current segment the new candidate for coalescing.\n pushSeg(prev);\n prev = segment;\n }\n } else {\n // This segment needs to preserve it's metadata as it may be referenced by future ops. It's ineligible\n // for coalescing, so emit the 'prev' segment now (if any).\n pushSeg(prev);\n prev = undefined;\n\n const raw: IJSONSegmentWithMergeInfo = { json: segment.toJSONObject() };\n // If the segment insertion is above the MSN, record the insertion merge info.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n if (segment.seq! > minSeq) {\n raw.seq = segment.seq;\n raw.client = this.getLongClientId(segment.clientId);\n }\n // We have already dispensed with removed segments below the MSN and removed segments with unassigned\n // sequence numbers. Any remaining removal info should be preserved.\n if (segment.removedSeq !== undefined) {\n assert(segment.removedSeq !== UnassignedSequenceNumber && segment.removedSeq > minSeq,\n 0x065 /* \"On removal info preservation, segment has invalid removed sequence number!\" */);\n raw.removedSeq = segment.removedSeq;\n\n // back compat for when we split overlap and removed client\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n raw.removedClient = this.getLongClientId(segment.removedClientId!);\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const removedClientIds = [segment.removedClientId!];\n if(segment.removedClientOverlap !== undefined) {\n removedClientIds.push(... segment.removedClientOverlap);\n }\n raw.removedClientIds = removedClientIds.map((id)=>this.getLongClientId(id));\n }\n\n // Sanity check that we are preserving either the seq < minSeq or a removed segment's info.\n assert(raw.seq !== undefined && raw.client !== undefined\n || raw.removedSeq !== undefined && raw.removedClient !== undefined,\n 0x066 /* \"Corrupted preservation of segment metadata!\" */);\n\n // Record the segment with it's required metadata.\n pushSegRaw(raw, segment.cachedLength);\n }\n return true;\n };\n\n mergeTree.walkAllSegments(mergeTree.root, extractSegment, this);\n\n // If the last segment in the walk was coalescable, push it now.\n pushSeg(prev);\n\n return this.segments;\n }\n\n public static async loadChunk(\n storage: IChannelStorageService,\n path: string,\n logger: ITelemetryLogger,\n options: PropertySet | undefined,\n serializer?: IFluidSerializer,\n ): Promise<MergeTreeChunkV1> {\n const blob = await storage.readBlob(path);\n const chunkAsString = bufferToString(blob, \"utf8\");\n return SnapshotV1.processChunk(path, chunkAsString, logger, options, serializer);\n }\n\n public static processChunk(\n path: string,\n chunk: string,\n logger: ITelemetryLogger,\n options: PropertySet | undefined,\n serializer?: IFluidSerializer,\n ): MergeTreeChunkV1 {\n const chunkObj = serializer ? serializer.parse(chunk) : JSON.parse(chunk);\n return toLatestVersion(path, chunkObj, logger, options);\n }\n}\n"]}