@fluidframework/merge-tree 0.57.2 → 0.58.1000
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 +10 -10
- 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/lib/mergeTree.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
/* eslint-disable max-lines */
|
|
5
6
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
6
7
|
/* eslint-disable @typescript-eslint/consistent-type-assertions */
|
|
7
|
-
/* eslint-disable @typescript-eslint/no-shadow */
|
|
8
8
|
/* eslint-disable no-bitwise */
|
|
9
|
-
import { assert
|
|
9
|
+
import { assert } from "@fluidframework/common-utils";
|
|
10
10
|
import { Heap, ListMakeHead, Stack, } from "./collections";
|
|
11
11
|
import { LocalClientId, NonCollabClient, TreeMaintenanceSequenceNumber, UnassignedSequenceNumber, UniversalSequenceNumber, } from "./constants";
|
|
12
12
|
import { LocalReference, LocalReferenceCollection } from "./localReference";
|
|
@@ -26,7 +26,6 @@ export class MergeNode {
|
|
|
26
26
|
return false;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
30
29
|
function addTile(tile, tiles) {
|
|
31
30
|
const tileLabels = tile.getTileLabels();
|
|
32
31
|
if (tileLabels) {
|
|
@@ -35,7 +34,6 @@ function addTile(tile, tiles) {
|
|
|
35
34
|
}
|
|
36
35
|
}
|
|
37
36
|
}
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
39
37
|
function addTileIfNotPresent(tile, tiles) {
|
|
40
38
|
const tileLabels = tile.getTileLabels();
|
|
41
39
|
if (tileLabels) {
|
|
@@ -47,7 +45,7 @@ function addTileIfNotPresent(tile, tiles) {
|
|
|
47
45
|
}
|
|
48
46
|
}
|
|
49
47
|
function applyStackDelta(currentStackMap, deltaStackMap) {
|
|
50
|
-
// eslint-disable-next-line guard-for-in
|
|
48
|
+
// eslint-disable-next-line guard-for-in
|
|
51
49
|
for (const label in deltaStackMap) {
|
|
52
50
|
const deltaStack = deltaStackMap[label];
|
|
53
51
|
if (!deltaStack.empty()) {
|
|
@@ -153,7 +151,6 @@ export function ordinalToArray(ord) {
|
|
|
153
151
|
// `MaxNodesInBlock`. (i.e., `MaxNodesInBlock` contains 1 extra slot for temporary storage to
|
|
154
152
|
// facilitate splits.)
|
|
155
153
|
export const MaxNodesInBlock = 8;
|
|
156
|
-
const traceOrdinals = false;
|
|
157
154
|
export class MergeBlock extends MergeNode {
|
|
158
155
|
constructor(childCount) {
|
|
159
156
|
super();
|
|
@@ -180,16 +177,9 @@ export class MergeBlock extends MergeNode {
|
|
|
180
177
|
localOrdinal = prevOrdCode + ordinalWidth;
|
|
181
178
|
}
|
|
182
179
|
child.ordinal = this.ordinal + String.fromCharCode(localOrdinal);
|
|
183
|
-
if (traceOrdinals) {
|
|
184
|
-
// eslint-disable-next-line max-len
|
|
185
|
-
console.log(`so: prnt chld prev ${ordinalToArray(this.ordinal)} ${ordinalToArray(child.ordinal)} ${(index > 0) ? ordinalToArray(this.children[index - 1].ordinal) : "NA"}`);
|
|
186
|
-
}
|
|
187
180
|
assert(child.ordinal.length === (this.ordinal.length + 1), 0x041 /* "Unexpected child ordinal length!" */);
|
|
188
181
|
if (index > 0) {
|
|
189
182
|
assert(child.ordinal > this.children[index - 1].ordinal, 0x042);
|
|
190
|
-
// eslint-disable-next-line max-len
|
|
191
|
-
// console.log(`${ordinalToArray(this.ordinal)} ${ordinalToArray(child.ordinal)} ${ordinalToArray(this.children[index - 1].ordinal)}`);
|
|
192
|
-
// console.log(`ord width ${ordinalWidth}`);
|
|
193
183
|
}
|
|
194
184
|
}
|
|
195
185
|
assignChild(child, index, updateOrdinal = true) {
|
|
@@ -216,7 +206,7 @@ class HierMergeBlock extends MergeBlock {
|
|
|
216
206
|
}
|
|
217
207
|
hierToString(indentCount) {
|
|
218
208
|
let strbuf = "";
|
|
219
|
-
// eslint-disable-next-line guard-for-in
|
|
209
|
+
// eslint-disable-next-line guard-for-in
|
|
220
210
|
for (const key in this.rangeStacks) {
|
|
221
211
|
const stack = this.rangeStacks[key];
|
|
222
212
|
strbuf += internedSpaces(indentCount);
|
|
@@ -289,7 +279,6 @@ export class BaseSegment extends MergeNode {
|
|
|
289
279
|
this.localSeq = undefined;
|
|
290
280
|
return true;
|
|
291
281
|
case 1 /* REMOVE */:
|
|
292
|
-
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
293
282
|
const removalInfo = this;
|
|
294
283
|
assert(!!removalInfo, 0x046 /* "On remove ack, missing removal info!" */);
|
|
295
284
|
assert(!!removalInfo.removedSeq, 0x047 /* "On remove ack, missing removed sequence number!" */);
|
|
@@ -298,11 +287,6 @@ export class BaseSegment extends MergeNode {
|
|
|
298
287
|
removalInfo.removedSeq = opArgs.sequencedMessage.sequenceNumber;
|
|
299
288
|
return true;
|
|
300
289
|
}
|
|
301
|
-
if (MergeTree.diagOverlappingRemove) {
|
|
302
|
-
console.log(`grump @seq ${opArgs.sequencedMessage.sequenceNumber} ` +
|
|
303
|
-
`cli ${glc(mergeTree, mergeTree.collabWindow.clientId)} ` +
|
|
304
|
-
`from ${removalInfo.removedSeq} text ${mergeTree.toString()}`);
|
|
305
|
-
}
|
|
306
290
|
return false;
|
|
307
291
|
default:
|
|
308
292
|
throw new Error(`${opArgs.op.type} is in unrecognized operation type`);
|
|
@@ -502,7 +486,6 @@ export class Marker extends BaseSegment {
|
|
|
502
486
|
// Avoid circular reference when stringifying makers containing handles.
|
|
503
487
|
// (Substitute a debug string instead.)
|
|
504
488
|
const handle = !!value && value.IFluidHandle;
|
|
505
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
506
489
|
return handle
|
|
507
490
|
? `#Handle(${handle.routeContext.path}/${handle.path})`
|
|
508
491
|
: value;
|
|
@@ -559,12 +542,6 @@ export class CollaborationWindow {
|
|
|
559
542
|
}
|
|
560
543
|
export const compareNumbers = (a, b) => a - b;
|
|
561
544
|
export const compareStrings = (a, b) => a.localeCompare(b);
|
|
562
|
-
export function clock() {
|
|
563
|
-
return Trace.start();
|
|
564
|
-
}
|
|
565
|
-
export function elapsedMicroseconds(trace) {
|
|
566
|
-
return trace.trace().duration * 1000;
|
|
567
|
-
}
|
|
568
545
|
const indentStrings = ["", " ", " "];
|
|
569
546
|
export function internedSpaces(n) {
|
|
570
547
|
if (indentStrings[n] === undefined) {
|
|
@@ -583,14 +560,6 @@ const LRUSegmentComparer = {
|
|
|
583
560
|
min: { maxSeq: -2 },
|
|
584
561
|
compare: (a, b) => a.maxSeq - b.maxSeq,
|
|
585
562
|
};
|
|
586
|
-
export function glc(mergeTree, id) {
|
|
587
|
-
if (mergeTree.getLongClientId) {
|
|
588
|
-
return mergeTree.getLongClientId(id);
|
|
589
|
-
}
|
|
590
|
-
else {
|
|
591
|
-
return id.toString();
|
|
592
|
-
}
|
|
593
|
-
}
|
|
594
563
|
function applyLeafRangeMarker(marker, searchInfo) {
|
|
595
564
|
for (const rangeLabel of searchInfo.rangeLabels) {
|
|
596
565
|
if (marker.hasRangeLabel(rangeLabel)) {
|
|
@@ -670,10 +639,6 @@ export class MergeTree {
|
|
|
670
639
|
// TODO: make and use interface describing options
|
|
671
640
|
constructor(options) {
|
|
672
641
|
this.options = options;
|
|
673
|
-
this.windowTime = 0;
|
|
674
|
-
this.packTime = 0;
|
|
675
|
-
this.ordTime = 0;
|
|
676
|
-
this.maxOrdTime = 0;
|
|
677
642
|
this.blockUpdateActions = MergeTree.initBlockUpdateActions;
|
|
678
643
|
this.collabWindow = new CollaborationWindow();
|
|
679
644
|
// TODO: add remove on segment remove
|
|
@@ -757,7 +722,6 @@ export class MergeTree {
|
|
|
757
722
|
// This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
|
|
758
723
|
assert(!this.collabWindow.collaborating, 0x049 /* "Trying to reload from segments while collaborating!" */);
|
|
759
724
|
const maxChildren = MaxNodesInBlock - 1;
|
|
760
|
-
const measureReloadTime = false;
|
|
761
725
|
// Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
|
|
762
726
|
const buildMergeBlock = (nodes) => {
|
|
763
727
|
const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
|
|
@@ -781,15 +745,10 @@ export class MergeTree {
|
|
|
781
745
|
// snapshot header. The bulk of the segments in long documents are inserted via `insertSegments()`.
|
|
782
746
|
this.blockUpdate(block);
|
|
783
747
|
}
|
|
784
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
785
748
|
return blocks.length === 1 // If there is only one block at this layer...
|
|
786
749
|
? blocks[0] // ...then we're done. Return the root.
|
|
787
750
|
: buildMergeBlock(blocks); // ...otherwise recursively build the next layer above blocks.
|
|
788
751
|
};
|
|
789
|
-
let clockStart;
|
|
790
|
-
if (measureReloadTime) {
|
|
791
|
-
clockStart = clock();
|
|
792
|
-
}
|
|
793
752
|
if (segments.length > 0) {
|
|
794
753
|
this.root = buildMergeBlock(segments);
|
|
795
754
|
this.nodeUpdateOrdinals(this.root);
|
|
@@ -797,9 +756,6 @@ export class MergeTree {
|
|
|
797
756
|
else {
|
|
798
757
|
this.root = this.makeBlock(0);
|
|
799
758
|
}
|
|
800
|
-
if (clockStart) {
|
|
801
|
-
console.log(`reload time ${elapsedMicroseconds(clockStart)}`);
|
|
802
|
-
}
|
|
803
759
|
}
|
|
804
760
|
/* eslint-enable max-len */
|
|
805
761
|
// For now assume min starts at zero
|
|
@@ -810,15 +766,7 @@ export class MergeTree {
|
|
|
810
766
|
this.collabWindow.currentSeq = currentSeq;
|
|
811
767
|
this.segmentsToScour = new Heap([], LRUSegmentComparer);
|
|
812
768
|
this.pendingSegments = ListMakeHead();
|
|
813
|
-
const measureFullCollab = false;
|
|
814
|
-
let clockStart;
|
|
815
|
-
if (measureFullCollab) {
|
|
816
|
-
clockStart = clock();
|
|
817
|
-
}
|
|
818
769
|
this.nodeUpdateLengthNewStructure(this.root, true);
|
|
819
|
-
if (clockStart) {
|
|
820
|
-
console.log(`update partial lengths at start ${elapsedMicroseconds(clockStart)}`);
|
|
821
|
-
}
|
|
822
770
|
}
|
|
823
771
|
addToLRUSet(segment, seq) {
|
|
824
772
|
// If the parent node has not yet been marked for scour (i.e., needsScour is not false or undefined),
|
|
@@ -848,10 +796,6 @@ export class MergeTree {
|
|
|
848
796
|
holdNodes.push(segment);
|
|
849
797
|
}
|
|
850
798
|
else {
|
|
851
|
-
if (MergeTree.traceZRemove) {
|
|
852
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation, max-len
|
|
853
|
-
console.log(`${this.getLongClientId(this.collabWindow.clientId)}: Zremove ${segment["text"]}; cli ${this.getLongClientId(segment.clientId)}`);
|
|
854
|
-
}
|
|
855
799
|
// Notify maintenance event observers that the segment is being unlinked from the MergeTree
|
|
856
800
|
if (this.mergeTreeMaintenanceCallback) {
|
|
857
801
|
this.mergeTreeMaintenanceCallback({
|
|
@@ -871,10 +815,6 @@ export class MergeTree {
|
|
|
871
815
|
&& prevSegment.trackingCollection.matches(segment.trackingCollection)
|
|
872
816
|
&& this.localNetLength(segment) > 0;
|
|
873
817
|
if (canAppend) {
|
|
874
|
-
if (MergeTree.traceAppend) {
|
|
875
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation, max-len
|
|
876
|
-
console.log(`${this.getLongClientId(this.collabWindow.clientId)}: append ${prevSegment["text"]} + ${segment["text"]}; cli ${this.getLongClientId(prevSegment.clientId)} + cli ${this.getLongClientId(segment.clientId)}`);
|
|
877
|
-
}
|
|
878
818
|
prevSegment.append(segment);
|
|
879
819
|
if (this.mergeTreeMaintenanceCallback) {
|
|
880
820
|
this.mergeTreeMaintenanceCallback({
|
|
@@ -950,9 +890,6 @@ export class MergeTree {
|
|
|
950
890
|
packedBlocks[nodeIndex] = packedBlock;
|
|
951
891
|
this.nodeUpdateLengthNewStructure(packedBlock);
|
|
952
892
|
}
|
|
953
|
-
if (readCount !== totalNodeCount) {
|
|
954
|
-
console.log(`total count ${totalNodeCount} readCount ${readCount}`);
|
|
955
|
-
}
|
|
956
893
|
parent.children = packedBlocks;
|
|
957
894
|
for (let j = 0; j < childCount; j++) {
|
|
958
895
|
parent.assignChild(packedBlocks[j], j, false);
|
|
@@ -970,10 +907,6 @@ export class MergeTree {
|
|
|
970
907
|
if (!this.collabWindow.collaborating) {
|
|
971
908
|
return;
|
|
972
909
|
}
|
|
973
|
-
let clockStart;
|
|
974
|
-
if (MergeTree.options.measureWindowTime) {
|
|
975
|
-
clockStart = clock();
|
|
976
|
-
}
|
|
977
910
|
for (let i = 0; i < zamboniSegmentsMaxCount; i++) {
|
|
978
911
|
let segmentToScour = this.segmentsToScour.peek();
|
|
979
912
|
if (!segmentToScour || segmentToScour.maxSeq > this.collabWindow.minSeq) {
|
|
@@ -984,7 +917,6 @@ export class MergeTree {
|
|
|
984
917
|
if (segmentToScour.segment.parent && segmentToScour.segment.parent.needsScour !== false) {
|
|
985
918
|
const block = segmentToScour.segment.parent;
|
|
986
919
|
const childrenCopy = [];
|
|
987
|
-
// console.log(`scouring from ${segmentToScour.segment.seq}`);
|
|
988
920
|
this.scourNode(block, childrenCopy);
|
|
989
921
|
// This will avoid the cost of re-scouring nodes
|
|
990
922
|
// that have recently been scoured
|
|
@@ -997,15 +929,7 @@ export class MergeTree {
|
|
|
997
929
|
block.assignChild(childrenCopy[j], j, false);
|
|
998
930
|
}
|
|
999
931
|
if (this.underflow(block) && block.parent) {
|
|
1000
|
-
// nodeUpdatePathLengths(node, UnassignedSequenceNumber, -1, true);
|
|
1001
|
-
let packClockStart;
|
|
1002
|
-
if (MergeTree.options.measureWindowTime) {
|
|
1003
|
-
packClockStart = clock();
|
|
1004
|
-
}
|
|
1005
932
|
this.packParent(block.parent);
|
|
1006
|
-
if (MergeTree.options.measureWindowTime) {
|
|
1007
|
-
this.packTime += elapsedMicroseconds(packClockStart);
|
|
1008
|
-
}
|
|
1009
933
|
}
|
|
1010
934
|
else {
|
|
1011
935
|
this.nodeUpdateOrdinals(block);
|
|
@@ -1014,9 +938,6 @@ export class MergeTree {
|
|
|
1014
938
|
}
|
|
1015
939
|
}
|
|
1016
940
|
}
|
|
1017
|
-
if (MergeTree.options.measureWindowTime) {
|
|
1018
|
-
this.windowTime += elapsedMicroseconds(clockStart);
|
|
1019
|
-
}
|
|
1020
941
|
}
|
|
1021
942
|
getCollabWindow() {
|
|
1022
943
|
return this.collabWindow;
|
|
@@ -1065,56 +986,8 @@ export class MergeTree {
|
|
|
1065
986
|
return stats;
|
|
1066
987
|
};
|
|
1067
988
|
const rootStats = nodeGetStats(this.root);
|
|
1068
|
-
if (MergeTree.options.measureWindowTime) {
|
|
1069
|
-
rootStats.windowTime = this.windowTime;
|
|
1070
|
-
rootStats.packTime = this.packTime;
|
|
1071
|
-
rootStats.ordTime = this.ordTime;
|
|
1072
|
-
rootStats.maxOrdTime = this.maxOrdTime;
|
|
1073
|
-
}
|
|
1074
989
|
return rootStats;
|
|
1075
990
|
}
|
|
1076
|
-
findHistorialPosition(pos, fromSeq, toSeq, clientId) {
|
|
1077
|
-
return this.findHistorialPositionFromClient(pos, fromSeq, toSeq, clientId);
|
|
1078
|
-
}
|
|
1079
|
-
findHistorialPositionFromClient(pos, fromSeq, toSeq, clientId) {
|
|
1080
|
-
assert(fromSeq < toSeq, 0x04a /* "Invalid range for historical position search!" */);
|
|
1081
|
-
if (pos < this.getLength(fromSeq, clientId)) {
|
|
1082
|
-
assert(toSeq <= this.collabWindow.currentSeq, 0x04b /* "Out-of-bounds end sequence number for historical position search!" */);
|
|
1083
|
-
const segoff = this.getContainingSegment(pos, fromSeq, clientId);
|
|
1084
|
-
assert(segoff.segment !== undefined, 0x04c /* "Containing segment for historical position search is undefined!" */);
|
|
1085
|
-
const toPos = this.getPosition(segoff.segment, toSeq, clientId);
|
|
1086
|
-
const ret = toPos + segoff.offset;
|
|
1087
|
-
assert(ret !== undefined, 0x04d /* "Return value for historical position search is undefined!" */);
|
|
1088
|
-
return ret;
|
|
1089
|
-
}
|
|
1090
|
-
else {
|
|
1091
|
-
return pos;
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
1094
|
-
findHistorialRangeFromClient(rangeStart, rangeEnd, fromSeq, toSeq, clientId) {
|
|
1095
|
-
const ranges = [];
|
|
1096
|
-
const recordRange = (segment, pos, refSeq, clientId, segStart, segEnd) => {
|
|
1097
|
-
var _a;
|
|
1098
|
-
let _segStart = segStart;
|
|
1099
|
-
let _segEnd = segEnd;
|
|
1100
|
-
if (((_a = this.nodeLength(segment, toSeq, clientId)) !== null && _a !== void 0 ? _a : 0) > 0) {
|
|
1101
|
-
const position = this.getPosition(segment, toSeq, clientId);
|
|
1102
|
-
if (_segStart < 0) {
|
|
1103
|
-
_segStart = 0;
|
|
1104
|
-
}
|
|
1105
|
-
if (_segEnd > segment.cachedLength) {
|
|
1106
|
-
_segEnd = segment.cachedLength;
|
|
1107
|
-
}
|
|
1108
|
-
ranges.push({ start: position + _segStart, end: position + _segEnd });
|
|
1109
|
-
}
|
|
1110
|
-
return true;
|
|
1111
|
-
};
|
|
1112
|
-
this.mapRange({ leaf: recordRange }, fromSeq, clientId, undefined, rangeStart, rangeEnd);
|
|
1113
|
-
return ranges;
|
|
1114
|
-
}
|
|
1115
|
-
findHistorialRange(rangeStart, rangeEnd, fromSeq, toSeq, clientId) {
|
|
1116
|
-
return this.findHistorialRangeFromClient(rangeStart, rangeEnd, fromSeq, toSeq, clientId);
|
|
1117
|
-
}
|
|
1118
991
|
getLength(refSeq, clientId) {
|
|
1119
992
|
return this.blockLength(this.root, refSeq, clientId);
|
|
1120
993
|
}
|
|
@@ -1384,15 +1257,12 @@ export class MergeTree {
|
|
|
1384
1257
|
* Assign sequence number to existing segment; update partial lengths to reflect the change
|
|
1385
1258
|
* @param seq - sequence number given by server to pending segment
|
|
1386
1259
|
*/
|
|
1387
|
-
ackPendingSegment(opArgs
|
|
1260
|
+
ackPendingSegment(opArgs) {
|
|
1388
1261
|
const seq = opArgs.sequencedMessage.sequenceNumber;
|
|
1389
1262
|
const pendingSegmentGroup = this.pendingSegments.dequeue();
|
|
1390
1263
|
const nodesToUpdate = [];
|
|
1391
1264
|
let overwrite = false;
|
|
1392
1265
|
if (pendingSegmentGroup !== undefined) {
|
|
1393
|
-
if (verboseOps) {
|
|
1394
|
-
console.log(`segment group has ${pendingSegmentGroup.segments.length} segments`);
|
|
1395
|
-
}
|
|
1396
1266
|
const deltaSegments = [];
|
|
1397
1267
|
pendingSegmentGroup.segments.map((pendingSegment) => {
|
|
1398
1268
|
overwrite = !pendingSegment.ack(pendingSegmentGroup, opArgs, this) || overwrite;
|
|
@@ -1466,12 +1336,7 @@ export class MergeTree {
|
|
|
1466
1336
|
return pos;
|
|
1467
1337
|
}
|
|
1468
1338
|
insertSegments(pos, segments, refSeq, clientId, seq, opArgs) {
|
|
1469
|
-
// const tt = MergeTree.traceTraversal;
|
|
1470
|
-
// MergeTree.traceTraversal = true;
|
|
1471
1339
|
this.ensureIntervalBoundary(pos, refSeq, clientId);
|
|
1472
|
-
if (MergeTree.traceOrdinals) {
|
|
1473
|
-
this.ordinalIntegrity();
|
|
1474
|
-
}
|
|
1475
1340
|
const localSeq = seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1476
1341
|
this.blockInsert(pos, refSeq, clientId, seq, localSeq, segments);
|
|
1477
1342
|
// opArgs == undefined => loading snapshot or test code
|
|
@@ -1481,10 +1346,6 @@ export class MergeTree {
|
|
|
1481
1346
|
deltaSegments: segments.map((segment) => ({ segment })),
|
|
1482
1347
|
});
|
|
1483
1348
|
}
|
|
1484
|
-
// MergeTree.traceTraversal = tt;
|
|
1485
|
-
if (MergeTree.traceOrdinals) {
|
|
1486
|
-
this.ordinalIntegrity();
|
|
1487
|
-
}
|
|
1488
1349
|
if (this.collabWindow.collaborating && MergeTree.options.zamboniSegments &&
|
|
1489
1350
|
(seq !== UnassignedSequenceNumber)) {
|
|
1490
1351
|
this.zamboniSegments();
|
|
@@ -1594,12 +1455,21 @@ export class MergeTree {
|
|
|
1594
1455
|
/**
|
|
1595
1456
|
* Resolves a remote client's position against the local sequence
|
|
1596
1457
|
* and returns the remote client's position relative to the local
|
|
1597
|
-
* sequence
|
|
1458
|
+
* sequence. The client ref seq must be above the minimum sequence number
|
|
1459
|
+
* or the return value will be undefined.
|
|
1460
|
+
* Generally this method is used in conjunction with signals which provide
|
|
1461
|
+
* point in time values for the below parameters, and is useful for things
|
|
1462
|
+
* like displaying user position. It should not be used with persisted values
|
|
1463
|
+
* as persisted values will quickly become invalid as the remoteClientRefSeq
|
|
1464
|
+
* moves below the minimum sequence number
|
|
1598
1465
|
* @param remoteClientPosition - The remote client's position to resolve
|
|
1599
1466
|
* @param remoteClientRefSeq - The reference sequence number of the remote client
|
|
1600
1467
|
* @param remoteClientId - The client id of the remote client
|
|
1601
1468
|
*/
|
|
1602
1469
|
resolveRemoteClientPosition(remoteClientPosition, remoteClientRefSeq, remoteClientId) {
|
|
1470
|
+
if (remoteClientRefSeq < this.collabWindow.minSeq) {
|
|
1471
|
+
return undefined;
|
|
1472
|
+
}
|
|
1603
1473
|
const segmentInfo = this.getContainingSegment(remoteClientPosition, remoteClientRefSeq, remoteClientId);
|
|
1604
1474
|
const segwindow = this.getCollabWindow();
|
|
1605
1475
|
if (segmentInfo && segmentInfo.segment) {
|
|
@@ -1625,10 +1495,6 @@ export class MergeTree {
|
|
|
1625
1495
|
let segIsLocal = false;
|
|
1626
1496
|
const checkSegmentIsLocal = (segment, pos, refSeq, clientId) => {
|
|
1627
1497
|
if (segment.seq === UnassignedSequenceNumber) {
|
|
1628
|
-
if (MergeTree.diagInsertTie) {
|
|
1629
|
-
// eslint-disable-next-line max-len
|
|
1630
|
-
console.log(`@cli ${glc(this, this.collabWindow.clientId)}: promoting continue due to seq ${segment.seq} text ${segment.toString()} ref ${refSeq}`);
|
|
1631
|
-
}
|
|
1632
1498
|
segIsLocal = true;
|
|
1633
1499
|
}
|
|
1634
1500
|
// Only need to look at first segment that follows finished node
|
|
@@ -1637,10 +1503,6 @@ export class MergeTree {
|
|
|
1637
1503
|
const continueFrom = (node) => {
|
|
1638
1504
|
segIsLocal = false;
|
|
1639
1505
|
this.rightExcursion(node, checkSegmentIsLocal);
|
|
1640
|
-
if (MergeTree.diagInsertTie && segIsLocal) {
|
|
1641
|
-
// eslint-disable-next-line max-len
|
|
1642
|
-
console.log(`@cli ${glc(this, this.collabWindow.clientId)}: attempting continue with seq ${seq} ref ${refSeq} `);
|
|
1643
|
-
}
|
|
1644
1506
|
return segIsLocal;
|
|
1645
1507
|
};
|
|
1646
1508
|
let segmentGroup;
|
|
@@ -1711,7 +1573,7 @@ export class MergeTree {
|
|
|
1711
1573
|
if (pos === 0) {
|
|
1712
1574
|
// normalize the seq numbers
|
|
1713
1575
|
// if the new seg is local (UnassignedSequenceNumber) give it the highest possible
|
|
1714
|
-
// seq for
|
|
1576
|
+
// seq for comparison, as it will get a seq higher than any other seq once sequences
|
|
1715
1577
|
// if the current seg is local (UnassignedSequenceNumber) give it the second highest
|
|
1716
1578
|
// possible seq, as the highest is reserved for the previous.
|
|
1717
1579
|
const newSeq = seq === UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER : seq;
|
|
@@ -1796,7 +1658,6 @@ export class MergeTree {
|
|
|
1796
1658
|
let child;
|
|
1797
1659
|
let newNode;
|
|
1798
1660
|
let fromSplit;
|
|
1799
|
-
let found = false;
|
|
1800
1661
|
for (childIndex = 0; childIndex < block.childCount; childIndex++) {
|
|
1801
1662
|
child = children[childIndex];
|
|
1802
1663
|
const len = this.nodeLength(child, refSeq, clientId);
|
|
@@ -1805,23 +1666,8 @@ export class MergeTree {
|
|
|
1805
1666
|
// will be removed, so should just be skipped for now
|
|
1806
1667
|
continue;
|
|
1807
1668
|
}
|
|
1808
|
-
if (MergeTree.traceTraversal) {
|
|
1809
|
-
let segInfo;
|
|
1810
|
-
if ((!child.isLeaf()) && this.collabWindow.collaborating) {
|
|
1811
|
-
segInfo = `minLength: ${child.partialLengths.minLength}`;
|
|
1812
|
-
}
|
|
1813
|
-
else {
|
|
1814
|
-
const segment = child;
|
|
1815
|
-
segInfo = `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} text: ${segment.toString()}`;
|
|
1816
|
-
if (segment.removedSeq !== undefined) {
|
|
1817
|
-
segInfo += ` rcli: ${glc(this, segment.removedClientId)} rseq: ${segment.removedSeq}`;
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
|
-
console.log(`@tcli: ${glc(this, this.collabWindow.clientId)} len: ${len} pos: ${_pos} ${segInfo}`);
|
|
1821
|
-
}
|
|
1822
1669
|
if ((_pos < len) || ((_pos === len) && this.breakTie(_pos, child, seq))) {
|
|
1823
1670
|
// Found entry containing pos
|
|
1824
|
-
found = true;
|
|
1825
1671
|
if (!child.isLeaf()) {
|
|
1826
1672
|
const childBlock = child;
|
|
1827
1673
|
// Internal node
|
|
@@ -1836,10 +1682,6 @@ export class MergeTree {
|
|
|
1836
1682
|
return undefined;
|
|
1837
1683
|
}
|
|
1838
1684
|
else if (splitNode === MergeTree.theUnfinishedNode) {
|
|
1839
|
-
if (MergeTree.traceTraversal) {
|
|
1840
|
-
// eslint-disable-next-line max-len
|
|
1841
|
-
console.log(`@cli ${glc(this, this.collabWindow.clientId)} unfinished bus pos ${_pos} len ${len}`);
|
|
1842
|
-
}
|
|
1843
1685
|
_pos -= len; // Act as if shifted segment
|
|
1844
1686
|
continue;
|
|
1845
1687
|
}
|
|
@@ -1850,15 +1692,9 @@ export class MergeTree {
|
|
|
1850
1692
|
}
|
|
1851
1693
|
}
|
|
1852
1694
|
else {
|
|
1853
|
-
if (MergeTree.traceTraversal) {
|
|
1854
|
-
console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action`);
|
|
1855
|
-
}
|
|
1856
1695
|
const segment = child;
|
|
1857
1696
|
const segmentChanges = context.leaf(segment, _pos, context);
|
|
1858
1697
|
if (segmentChanges.replaceCurrent) {
|
|
1859
|
-
if (MergeTree.traceOrdinals) {
|
|
1860
|
-
console.log(`assign from leaf with block ord ${ordinalToArray(block.ordinal)}`);
|
|
1861
|
-
}
|
|
1862
1698
|
block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
|
|
1863
1699
|
segmentChanges.replaceCurrent.ordinal = child.ordinal;
|
|
1864
1700
|
}
|
|
@@ -1880,12 +1716,6 @@ export class MergeTree {
|
|
|
1880
1716
|
_pos -= len;
|
|
1881
1717
|
}
|
|
1882
1718
|
}
|
|
1883
|
-
if (MergeTree.traceTraversal) {
|
|
1884
|
-
if ((!found) && (_pos > 0)) {
|
|
1885
|
-
// eslint-disable-next-line max-len
|
|
1886
|
-
console.log(`inserting walk fell through pos ${_pos} len: ${this.blockLength(this.root, refSeq, clientId)}`);
|
|
1887
|
-
}
|
|
1888
|
-
}
|
|
1889
1719
|
if (!newNode) {
|
|
1890
1720
|
if (_pos === 0) {
|
|
1891
1721
|
if ((seq !== UnassignedSequenceNumber) && context.continuePredicate &&
|
|
@@ -1893,9 +1723,6 @@ export class MergeTree {
|
|
|
1893
1723
|
return MergeTree.theUnfinishedNode;
|
|
1894
1724
|
}
|
|
1895
1725
|
else {
|
|
1896
|
-
if (MergeTree.traceTraversal) {
|
|
1897
|
-
console.log(`@tcli: ${glc(this, this.collabWindow.clientId)}: leaf action pos 0`);
|
|
1898
|
-
}
|
|
1899
1726
|
const segmentChanges = context.leaf(undefined, _pos, context);
|
|
1900
1727
|
newNode = segmentChanges.next;
|
|
1901
1728
|
// Assert segmentChanges.replaceCurrent === undefined
|
|
@@ -1912,9 +1739,6 @@ export class MergeTree {
|
|
|
1912
1739
|
block.setOrdinal(newNode, childIndex);
|
|
1913
1740
|
if (block.childCount < MaxNodesInBlock) {
|
|
1914
1741
|
if (fromSplit) {
|
|
1915
|
-
if (MergeTree.traceOrdinals) {
|
|
1916
|
-
console.log(`split ord ${ordinalToArray(fromSplit.ordinal)}`);
|
|
1917
|
-
}
|
|
1918
1742
|
this.nodeUpdateOrdinals(fromSplit);
|
|
1919
1743
|
}
|
|
1920
1744
|
if (context.structureChange) {
|
|
@@ -1948,43 +1772,7 @@ export class MergeTree {
|
|
|
1948
1772
|
this.nodeUpdateLengthNewStructure(newNode);
|
|
1949
1773
|
return newNode;
|
|
1950
1774
|
}
|
|
1951
|
-
ordinalIntegrity() {
|
|
1952
|
-
console.log("chk ordnls");
|
|
1953
|
-
this.nodeOrdinalIntegrity(this.root);
|
|
1954
|
-
}
|
|
1955
|
-
nodeOrdinalIntegrity(block) {
|
|
1956
|
-
const olen = block.ordinal.length;
|
|
1957
|
-
for (let i = 0; i < block.childCount; i++) {
|
|
1958
|
-
const child = block.children[i];
|
|
1959
|
-
if (child.ordinal) {
|
|
1960
|
-
if (olen !== (child.ordinal.length - 1)) {
|
|
1961
|
-
console.log("node integrity issue");
|
|
1962
|
-
}
|
|
1963
|
-
if (i > 0) {
|
|
1964
|
-
if (child.ordinal <= block.children[i - 1].ordinal) {
|
|
1965
|
-
console.log("node sib integrity issue");
|
|
1966
|
-
// eslint-disable-next-line max-len
|
|
1967
|
-
console.log(`??: prnt chld prev ${ordinalToArray(block.ordinal)} ${ordinalToArray(child.ordinal)} ${(i > 0) ? ordinalToArray(block.children[i - 1].ordinal) : "NA"}`);
|
|
1968
|
-
}
|
|
1969
|
-
}
|
|
1970
|
-
if (!child.isLeaf()) {
|
|
1971
|
-
this.nodeOrdinalIntegrity(child);
|
|
1972
|
-
}
|
|
1973
|
-
}
|
|
1974
|
-
else {
|
|
1975
|
-
console.log(`node child ordinal not set ${i}`);
|
|
1976
|
-
console.log(`??: prnt ${ordinalToArray(block.ordinal)}`);
|
|
1977
|
-
}
|
|
1978
|
-
}
|
|
1979
|
-
}
|
|
1980
1775
|
nodeUpdateOrdinals(block) {
|
|
1981
|
-
if (MergeTree.traceOrdinals) {
|
|
1982
|
-
console.log(`update ordinals for children of node with ordinal ${ordinalToArray(block.ordinal)}`);
|
|
1983
|
-
}
|
|
1984
|
-
let clockStart;
|
|
1985
|
-
if (MergeTree.options.measureOrdinalTime) {
|
|
1986
|
-
clockStart = clock();
|
|
1987
|
-
}
|
|
1988
1776
|
for (let i = 0; i < block.childCount; i++) {
|
|
1989
1777
|
const child = block.children[i];
|
|
1990
1778
|
block.setOrdinal(child, i);
|
|
@@ -1992,21 +1780,11 @@ export class MergeTree {
|
|
|
1992
1780
|
this.nodeUpdateOrdinals(child);
|
|
1993
1781
|
}
|
|
1994
1782
|
}
|
|
1995
|
-
if (clockStart) {
|
|
1996
|
-
const elapsed = elapsedMicroseconds(clockStart);
|
|
1997
|
-
if (elapsed > this.maxOrdTime) {
|
|
1998
|
-
this.maxOrdTime = elapsed;
|
|
1999
|
-
}
|
|
2000
|
-
this.ordTime += elapsed;
|
|
2001
|
-
}
|
|
2002
1783
|
}
|
|
2003
1784
|
addOverlappingClient(removalInfo, clientId) {
|
|
2004
1785
|
if (!removalInfo.removedClientOverlap) {
|
|
2005
1786
|
removalInfo.removedClientOverlap = [];
|
|
2006
1787
|
}
|
|
2007
|
-
if (MergeTree.diagOverlappingRemove) {
|
|
2008
|
-
console.log(`added cli ${glc(this, clientId)} to rseq: ${removalInfo.removedSeq}`);
|
|
2009
|
-
}
|
|
2010
1788
|
removalInfo.removedClientOverlap.push(clientId);
|
|
2011
1789
|
}
|
|
2012
1790
|
/**
|
|
@@ -2066,10 +1844,6 @@ export class MergeTree {
|
|
|
2066
1844
|
const markRemoved = (segment, pos, start, end) => {
|
|
2067
1845
|
const removalInfo = segment;
|
|
2068
1846
|
if (removalInfo.removedSeq !== undefined) {
|
|
2069
|
-
if (MergeTree.diagOverlappingRemove) {
|
|
2070
|
-
// eslint-disable-next-line max-len
|
|
2071
|
-
console.log(`yump @seq ${seq} cli ${glc(this, this.collabWindow.clientId)}: overlaps deleted segment ${removalInfo.removedSeq} text '${segment.toString()}'`);
|
|
2072
|
-
}
|
|
2073
1847
|
_overwrite = true;
|
|
2074
1848
|
if (removalInfo.removedSeq === UnassignedSequenceNumber) {
|
|
2075
1849
|
// replace because comes later
|
|
@@ -2104,7 +1878,6 @@ export class MergeTree {
|
|
|
2104
1878
|
this.addToLRUSet(segment, seq);
|
|
2105
1879
|
}
|
|
2106
1880
|
}
|
|
2107
|
-
// console.log(`saved local removed seg with text: ${textSegment.text}`);
|
|
2108
1881
|
}
|
|
2109
1882
|
return true;
|
|
2110
1883
|
};
|
|
@@ -2117,7 +1890,6 @@ export class MergeTree {
|
|
|
2117
1890
|
}
|
|
2118
1891
|
return true;
|
|
2119
1892
|
};
|
|
2120
|
-
// MergeTree.traceTraversal = true;
|
|
2121
1893
|
this.mapRange({ leaf: markRemoved, post: afterMarkRemoved }, refSeq, clientId, undefined, start, end);
|
|
2122
1894
|
if (savedLocalRefs.length > 0) {
|
|
2123
1895
|
const length = this.getLength(refSeq, clientId);
|
|
@@ -2163,7 +1935,6 @@ export class MergeTree {
|
|
|
2163
1935
|
this.zamboniSegments();
|
|
2164
1936
|
}
|
|
2165
1937
|
}
|
|
2166
|
-
// MergeTree.traceTraversal = false;
|
|
2167
1938
|
}
|
|
2168
1939
|
nodeUpdateLengthNewStructure(node, recur = false) {
|
|
2169
1940
|
this.blockUpdate(node);
|
|
@@ -2252,45 +2023,6 @@ export class MergeTree {
|
|
|
2252
2023
|
}
|
|
2253
2024
|
this.nodeMap(this.root, actions, 0, refSeq, clientId, accum, start, end);
|
|
2254
2025
|
}
|
|
2255
|
-
nodeToString(block, strbuf, indentCount = 0) {
|
|
2256
|
-
let _strbuf = strbuf;
|
|
2257
|
-
_strbuf += internedSpaces(indentCount);
|
|
2258
|
-
// eslint-disable-next-line max-len
|
|
2259
|
-
_strbuf += `Node (len ${block.cachedLength}) p len (${block.parent ? block.parent.cachedLength : 0}) ord ${ordinalToArray(block.ordinal)} with ${block.childCount} segs:\n`;
|
|
2260
|
-
if (MergeTree.blockUpdateMarkers) {
|
|
2261
|
-
_strbuf += internedSpaces(indentCount);
|
|
2262
|
-
_strbuf += block.hierToString(indentCount);
|
|
2263
|
-
}
|
|
2264
|
-
if (this.collabWindow.collaborating) {
|
|
2265
|
-
_strbuf += internedSpaces(indentCount);
|
|
2266
|
-
_strbuf += `${block.partialLengths.toString((id) => glc(this, id), indentCount)}\n`;
|
|
2267
|
-
}
|
|
2268
|
-
const children = block.children;
|
|
2269
|
-
for (let childIndex = 0; childIndex < block.childCount; childIndex++) {
|
|
2270
|
-
const child = children[childIndex];
|
|
2271
|
-
if (!child.isLeaf()) {
|
|
2272
|
-
_strbuf = this.nodeToString(child, _strbuf, indentCount + 4);
|
|
2273
|
-
}
|
|
2274
|
-
else {
|
|
2275
|
-
const segment = child;
|
|
2276
|
-
_strbuf += internedSpaces(indentCount + 4);
|
|
2277
|
-
// eslint-disable-next-line max-len
|
|
2278
|
-
_strbuf += `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} ord: ${ordinalToArray(segment.ordinal)}`;
|
|
2279
|
-
const removalInfo = segment;
|
|
2280
|
-
if (removalInfo.removedSeq !== undefined) {
|
|
2281
|
-
_strbuf += ` rcli: ${glc(this, removalInfo.removedClientId)} rseq: ${removalInfo.removedSeq}`;
|
|
2282
|
-
}
|
|
2283
|
-
_strbuf += "\n";
|
|
2284
|
-
_strbuf += internedSpaces(indentCount + 4);
|
|
2285
|
-
_strbuf += segment.toString();
|
|
2286
|
-
_strbuf += "\n";
|
|
2287
|
-
}
|
|
2288
|
-
}
|
|
2289
|
-
return _strbuf;
|
|
2290
|
-
}
|
|
2291
|
-
toString() {
|
|
2292
|
-
return this.nodeToString(this.root, "", 0);
|
|
2293
|
-
}
|
|
2294
2026
|
incrementalBlockMap(stateStack) {
|
|
2295
2027
|
var _a;
|
|
2296
2028
|
while (!stateStack.empty()) {
|
|
@@ -2313,22 +2045,12 @@ export class MergeTree {
|
|
|
2313
2045
|
if ((state.op === IncrementalExecOp.Go) && (state.childIndex < state.block.childCount)) {
|
|
2314
2046
|
const child = state.block.children[state.childIndex];
|
|
2315
2047
|
const len = (_a = this.nodeLength(child, state.refSeq, state.clientId)) !== null && _a !== void 0 ? _a : 0;
|
|
2316
|
-
if (MergeTree.traceIncrTraversal) {
|
|
2317
|
-
if (child.isLeaf()) {
|
|
2318
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation, max-len
|
|
2319
|
-
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)}`);
|
|
2320
|
-
}
|
|
2321
|
-
}
|
|
2322
2048
|
if ((len > 0) && (state.start < len) && (state.end > 0)) {
|
|
2323
2049
|
if (!child.isLeaf()) {
|
|
2324
2050
|
const childState = new IncrementalMapState(child, state.actions, state.pos, state.refSeq, state.clientId, state.context, state.start, state.end, 0);
|
|
2325
2051
|
stateStack.push(childState);
|
|
2326
2052
|
}
|
|
2327
2053
|
else {
|
|
2328
|
-
if (MergeTree.traceIncrTraversal) {
|
|
2329
|
-
// eslint-disable-next-line @typescript-eslint/dot-notation
|
|
2330
|
-
console.log(`action on seg with text ${child["text"]}`);
|
|
2331
|
-
}
|
|
2332
2054
|
state.actions.leaf(child, state);
|
|
2333
2055
|
}
|
|
2334
2056
|
}
|
|
@@ -2370,21 +2092,6 @@ export class MergeTree {
|
|
|
2370
2092
|
for (let childIndex = 0; childIndex < node.childCount; childIndex++) {
|
|
2371
2093
|
const child = children[childIndex];
|
|
2372
2094
|
const len = (_a = this.nodeLength(child, refSeq, clientId)) !== null && _a !== void 0 ? _a : 0;
|
|
2373
|
-
if (MergeTree.traceTraversal) {
|
|
2374
|
-
let segInfo;
|
|
2375
|
-
if ((!child.isLeaf()) && this.collabWindow.collaborating) {
|
|
2376
|
-
segInfo = `minLength: ${child.partialLengths.minLength}`;
|
|
2377
|
-
}
|
|
2378
|
-
else {
|
|
2379
|
-
const segment = child;
|
|
2380
|
-
segInfo = `cli: ${glc(this, segment.clientId)} seq: ${segment.seq} text: '${segment.toString()}'`;
|
|
2381
|
-
if (segment.removedSeq !== undefined) {
|
|
2382
|
-
segInfo += ` rcli: ${glc(this, segment.removedClientId)} rseq: ${segment.removedSeq}`;
|
|
2383
|
-
}
|
|
2384
|
-
}
|
|
2385
|
-
// eslint-disable-next-line max-len
|
|
2386
|
-
console.log(`@tcli ${glc(this, this.collabWindow.clientId)}: map len: ${len} start: ${_start} end: ${_end} ${segInfo}`);
|
|
2387
|
-
}
|
|
2388
2095
|
if (go && (_end > 0) && (len > 0) && (_start < len)) {
|
|
2389
2096
|
// Found entry containing pos
|
|
2390
2097
|
if (!child.isLeaf()) {
|
|
@@ -2393,9 +2100,6 @@ export class MergeTree {
|
|
|
2393
2100
|
}
|
|
2394
2101
|
}
|
|
2395
2102
|
else {
|
|
2396
|
-
if (MergeTree.traceTraversal) {
|
|
2397
|
-
console.log(`@tcli ${glc(this, this.collabWindow.clientId)}: map leaf action`);
|
|
2398
|
-
}
|
|
2399
2103
|
if (actions.leaf) {
|
|
2400
2104
|
go = actions.leaf(child, _pos, refSeq, clientId, _start, _end, accum);
|
|
2401
2105
|
}
|
|
@@ -2457,18 +2161,8 @@ MergeTree.zamboniSegmentsMaxCount = 2;
|
|
|
2457
2161
|
MergeTree.options = {
|
|
2458
2162
|
incrementalUpdate: true,
|
|
2459
2163
|
insertAfterRemovedSegs: true,
|
|
2460
|
-
measureOrdinalTime: true,
|
|
2461
|
-
measureWindowTime: true,
|
|
2462
2164
|
zamboniSegments: true,
|
|
2463
2165
|
};
|
|
2464
|
-
MergeTree.traceAppend = false;
|
|
2465
|
-
MergeTree.traceZRemove = false;
|
|
2466
|
-
MergeTree.traceOrdinals = false;
|
|
2467
|
-
MergeTree.traceGatherText = false;
|
|
2468
|
-
MergeTree.diagInsertTie = false;
|
|
2469
|
-
MergeTree.diagOverlappingRemove = false;
|
|
2470
|
-
MergeTree.traceTraversal = false;
|
|
2471
|
-
MergeTree.traceIncrTraversal = false;
|
|
2472
2166
|
MergeTree.theUnfinishedNode = { childCount: -1 };
|
|
2473
2167
|
// WARNING:
|
|
2474
2168
|
// Setting blockUpdateMarkers to false will result in eventual consistency issues
|