@fluidframework/merge-tree 0.57.0 → 0.58.0-55983
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.
- package/dist/base.d.ts +0 -1
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js.map +1 -1
- package/dist/client.d.ts +3 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +14 -36
- package/dist/client.js.map +1 -1
- package/dist/collections.d.ts +1 -4
- package/dist/collections.d.ts.map +1 -1
- package/dist/collections.js +8 -24
- package/dist/collections.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/mergeTree.d.ts +8 -30
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +17 -326
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/dist/mergeTreeDeltaCallback.js.map +1 -1
- package/dist/ops.d.ts +0 -6
- package/dist/ops.d.ts.map +1 -1
- package/dist/ops.js +1 -8
- package/dist/ops.js.map +1 -1
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +14 -26
- package/dist/partialLengths.js.map +1 -1
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +2 -15
- package/dist/properties.js.map +1 -1
- package/dist/segmentPropertiesManager.js +1 -5
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotChunks.js +3 -3
- package/dist/snapshotChunks.js.map +1 -1
- package/dist/snapshotV1.d.ts +2 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js +4 -4
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +3 -6
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts +3 -3
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js +12 -12
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/textSegment.d.ts.map +1 -1
- package/dist/textSegment.js +3 -17
- package/dist/textSegment.js.map +1 -1
- package/lib/base.d.ts +0 -1
- package/lib/base.d.ts.map +1 -1
- package/lib/base.js.map +1 -1
- package/lib/client.d.ts +3 -5
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +11 -33
- package/lib/client.js.map +1 -1
- package/lib/collections.d.ts +1 -4
- package/lib/collections.d.ts.map +1 -1
- package/lib/collections.js +8 -24
- package/lib/collections.js.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/mergeTree.d.ts +8 -30
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +16 -322
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/lib/mergeTreeDeltaCallback.js.map +1 -1
- package/lib/ops.d.ts +0 -6
- package/lib/ops.d.ts.map +1 -1
- package/lib/ops.js +0 -7
- package/lib/ops.js.map +1 -1
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +14 -26
- package/lib/partialLengths.js.map +1 -1
- package/lib/properties.d.ts.map +1 -1
- package/lib/properties.js +2 -15
- package/lib/properties.js.map +1 -1
- package/lib/segmentPropertiesManager.js +1 -5
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotChunks.js +3 -3
- package/lib/snapshotChunks.js.map +1 -1
- package/lib/snapshotV1.d.ts +2 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js +4 -4
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +3 -6
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts +3 -3
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js +12 -12
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/textSegment.d.ts.map +1 -1
- package/lib/textSegment.js +4 -18
- package/lib/textSegment.js.map +1 -1
- package/package.json +11 -11
- package/src/base.ts +2 -3
- package/src/client.ts +11 -36
- package/src/collections.ts +9 -26
- package/src/index.ts +0 -1
- package/src/mergeTree.ts +32 -357
- package/src/mergeTreeDeltaCallback.ts +0 -1
- package/src/ops.ts +0 -7
- package/src/partialLengths.ts +17 -27
- package/src/properties.ts +7 -15
- package/src/segmentPropertiesManager.ts +5 -5
- package/src/snapshotChunks.ts +3 -3
- package/src/snapshotV1.ts +3 -3
- package/src/snapshotlegacy.ts +4 -6
- package/src/sortedSegmentSet.ts +12 -12
- package/src/textSegment.ts +5 -20
- package/dist/text.d.ts +0 -8
- package/dist/text.d.ts.map +0 -1
- package/dist/text.js +0 -78
- package/dist/text.js.map +0 -1
- package/lib/text.d.ts +0 -8
- package/lib/text.d.ts.map +0 -1
- package/lib/text.js +0 -73
- package/lib/text.js.map +0 -1
- package/src/text.ts +0 -83
package/dist/mergeTree.js
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
exports.MergeTree = exports.glc = exports.clientSeqComparer = exports.internedSpaces = exports.elapsedMicroseconds = exports.clock = exports.compareStrings = exports.compareNumbers = exports.CollaborationWindow = exports.IncrementalMapState = exports.IncrementalExecOp = exports.Marker = exports.refHasRangeLabel = exports.refHasTileLabel = exports.refGetRangeLabels = exports.refGetTileLabels = exports.reservedMarkerSimpleTypeKey = exports.reservedMarkerIdKey = exports.reservedRangeLabelsKey = exports.reservedTileLabelsKey = exports.BaseSegment = exports.MergeBlock = exports.MaxNodesInBlock = exports.ordinalToArray = exports.MergeNode = void 0;
|
|
6
|
+
/* eslint-disable max-lines */
|
|
8
7
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
9
8
|
/* eslint-disable @typescript-eslint/consistent-type-assertions */
|
|
10
|
-
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.MergeTree = exports.clientSeqComparer = exports.internedSpaces = exports.compareStrings = exports.compareNumbers = exports.CollaborationWindow = exports.IncrementalMapState = exports.IncrementalExecOp = exports.Marker = exports.refHasRangeLabel = exports.refHasTileLabel = exports.refGetRangeLabels = exports.refGetTileLabels = exports.reservedMarkerSimpleTypeKey = exports.reservedMarkerIdKey = exports.reservedRangeLabelsKey = exports.reservedTileLabelsKey = exports.BaseSegment = exports.MergeBlock = exports.MaxNodesInBlock = exports.ordinalToArray = exports.MergeNode = void 0;
|
|
11
11
|
/* eslint-disable no-bitwise */
|
|
12
12
|
const common_utils_1 = require("@fluidframework/common-utils");
|
|
13
13
|
const collections_1 = require("./collections");
|
|
@@ -30,7 +30,6 @@ class MergeNode {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
exports.MergeNode = MergeNode;
|
|
33
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
34
33
|
function addTile(tile, tiles) {
|
|
35
34
|
const tileLabels = tile.getTileLabels();
|
|
36
35
|
if (tileLabels) {
|
|
@@ -39,7 +38,6 @@ function addTile(tile, tiles) {
|
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
43
41
|
function addTileIfNotPresent(tile, tiles) {
|
|
44
42
|
const tileLabels = tile.getTileLabels();
|
|
45
43
|
if (tileLabels) {
|
|
@@ -51,7 +49,7 @@ function addTileIfNotPresent(tile, tiles) {
|
|
|
51
49
|
}
|
|
52
50
|
}
|
|
53
51
|
function applyStackDelta(currentStackMap, deltaStackMap) {
|
|
54
|
-
// eslint-disable-next-line guard-for-in
|
|
52
|
+
// eslint-disable-next-line guard-for-in
|
|
55
53
|
for (const label in deltaStackMap) {
|
|
56
54
|
const deltaStack = deltaStackMap[label];
|
|
57
55
|
if (!deltaStack.empty()) {
|
|
@@ -158,7 +156,6 @@ exports.ordinalToArray = ordinalToArray;
|
|
|
158
156
|
// `MaxNodesInBlock`. (i.e., `MaxNodesInBlock` contains 1 extra slot for temporary storage to
|
|
159
157
|
// facilitate splits.)
|
|
160
158
|
exports.MaxNodesInBlock = 8;
|
|
161
|
-
const traceOrdinals = false;
|
|
162
159
|
class MergeBlock extends MergeNode {
|
|
163
160
|
constructor(childCount) {
|
|
164
161
|
super();
|
|
@@ -185,16 +182,9 @@ class MergeBlock extends MergeNode {
|
|
|
185
182
|
localOrdinal = prevOrdCode + ordinalWidth;
|
|
186
183
|
}
|
|
187
184
|
child.ordinal = this.ordinal + String.fromCharCode(localOrdinal);
|
|
188
|
-
if (traceOrdinals) {
|
|
189
|
-
// eslint-disable-next-line max-len
|
|
190
|
-
console.log(`so: prnt chld prev ${ordinalToArray(this.ordinal)} ${ordinalToArray(child.ordinal)} ${(index > 0) ? ordinalToArray(this.children[index - 1].ordinal) : "NA"}`);
|
|
191
|
-
}
|
|
192
185
|
common_utils_1.assert(child.ordinal.length === (this.ordinal.length + 1), 0x041 /* "Unexpected child ordinal length!" */);
|
|
193
186
|
if (index > 0) {
|
|
194
187
|
common_utils_1.assert(child.ordinal > this.children[index - 1].ordinal, 0x042);
|
|
195
|
-
// eslint-disable-next-line max-len
|
|
196
|
-
// console.log(`${ordinalToArray(this.ordinal)} ${ordinalToArray(child.ordinal)} ${ordinalToArray(this.children[index - 1].ordinal)}`);
|
|
197
|
-
// console.log(`ord width ${ordinalWidth}`);
|
|
198
188
|
}
|
|
199
189
|
}
|
|
200
190
|
assignChild(child, index, updateOrdinal = true) {
|
|
@@ -222,7 +212,7 @@ class HierMergeBlock extends MergeBlock {
|
|
|
222
212
|
}
|
|
223
213
|
hierToString(indentCount) {
|
|
224
214
|
let strbuf = "";
|
|
225
|
-
// eslint-disable-next-line guard-for-in
|
|
215
|
+
// eslint-disable-next-line guard-for-in
|
|
226
216
|
for (const key in this.rangeStacks) {
|
|
227
217
|
const stack = this.rangeStacks[key];
|
|
228
218
|
strbuf += internedSpaces(indentCount);
|
|
@@ -295,7 +285,6 @@ class BaseSegment extends MergeNode {
|
|
|
295
285
|
this.localSeq = undefined;
|
|
296
286
|
return true;
|
|
297
287
|
case 1 /* REMOVE */:
|
|
298
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
299
288
|
const removalInfo = this;
|
|
300
289
|
common_utils_1.assert(!!removalInfo, 0x046 /* "On remove ack, missing removal info!" */);
|
|
301
290
|
common_utils_1.assert(!!removalInfo.removedSeq, 0x047 /* "On remove ack, missing removed sequence number!" */);
|
|
@@ -304,11 +293,6 @@ class BaseSegment extends MergeNode {
|
|
|
304
293
|
removalInfo.removedSeq = opArgs.sequencedMessage.sequenceNumber;
|
|
305
294
|
return true;
|
|
306
295
|
}
|
|
307
|
-
if (MergeTree.diagOverlappingRemove) {
|
|
308
|
-
console.log(`grump @seq ${opArgs.sequencedMessage.sequenceNumber} ` +
|
|
309
|
-
`cli ${glc(mergeTree, mergeTree.collabWindow.clientId)} ` +
|
|
310
|
-
`from ${removalInfo.removedSeq} text ${mergeTree.toString()}`);
|
|
311
|
-
}
|
|
312
296
|
return false;
|
|
313
297
|
default:
|
|
314
298
|
throw new Error(`${opArgs.op.type} is in unrecognized operation type`);
|
|
@@ -513,7 +497,6 @@ class Marker extends BaseSegment {
|
|
|
513
497
|
// Avoid circular reference when stringifying makers containing handles.
|
|
514
498
|
// (Substitute a debug string instead.)
|
|
515
499
|
const handle = !!value && value.IFluidHandle;
|
|
516
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
517
500
|
return handle
|
|
518
501
|
? `#Handle(${handle.routeContext.path}/${handle.path})`
|
|
519
502
|
: value;
|
|
@@ -575,14 +558,6 @@ const compareNumbers = (a, b) => a - b;
|
|
|
575
558
|
exports.compareNumbers = compareNumbers;
|
|
576
559
|
const compareStrings = (a, b) => a.localeCompare(b);
|
|
577
560
|
exports.compareStrings = compareStrings;
|
|
578
|
-
function clock() {
|
|
579
|
-
return common_utils_1.Trace.start();
|
|
580
|
-
}
|
|
581
|
-
exports.clock = clock;
|
|
582
|
-
function elapsedMicroseconds(trace) {
|
|
583
|
-
return trace.trace().duration * 1000;
|
|
584
|
-
}
|
|
585
|
-
exports.elapsedMicroseconds = elapsedMicroseconds;
|
|
586
561
|
const indentStrings = ["", " ", " "];
|
|
587
562
|
function internedSpaces(n) {
|
|
588
563
|
if (indentStrings[n] === undefined) {
|
|
@@ -602,15 +577,6 @@ const LRUSegmentComparer = {
|
|
|
602
577
|
min: { maxSeq: -2 },
|
|
603
578
|
compare: (a, b) => a.maxSeq - b.maxSeq,
|
|
604
579
|
};
|
|
605
|
-
function glc(mergeTree, id) {
|
|
606
|
-
if (mergeTree.getLongClientId) {
|
|
607
|
-
return mergeTree.getLongClientId(id);
|
|
608
|
-
}
|
|
609
|
-
else {
|
|
610
|
-
return id.toString();
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
exports.glc = glc;
|
|
614
580
|
function applyLeafRangeMarker(marker, searchInfo) {
|
|
615
581
|
for (const rangeLabel of searchInfo.rangeLabels) {
|
|
616
582
|
if (marker.hasRangeLabel(rangeLabel)) {
|
|
@@ -690,10 +656,6 @@ class MergeTree {
|
|
|
690
656
|
// TODO: make and use interface describing options
|
|
691
657
|
constructor(options) {
|
|
692
658
|
this.options = options;
|
|
693
|
-
this.windowTime = 0;
|
|
694
|
-
this.packTime = 0;
|
|
695
|
-
this.ordTime = 0;
|
|
696
|
-
this.maxOrdTime = 0;
|
|
697
659
|
this.blockUpdateActions = MergeTree.initBlockUpdateActions;
|
|
698
660
|
this.collabWindow = new CollaborationWindow();
|
|
699
661
|
// TODO: add remove on segment remove
|
|
@@ -777,7 +739,6 @@ class MergeTree {
|
|
|
777
739
|
// This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
|
|
778
740
|
common_utils_1.assert(!this.collabWindow.collaborating, 0x049 /* "Trying to reload from segments while collaborating!" */);
|
|
779
741
|
const maxChildren = exports.MaxNodesInBlock - 1;
|
|
780
|
-
const measureReloadTime = false;
|
|
781
742
|
// Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
|
|
782
743
|
const buildMergeBlock = (nodes) => {
|
|
783
744
|
const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
|
|
@@ -801,15 +762,10 @@ class MergeTree {
|
|
|
801
762
|
// snapshot header. The bulk of the segments in long documents are inserted via `insertSegments()`.
|
|
802
763
|
this.blockUpdate(block);
|
|
803
764
|
}
|
|
804
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
805
765
|
return blocks.length === 1 // If there is only one block at this layer...
|
|
806
766
|
? blocks[0] // ...then we're done. Return the root.
|
|
807
767
|
: buildMergeBlock(blocks); // ...otherwise recursively build the next layer above blocks.
|
|
808
768
|
};
|
|
809
|
-
let clockStart;
|
|
810
|
-
if (measureReloadTime) {
|
|
811
|
-
clockStart = clock();
|
|
812
|
-
}
|
|
813
769
|
if (segments.length > 0) {
|
|
814
770
|
this.root = buildMergeBlock(segments);
|
|
815
771
|
this.nodeUpdateOrdinals(this.root);
|
|
@@ -817,9 +773,6 @@ class MergeTree {
|
|
|
817
773
|
else {
|
|
818
774
|
this.root = this.makeBlock(0);
|
|
819
775
|
}
|
|
820
|
-
if (clockStart) {
|
|
821
|
-
console.log(`reload time ${elapsedMicroseconds(clockStart)}`);
|
|
822
|
-
}
|
|
823
776
|
}
|
|
824
777
|
/* eslint-enable max-len */
|
|
825
778
|
// For now assume min starts at zero
|
|
@@ -830,15 +783,7 @@ class MergeTree {
|
|
|
830
783
|
this.collabWindow.currentSeq = currentSeq;
|
|
831
784
|
this.segmentsToScour = new collections_1.Heap([], LRUSegmentComparer);
|
|
832
785
|
this.pendingSegments = collections_1.ListMakeHead();
|
|
833
|
-
const measureFullCollab = false;
|
|
834
|
-
let clockStart;
|
|
835
|
-
if (measureFullCollab) {
|
|
836
|
-
clockStart = clock();
|
|
837
|
-
}
|
|
838
786
|
this.nodeUpdateLengthNewStructure(this.root, true);
|
|
839
|
-
if (clockStart) {
|
|
840
|
-
console.log(`update partial lengths at start ${elapsedMicroseconds(clockStart)}`);
|
|
841
|
-
}
|
|
842
787
|
}
|
|
843
788
|
addToLRUSet(segment, seq) {
|
|
844
789
|
// If the parent node has not yet been marked for scour (i.e., needsScour is not false or undefined),
|
|
@@ -868,10 +813,6 @@ class MergeTree {
|
|
|
868
813
|
holdNodes.push(segment);
|
|
869
814
|
}
|
|
870
815
|
else {
|
|
871
|
-
if (MergeTree.traceZRemove) {
|
|
872
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation, max-len
|
|
873
|
-
console.log(`${this.getLongClientId(this.collabWindow.clientId)}: Zremove ${segment["text"]}; cli ${this.getLongClientId(segment.clientId)}`);
|
|
874
|
-
}
|
|
875
816
|
// Notify maintenance event observers that the segment is being unlinked from the MergeTree
|
|
876
817
|
if (this.mergeTreeMaintenanceCallback) {
|
|
877
818
|
this.mergeTreeMaintenanceCallback({
|
|
@@ -891,10 +832,6 @@ class MergeTree {
|
|
|
891
832
|
&& prevSegment.trackingCollection.matches(segment.trackingCollection)
|
|
892
833
|
&& this.localNetLength(segment) > 0;
|
|
893
834
|
if (canAppend) {
|
|
894
|
-
if (MergeTree.traceAppend) {
|
|
895
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation, max-len
|
|
896
|
-
console.log(`${this.getLongClientId(this.collabWindow.clientId)}: append ${prevSegment["text"]} + ${segment["text"]}; cli ${this.getLongClientId(prevSegment.clientId)} + cli ${this.getLongClientId(segment.clientId)}`);
|
|
897
|
-
}
|
|
898
835
|
prevSegment.append(segment);
|
|
899
836
|
if (this.mergeTreeMaintenanceCallback) {
|
|
900
837
|
this.mergeTreeMaintenanceCallback({
|
|
@@ -970,9 +907,6 @@ class MergeTree {
|
|
|
970
907
|
packedBlocks[nodeIndex] = packedBlock;
|
|
971
908
|
this.nodeUpdateLengthNewStructure(packedBlock);
|
|
972
909
|
}
|
|
973
|
-
if (readCount !== totalNodeCount) {
|
|
974
|
-
console.log(`total count ${totalNodeCount} readCount ${readCount}`);
|
|
975
|
-
}
|
|
976
910
|
parent.children = packedBlocks;
|
|
977
911
|
for (let j = 0; j < childCount; j++) {
|
|
978
912
|
parent.assignChild(packedBlocks[j], j, false);
|
|
@@ -990,10 +924,6 @@ class MergeTree {
|
|
|
990
924
|
if (!this.collabWindow.collaborating) {
|
|
991
925
|
return;
|
|
992
926
|
}
|
|
993
|
-
let clockStart;
|
|
994
|
-
if (MergeTree.options.measureWindowTime) {
|
|
995
|
-
clockStart = clock();
|
|
996
|
-
}
|
|
997
927
|
for (let i = 0; i < zamboniSegmentsMaxCount; i++) {
|
|
998
928
|
let segmentToScour = this.segmentsToScour.peek();
|
|
999
929
|
if (!segmentToScour || segmentToScour.maxSeq > this.collabWindow.minSeq) {
|
|
@@ -1004,7 +934,6 @@ class MergeTree {
|
|
|
1004
934
|
if (segmentToScour.segment.parent && segmentToScour.segment.parent.needsScour !== false) {
|
|
1005
935
|
const block = segmentToScour.segment.parent;
|
|
1006
936
|
const childrenCopy = [];
|
|
1007
|
-
// console.log(`scouring from ${segmentToScour.segment.seq}`);
|
|
1008
937
|
this.scourNode(block, childrenCopy);
|
|
1009
938
|
// This will avoid the cost of re-scouring nodes
|
|
1010
939
|
// that have recently been scoured
|
|
@@ -1017,15 +946,7 @@ class MergeTree {
|
|
|
1017
946
|
block.assignChild(childrenCopy[j], j, false);
|
|
1018
947
|
}
|
|
1019
948
|
if (this.underflow(block) && block.parent) {
|
|
1020
|
-
// nodeUpdatePathLengths(node, UnassignedSequenceNumber, -1, true);
|
|
1021
|
-
let packClockStart;
|
|
1022
|
-
if (MergeTree.options.measureWindowTime) {
|
|
1023
|
-
packClockStart = clock();
|
|
1024
|
-
}
|
|
1025
949
|
this.packParent(block.parent);
|
|
1026
|
-
if (MergeTree.options.measureWindowTime) {
|
|
1027
|
-
this.packTime += elapsedMicroseconds(packClockStart);
|
|
1028
|
-
}
|
|
1029
950
|
}
|
|
1030
951
|
else {
|
|
1031
952
|
this.nodeUpdateOrdinals(block);
|
|
@@ -1034,9 +955,6 @@ class MergeTree {
|
|
|
1034
955
|
}
|
|
1035
956
|
}
|
|
1036
957
|
}
|
|
1037
|
-
if (MergeTree.options.measureWindowTime) {
|
|
1038
|
-
this.windowTime += elapsedMicroseconds(clockStart);
|
|
1039
|
-
}
|
|
1040
958
|
}
|
|
1041
959
|
getCollabWindow() {
|
|
1042
960
|
return this.collabWindow;
|
|
@@ -1085,56 +1003,8 @@ class MergeTree {
|
|
|
1085
1003
|
return stats;
|
|
1086
1004
|
};
|
|
1087
1005
|
const rootStats = nodeGetStats(this.root);
|
|
1088
|
-
if (MergeTree.options.measureWindowTime) {
|
|
1089
|
-
rootStats.windowTime = this.windowTime;
|
|
1090
|
-
rootStats.packTime = this.packTime;
|
|
1091
|
-
rootStats.ordTime = this.ordTime;
|
|
1092
|
-
rootStats.maxOrdTime = this.maxOrdTime;
|
|
1093
|
-
}
|
|
1094
1006
|
return rootStats;
|
|
1095
1007
|
}
|
|
1096
|
-
findHistorialPosition(pos, fromSeq, toSeq, clientId) {
|
|
1097
|
-
return this.findHistorialPositionFromClient(pos, fromSeq, toSeq, clientId);
|
|
1098
|
-
}
|
|
1099
|
-
findHistorialPositionFromClient(pos, fromSeq, toSeq, clientId) {
|
|
1100
|
-
common_utils_1.assert(fromSeq < toSeq, 0x04a /* "Invalid range for historical position search!" */);
|
|
1101
|
-
if (pos < this.getLength(fromSeq, clientId)) {
|
|
1102
|
-
common_utils_1.assert(toSeq <= this.collabWindow.currentSeq, 0x04b /* "Out-of-bounds end sequence number for historical position search!" */);
|
|
1103
|
-
const segoff = this.getContainingSegment(pos, fromSeq, clientId);
|
|
1104
|
-
common_utils_1.assert(segoff.segment !== undefined, 0x04c /* "Containing segment for historical position search is undefined!" */);
|
|
1105
|
-
const toPos = this.getPosition(segoff.segment, toSeq, clientId);
|
|
1106
|
-
const ret = toPos + segoff.offset;
|
|
1107
|
-
common_utils_1.assert(ret !== undefined, 0x04d /* "Return value for historical position search is undefined!" */);
|
|
1108
|
-
return ret;
|
|
1109
|
-
}
|
|
1110
|
-
else {
|
|
1111
|
-
return pos;
|
|
1112
|
-
}
|
|
1113
|
-
}
|
|
1114
|
-
findHistorialRangeFromClient(rangeStart, rangeEnd, fromSeq, toSeq, clientId) {
|
|
1115
|
-
const ranges = [];
|
|
1116
|
-
const recordRange = (segment, pos, refSeq, clientId, segStart, segEnd) => {
|
|
1117
|
-
var _a;
|
|
1118
|
-
let _segStart = segStart;
|
|
1119
|
-
let _segEnd = segEnd;
|
|
1120
|
-
if (((_a = this.nodeLength(segment, toSeq, clientId)) !== null && _a !== void 0 ? _a : 0) > 0) {
|
|
1121
|
-
const position = this.getPosition(segment, toSeq, clientId);
|
|
1122
|
-
if (_segStart < 0) {
|
|
1123
|
-
_segStart = 0;
|
|
1124
|
-
}
|
|
1125
|
-
if (_segEnd > segment.cachedLength) {
|
|
1126
|
-
_segEnd = segment.cachedLength;
|
|
1127
|
-
}
|
|
1128
|
-
ranges.push({ start: position + _segStart, end: position + _segEnd });
|
|
1129
|
-
}
|
|
1130
|
-
return true;
|
|
1131
|
-
};
|
|
1132
|
-
this.mapRange({ leaf: recordRange }, fromSeq, clientId, undefined, rangeStart, rangeEnd);
|
|
1133
|
-
return ranges;
|
|
1134
|
-
}
|
|
1135
|
-
findHistorialRange(rangeStart, rangeEnd, fromSeq, toSeq, clientId) {
|
|
1136
|
-
return this.findHistorialRangeFromClient(rangeStart, rangeEnd, fromSeq, toSeq, clientId);
|
|
1137
|
-
}
|
|
1138
1008
|
getLength(refSeq, clientId) {
|
|
1139
1009
|
return this.blockLength(this.root, refSeq, clientId);
|
|
1140
1010
|
}
|
|
@@ -1404,15 +1274,12 @@ class MergeTree {
|
|
|
1404
1274
|
* Assign sequence number to existing segment; update partial lengths to reflect the change
|
|
1405
1275
|
* @param seq - sequence number given by server to pending segment
|
|
1406
1276
|
*/
|
|
1407
|
-
ackPendingSegment(opArgs
|
|
1277
|
+
ackPendingSegment(opArgs) {
|
|
1408
1278
|
const seq = opArgs.sequencedMessage.sequenceNumber;
|
|
1409
1279
|
const pendingSegmentGroup = this.pendingSegments.dequeue();
|
|
1410
1280
|
const nodesToUpdate = [];
|
|
1411
1281
|
let overwrite = false;
|
|
1412
1282
|
if (pendingSegmentGroup !== undefined) {
|
|
1413
|
-
if (verboseOps) {
|
|
1414
|
-
console.log(`segment group has ${pendingSegmentGroup.segments.length} segments`);
|
|
1415
|
-
}
|
|
1416
1283
|
const deltaSegments = [];
|
|
1417
1284
|
pendingSegmentGroup.segments.map((pendingSegment) => {
|
|
1418
1285
|
overwrite = !pendingSegment.ack(pendingSegmentGroup, opArgs, this) || overwrite;
|
|
@@ -1486,12 +1353,7 @@ class MergeTree {
|
|
|
1486
1353
|
return pos;
|
|
1487
1354
|
}
|
|
1488
1355
|
insertSegments(pos, segments, refSeq, clientId, seq, opArgs) {
|
|
1489
|
-
// const tt = MergeTree.traceTraversal;
|
|
1490
|
-
// MergeTree.traceTraversal = true;
|
|
1491
1356
|
this.ensureIntervalBoundary(pos, refSeq, clientId);
|
|
1492
|
-
if (MergeTree.traceOrdinals) {
|
|
1493
|
-
this.ordinalIntegrity();
|
|
1494
|
-
}
|
|
1495
1357
|
const localSeq = seq === constants_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1496
1358
|
this.blockInsert(pos, refSeq, clientId, seq, localSeq, segments);
|
|
1497
1359
|
// opArgs == undefined => loading snapshot or test code
|
|
@@ -1501,10 +1363,6 @@ class MergeTree {
|
|
|
1501
1363
|
deltaSegments: segments.map((segment) => ({ segment })),
|
|
1502
1364
|
});
|
|
1503
1365
|
}
|
|
1504
|
-
// MergeTree.traceTraversal = tt;
|
|
1505
|
-
if (MergeTree.traceOrdinals) {
|
|
1506
|
-
this.ordinalIntegrity();
|
|
1507
|
-
}
|
|
1508
1366
|
if (this.collabWindow.collaborating && MergeTree.options.zamboniSegments &&
|
|
1509
1367
|
(seq !== constants_1.UnassignedSequenceNumber)) {
|
|
1510
1368
|
this.zamboniSegments();
|
|
@@ -1614,12 +1472,21 @@ class MergeTree {
|
|
|
1614
1472
|
/**
|
|
1615
1473
|
* Resolves a remote client's position against the local sequence
|
|
1616
1474
|
* and returns the remote client's position relative to the local
|
|
1617
|
-
* sequence
|
|
1475
|
+
* sequence. The client ref seq must be above the minimum sequence number
|
|
1476
|
+
* or the return value will be undefined.
|
|
1477
|
+
* Generally this method is used in conjunction with signals which provide
|
|
1478
|
+
* point in time values for the below parameters, and is useful for things
|
|
1479
|
+
* like displaying user position. It should not be used with persisted values
|
|
1480
|
+
* as persisted values will quickly become invalid as the remoteClientRefSeq
|
|
1481
|
+
* moves below the minimum sequence number
|
|
1618
1482
|
* @param remoteClientPosition - The remote client's position to resolve
|
|
1619
1483
|
* @param remoteClientRefSeq - The reference sequence number of the remote client
|
|
1620
1484
|
* @param remoteClientId - The client id of the remote client
|
|
1621
1485
|
*/
|
|
1622
1486
|
resolveRemoteClientPosition(remoteClientPosition, remoteClientRefSeq, remoteClientId) {
|
|
1487
|
+
if (remoteClientRefSeq < this.collabWindow.minSeq) {
|
|
1488
|
+
return undefined;
|
|
1489
|
+
}
|
|
1623
1490
|
const segmentInfo = this.getContainingSegment(remoteClientPosition, remoteClientRefSeq, remoteClientId);
|
|
1624
1491
|
const segwindow = this.getCollabWindow();
|
|
1625
1492
|
if (segmentInfo && segmentInfo.segment) {
|
|
@@ -1645,10 +1512,6 @@ class MergeTree {
|
|
|
1645
1512
|
let segIsLocal = false;
|
|
1646
1513
|
const checkSegmentIsLocal = (segment, pos, refSeq, clientId) => {
|
|
1647
1514
|
if (segment.seq === constants_1.UnassignedSequenceNumber) {
|
|
1648
|
-
if (MergeTree.diagInsertTie) {
|
|
1649
|
-
// eslint-disable-next-line max-len
|
|
1650
|
-
console.log(`@cli ${glc(this, this.collabWindow.clientId)}: promoting continue due to seq ${segment.seq} text ${segment.toString()} ref ${refSeq}`);
|
|
1651
|
-
}
|
|
1652
1515
|
segIsLocal = true;
|
|
1653
1516
|
}
|
|
1654
1517
|
// Only need to look at first segment that follows finished node
|
|
@@ -1657,10 +1520,6 @@ class MergeTree {
|
|
|
1657
1520
|
const continueFrom = (node) => {
|
|
1658
1521
|
segIsLocal = false;
|
|
1659
1522
|
this.rightExcursion(node, checkSegmentIsLocal);
|
|
1660
|
-
if (MergeTree.diagInsertTie && segIsLocal) {
|
|
1661
|
-
// eslint-disable-next-line max-len
|
|
1662
|
-
console.log(`@cli ${glc(this, this.collabWindow.clientId)}: attempting continue with seq ${seq} ref ${refSeq} `);
|
|
1663
|
-
}
|
|
1664
1523
|
return segIsLocal;
|
|
1665
1524
|
};
|
|
1666
1525
|
let segmentGroup;
|
|
@@ -1731,7 +1590,7 @@ class MergeTree {
|
|
|
1731
1590
|
if (pos === 0) {
|
|
1732
1591
|
// normalize the seq numbers
|
|
1733
1592
|
// if the new seg is local (UnassignedSequenceNumber) give it the highest possible
|
|
1734
|
-
// seq for
|
|
1593
|
+
// seq for comparison, as it will get a seq higher than any other seq once sequences
|
|
1735
1594
|
// if the current seg is local (UnassignedSequenceNumber) give it the second highest
|
|
1736
1595
|
// possible seq, as the highest is reserved for the previous.
|
|
1737
1596
|
const newSeq = seq === constants_1.UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER : seq;
|
|
@@ -1816,7 +1675,6 @@ class MergeTree {
|
|
|
1816
1675
|
let child;
|
|
1817
1676
|
let newNode;
|
|
1818
1677
|
let fromSplit;
|
|
1819
|
-
let found = false;
|
|
1820
1678
|
for (childIndex = 0; childIndex < block.childCount; childIndex++) {
|
|
1821
1679
|
child = children[childIndex];
|
|
1822
1680
|
const len = this.nodeLength(child, refSeq, clientId);
|
|
@@ -1825,23 +1683,8 @@ class MergeTree {
|
|
|
1825
1683
|
// will be removed, so should just be skipped for now
|
|
1826
1684
|
continue;
|
|
1827
1685
|
}
|
|
1828
|
-
if (MergeTree.traceTraversal) {
|
|
1829
|
-
let segInfo;
|
|
1830
|
-
if ((!child.isLeaf()) && this.collabWindow.collaborating) {
|
|
1831
|
-
segInfo = `minLength: ${child.partialLengths.minLength}`;
|
|
1832
|
-
}
|
|
1833
|
-
else {
|
|
1834
|
-
const segment = child;
|
|
1835
|
-
segInfo = `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} text: ${segment.toString()}`;
|
|
1836
|
-
if (segment.removedSeq !== undefined) {
|
|
1837
|
-
segInfo += ` rcli: ${glc(this, segment.removedClientId)} rseq: ${segment.removedSeq}`;
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
|
-
console.log(`@tcli: ${glc(this, this.collabWindow.clientId)} len: ${len} pos: ${_pos} ${segInfo}`);
|
|
1841
|
-
}
|
|
1842
1686
|
if ((_pos < len) || ((_pos === len) && this.breakTie(_pos, child, seq))) {
|
|
1843
1687
|
// Found entry containing pos
|
|
1844
|
-
found = true;
|
|
1845
1688
|
if (!child.isLeaf()) {
|
|
1846
1689
|
const childBlock = child;
|
|
1847
1690
|
// Internal node
|
|
@@ -1856,10 +1699,6 @@ class MergeTree {
|
|
|
1856
1699
|
return undefined;
|
|
1857
1700
|
}
|
|
1858
1701
|
else if (splitNode === MergeTree.theUnfinishedNode) {
|
|
1859
|
-
if (MergeTree.traceTraversal) {
|
|
1860
|
-
// eslint-disable-next-line max-len
|
|
1861
|
-
console.log(`@cli ${glc(this, this.collabWindow.clientId)} unfinished bus pos ${_pos} len ${len}`);
|
|
1862
|
-
}
|
|
1863
1702
|
_pos -= len; // Act as if shifted segment
|
|
1864
1703
|
continue;
|
|
1865
1704
|
}
|
|
@@ -1870,15 +1709,9 @@ class MergeTree {
|
|
|
1870
1709
|
}
|
|
1871
1710
|
}
|
|
1872
1711
|
else {
|
|
1873
|
-
if (MergeTree.traceTraversal) {
|
|
1874
|
-
console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action`);
|
|
1875
|
-
}
|
|
1876
1712
|
const segment = child;
|
|
1877
1713
|
const segmentChanges = context.leaf(segment, _pos, context);
|
|
1878
1714
|
if (segmentChanges.replaceCurrent) {
|
|
1879
|
-
if (MergeTree.traceOrdinals) {
|
|
1880
|
-
console.log(`assign from leaf with block ord ${ordinalToArray(block.ordinal)}`);
|
|
1881
|
-
}
|
|
1882
1715
|
block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
|
|
1883
1716
|
segmentChanges.replaceCurrent.ordinal = child.ordinal;
|
|
1884
1717
|
}
|
|
@@ -1900,12 +1733,6 @@ class MergeTree {
|
|
|
1900
1733
|
_pos -= len;
|
|
1901
1734
|
}
|
|
1902
1735
|
}
|
|
1903
|
-
if (MergeTree.traceTraversal) {
|
|
1904
|
-
if ((!found) && (_pos > 0)) {
|
|
1905
|
-
// eslint-disable-next-line max-len
|
|
1906
|
-
console.log(`inserting walk fell through pos ${_pos} len: ${this.blockLength(this.root, refSeq, clientId)}`);
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
1736
|
if (!newNode) {
|
|
1910
1737
|
if (_pos === 0) {
|
|
1911
1738
|
if ((seq !== constants_1.UnassignedSequenceNumber) && context.continuePredicate &&
|
|
@@ -1913,9 +1740,6 @@ class MergeTree {
|
|
|
1913
1740
|
return MergeTree.theUnfinishedNode;
|
|
1914
1741
|
}
|
|
1915
1742
|
else {
|
|
1916
|
-
if (MergeTree.traceTraversal) {
|
|
1917
|
-
console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action pos 0`);
|
|
1918
|
-
}
|
|
1919
1743
|
const segmentChanges = context.leaf(undefined, _pos, context);
|
|
1920
1744
|
newNode = segmentChanges.next;
|
|
1921
1745
|
// Assert segmentChanges.replaceCurrent === undefined
|
|
@@ -1932,9 +1756,6 @@ class MergeTree {
|
|
|
1932
1756
|
block.setOrdinal(newNode, childIndex);
|
|
1933
1757
|
if (block.childCount < exports.MaxNodesInBlock) {
|
|
1934
1758
|
if (fromSplit) {
|
|
1935
|
-
if (MergeTree.traceOrdinals) {
|
|
1936
|
-
console.log(`split ord ${ordinalToArray(fromSplit.ordinal)}`);
|
|
1937
|
-
}
|
|
1938
1759
|
this.nodeUpdateOrdinals(fromSplit);
|
|
1939
1760
|
}
|
|
1940
1761
|
if (context.structureChange) {
|
|
@@ -1968,43 +1789,7 @@ class MergeTree {
|
|
|
1968
1789
|
this.nodeUpdateLengthNewStructure(newNode);
|
|
1969
1790
|
return newNode;
|
|
1970
1791
|
}
|
|
1971
|
-
ordinalIntegrity() {
|
|
1972
|
-
console.log("chk ordnls");
|
|
1973
|
-
this.nodeOrdinalIntegrity(this.root);
|
|
1974
|
-
}
|
|
1975
|
-
nodeOrdinalIntegrity(block) {
|
|
1976
|
-
const olen = block.ordinal.length;
|
|
1977
|
-
for (let i = 0; i < block.childCount; i++) {
|
|
1978
|
-
const child = block.children[i];
|
|
1979
|
-
if (child.ordinal) {
|
|
1980
|
-
if (olen !== (child.ordinal.length - 1)) {
|
|
1981
|
-
console.log("node integrity issue");
|
|
1982
|
-
}
|
|
1983
|
-
if (i > 0) {
|
|
1984
|
-
if (child.ordinal <= block.children[i - 1].ordinal) {
|
|
1985
|
-
console.log("node sib integrity issue");
|
|
1986
|
-
// eslint-disable-next-line max-len
|
|
1987
|
-
console.log(`??: prnt chld prev ${ordinalToArray(block.ordinal)} ${ordinalToArray(child.ordinal)} ${(i > 0) ? ordinalToArray(block.children[i - 1].ordinal) : "NA"}`);
|
|
1988
|
-
}
|
|
1989
|
-
}
|
|
1990
|
-
if (!child.isLeaf()) {
|
|
1991
|
-
this.nodeOrdinalIntegrity(child);
|
|
1992
|
-
}
|
|
1993
|
-
}
|
|
1994
|
-
else {
|
|
1995
|
-
console.log(`node child ordinal not set ${i}`);
|
|
1996
|
-
console.log(`??: prnt ${ordinalToArray(block.ordinal)}`);
|
|
1997
|
-
}
|
|
1998
|
-
}
|
|
1999
|
-
}
|
|
2000
1792
|
nodeUpdateOrdinals(block) {
|
|
2001
|
-
if (MergeTree.traceOrdinals) {
|
|
2002
|
-
console.log(`update ordinals for children of node with ordinal ${ordinalToArray(block.ordinal)}`);
|
|
2003
|
-
}
|
|
2004
|
-
let clockStart;
|
|
2005
|
-
if (MergeTree.options.measureOrdinalTime) {
|
|
2006
|
-
clockStart = clock();
|
|
2007
|
-
}
|
|
2008
1793
|
for (let i = 0; i < block.childCount; i++) {
|
|
2009
1794
|
const child = block.children[i];
|
|
2010
1795
|
block.setOrdinal(child, i);
|
|
@@ -2012,21 +1797,11 @@ class MergeTree {
|
|
|
2012
1797
|
this.nodeUpdateOrdinals(child);
|
|
2013
1798
|
}
|
|
2014
1799
|
}
|
|
2015
|
-
if (clockStart) {
|
|
2016
|
-
const elapsed = elapsedMicroseconds(clockStart);
|
|
2017
|
-
if (elapsed > this.maxOrdTime) {
|
|
2018
|
-
this.maxOrdTime = elapsed;
|
|
2019
|
-
}
|
|
2020
|
-
this.ordTime += elapsed;
|
|
2021
|
-
}
|
|
2022
1800
|
}
|
|
2023
1801
|
addOverlappingClient(removalInfo, clientId) {
|
|
2024
1802
|
if (!removalInfo.removedClientOverlap) {
|
|
2025
1803
|
removalInfo.removedClientOverlap = [];
|
|
2026
1804
|
}
|
|
2027
|
-
if (MergeTree.diagOverlappingRemove) {
|
|
2028
|
-
console.log(`added cli ${glc(this, clientId)} to rseq: ${removalInfo.removedSeq}`);
|
|
2029
|
-
}
|
|
2030
1805
|
removalInfo.removedClientOverlap.push(clientId);
|
|
2031
1806
|
}
|
|
2032
1807
|
/**
|
|
@@ -2086,10 +1861,6 @@ class MergeTree {
|
|
|
2086
1861
|
const markRemoved = (segment, pos, start, end) => {
|
|
2087
1862
|
const removalInfo = segment;
|
|
2088
1863
|
if (removalInfo.removedSeq !== undefined) {
|
|
2089
|
-
if (MergeTree.diagOverlappingRemove) {
|
|
2090
|
-
// eslint-disable-next-line max-len
|
|
2091
|
-
console.log(`yump @seq ${seq} cli ${glc(this, this.collabWindow.clientId)}: overlaps deleted segment ${removalInfo.removedSeq} text '${segment.toString()}'`);
|
|
2092
|
-
}
|
|
2093
1864
|
_overwrite = true;
|
|
2094
1865
|
if (removalInfo.removedSeq === constants_1.UnassignedSequenceNumber) {
|
|
2095
1866
|
// replace because comes later
|
|
@@ -2124,7 +1895,6 @@ class MergeTree {
|
|
|
2124
1895
|
this.addToLRUSet(segment, seq);
|
|
2125
1896
|
}
|
|
2126
1897
|
}
|
|
2127
|
-
// console.log(`saved local removed seg with text: ${textSegment.text}`);
|
|
2128
1898
|
}
|
|
2129
1899
|
return true;
|
|
2130
1900
|
};
|
|
@@ -2137,7 +1907,6 @@ class MergeTree {
|
|
|
2137
1907
|
}
|
|
2138
1908
|
return true;
|
|
2139
1909
|
};
|
|
2140
|
-
// MergeTree.traceTraversal = true;
|
|
2141
1910
|
this.mapRange({ leaf: markRemoved, post: afterMarkRemoved }, refSeq, clientId, undefined, start, end);
|
|
2142
1911
|
if (savedLocalRefs.length > 0) {
|
|
2143
1912
|
const length = this.getLength(refSeq, clientId);
|
|
@@ -2183,7 +1952,6 @@ class MergeTree {
|
|
|
2183
1952
|
this.zamboniSegments();
|
|
2184
1953
|
}
|
|
2185
1954
|
}
|
|
2186
|
-
// MergeTree.traceTraversal = false;
|
|
2187
1955
|
}
|
|
2188
1956
|
nodeUpdateLengthNewStructure(node, recur = false) {
|
|
2189
1957
|
this.blockUpdate(node);
|
|
@@ -2272,45 +2040,6 @@ class MergeTree {
|
|
|
2272
2040
|
}
|
|
2273
2041
|
this.nodeMap(this.root, actions, 0, refSeq, clientId, accum, start, end);
|
|
2274
2042
|
}
|
|
2275
|
-
nodeToString(block, strbuf, indentCount = 0) {
|
|
2276
|
-
let _strbuf = strbuf;
|
|
2277
|
-
_strbuf += internedSpaces(indentCount);
|
|
2278
|
-
// eslint-disable-next-line max-len
|
|
2279
|
-
_strbuf += `Node (len ${block.cachedLength}) p len (${block.parent ? block.parent.cachedLength : 0}) ord ${ordinalToArray(block.ordinal)} with ${block.childCount} segs:\n`;
|
|
2280
|
-
if (MergeTree.blockUpdateMarkers) {
|
|
2281
|
-
_strbuf += internedSpaces(indentCount);
|
|
2282
|
-
_strbuf += block.hierToString(indentCount);
|
|
2283
|
-
}
|
|
2284
|
-
if (this.collabWindow.collaborating) {
|
|
2285
|
-
_strbuf += internedSpaces(indentCount);
|
|
2286
|
-
_strbuf += `${block.partialLengths.toString((id) => glc(this, id), indentCount)}\n`;
|
|
2287
|
-
}
|
|
2288
|
-
const children = block.children;
|
|
2289
|
-
for (let childIndex = 0; childIndex < block.childCount; childIndex++) {
|
|
2290
|
-
const child = children[childIndex];
|
|
2291
|
-
if (!child.isLeaf()) {
|
|
2292
|
-
_strbuf = this.nodeToString(child, _strbuf, indentCount + 4);
|
|
2293
|
-
}
|
|
2294
|
-
else {
|
|
2295
|
-
const segment = child;
|
|
2296
|
-
_strbuf += internedSpaces(indentCount + 4);
|
|
2297
|
-
// eslint-disable-next-line max-len
|
|
2298
|
-
_strbuf += `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} ord: ${ordinalToArray(segment.ordinal)}`;
|
|
2299
|
-
const removalInfo = segment;
|
|
2300
|
-
if (removalInfo.removedSeq !== undefined) {
|
|
2301
|
-
_strbuf += ` rcli: ${glc(this, removalInfo.removedClientId)} rseq: ${removalInfo.removedSeq}`;
|
|
2302
|
-
}
|
|
2303
|
-
_strbuf += "\n";
|
|
2304
|
-
_strbuf += internedSpaces(indentCount + 4);
|
|
2305
|
-
_strbuf += segment.toString();
|
|
2306
|
-
_strbuf += "\n";
|
|
2307
|
-
}
|
|
2308
|
-
}
|
|
2309
|
-
return _strbuf;
|
|
2310
|
-
}
|
|
2311
|
-
toString() {
|
|
2312
|
-
return this.nodeToString(this.root, "", 0);
|
|
2313
|
-
}
|
|
2314
2043
|
incrementalBlockMap(stateStack) {
|
|
2315
2044
|
var _a;
|
|
2316
2045
|
while (!stateStack.empty()) {
|
|
@@ -2333,22 +2062,12 @@ class MergeTree {
|
|
|
2333
2062
|
if ((state.op === IncrementalExecOp.Go) && (state.childIndex < state.block.childCount)) {
|
|
2334
2063
|
const child = state.block.children[state.childIndex];
|
|
2335
2064
|
const len = (_a = this.nodeLength(child, state.refSeq, state.clientId)) !== null && _a !== void 0 ? _a : 0;
|
|
2336
|
-
if (MergeTree.traceIncrTraversal) {
|
|
2337
|
-
if (child.isLeaf()) {
|
|
2338
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation, max-len
|
|
2339
|
-
console.log(`considering (r ${state.refSeq} c ${glc(this, state.clientId)}) seg with text ${child["text"]} len ${len} seq ${child.seq} rseq ${child.removedSeq} cli ${glc(this, child.clientId)}`);
|
|
2340
|
-
}
|
|
2341
|
-
}
|
|
2342
2065
|
if ((len > 0) && (state.start < len) && (state.end > 0)) {
|
|
2343
2066
|
if (!child.isLeaf()) {
|
|
2344
2067
|
const childState = new IncrementalMapState(child, state.actions, state.pos, state.refSeq, state.clientId, state.context, state.start, state.end, 0);
|
|
2345
2068
|
stateStack.push(childState);
|
|
2346
2069
|
}
|
|
2347
2070
|
else {
|
|
2348
|
-
if (MergeTree.traceIncrTraversal) {
|
|
2349
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
2350
|
-
console.log(`action on seg with text ${child["text"]}`);
|
|
2351
|
-
}
|
|
2352
2071
|
state.actions.leaf(child, state);
|
|
2353
2072
|
}
|
|
2354
2073
|
}
|
|
@@ -2390,21 +2109,6 @@ class MergeTree {
|
|
|
2390
2109
|
for (let childIndex = 0; childIndex < node.childCount; childIndex++) {
|
|
2391
2110
|
const child = children[childIndex];
|
|
2392
2111
|
const len = (_a = this.nodeLength(child, refSeq, clientId)) !== null && _a !== void 0 ? _a : 0;
|
|
2393
|
-
if (MergeTree.traceTraversal) {
|
|
2394
|
-
let segInfo;
|
|
2395
|
-
if ((!child.isLeaf()) && this.collabWindow.collaborating) {
|
|
2396
|
-
segInfo = `minLength: ${child.partialLengths.minLength}`;
|
|
2397
|
-
}
|
|
2398
|
-
else {
|
|
2399
|
-
const segment = child;
|
|
2400
|
-
segInfo = `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} text: '${segment.toString()}'`;
|
|
2401
|
-
if (segment.removedSeq !== undefined) {
|
|
2402
|
-
segInfo += ` rcli: ${glc(this, segment.removedClientId)} rseq: ${segment.removedSeq}`;
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
// eslint-disable-next-line max-len
|
|
2406
|
-
console.log(`@tcli ${glc(this, this.collabWindow.clientId)}: map len: ${len} start: ${_start} end: ${_end} ${segInfo}`);
|
|
2407
|
-
}
|
|
2408
2112
|
if (go && (_end > 0) && (len > 0) && (_start < len)) {
|
|
2409
2113
|
// Found entry containing pos
|
|
2410
2114
|
if (!child.isLeaf()) {
|
|
@@ -2413,9 +2117,6 @@ class MergeTree {
|
|
|
2413
2117
|
}
|
|
2414
2118
|
}
|
|
2415
2119
|
else {
|
|
2416
|
-
if (MergeTree.traceTraversal) {
|
|
2417
|
-
console.log(`@tcli ${glc(this, this.collabWindow.clientId)}: map leaf action`);
|
|
2418
|
-
}
|
|
2419
2120
|
if (actions.leaf) {
|
|
2420
2121
|
go = actions.leaf(child, _pos, refSeq, clientId, _start, _end, accum);
|
|
2421
2122
|
}
|
|
@@ -2478,18 +2179,8 @@ MergeTree.zamboniSegmentsMaxCount = 2;
|
|
|
2478
2179
|
MergeTree.options = {
|
|
2479
2180
|
incrementalUpdate: true,
|
|
2480
2181
|
insertAfterRemovedSegs: true,
|
|
2481
|
-
measureOrdinalTime: true,
|
|
2482
|
-
measureWindowTime: true,
|
|
2483
2182
|
zamboniSegments: true,
|
|
2484
2183
|
};
|
|
2485
|
-
MergeTree.traceAppend = false;
|
|
2486
|
-
MergeTree.traceZRemove = false;
|
|
2487
|
-
MergeTree.traceOrdinals = false;
|
|
2488
|
-
MergeTree.traceGatherText = false;
|
|
2489
|
-
MergeTree.diagInsertTie = false;
|
|
2490
|
-
MergeTree.diagOverlappingRemove = false;
|
|
2491
|
-
MergeTree.traceTraversal = false;
|
|
2492
|
-
MergeTree.traceIncrTraversal = false;
|
|
2493
2184
|
MergeTree.theUnfinishedNode = { childCount: -1 };
|
|
2494
2185
|
// WARNING:
|
|
2495
2186
|
// Setting blockUpdateMarkers to false will result in eventual consistency issues
|