@fluidframework/merge-tree 2.20.0 → 2.22.0
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/.eslintrc.cjs +0 -1
- package/CHANGELOG.md +8 -0
- package/README.md +1 -0
- package/dist/attributionCollection.js +5 -7
- package/dist/attributionCollection.js.map +1 -1
- package/dist/localReference.js +6 -8
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +69 -34
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +15 -4
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +1 -1
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/partialLengths.d.ts +114 -144
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +431 -525
- package/dist/partialLengths.js.map +1 -1
- package/dist/perspective.d.ts +10 -1
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +10 -1
- package/dist/perspective.js.map +1 -1
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +2 -3
- package/dist/properties.js.map +1 -1
- package/dist/revertibles.js +3 -3
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentInfos.d.ts +3 -0
- package/dist/segmentInfos.d.ts.map +1 -1
- package/dist/segmentInfos.js.map +1 -1
- package/dist/segmentPropertiesManager.js +3 -3
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotLoader.js +2 -2
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts +5 -3
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js +33 -41
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/sortedSet.d.ts +20 -3
- package/dist/sortedSet.d.ts.map +1 -1
- package/dist/sortedSet.js +23 -14
- package/dist/sortedSet.js.map +1 -1
- package/dist/test/Snapshot.perf.spec.js +1 -1
- package/dist/test/Snapshot.perf.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +20 -0
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.js +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/dist/test/client.attributionFarm.spec.js +1 -1
- package/dist/test/client.attributionFarm.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +48 -0
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.obliterateFarm.spec.d.ts +12 -0
- package/dist/test/client.obliterateFarm.spec.d.ts.map +1 -0
- package/dist/test/client.obliterateFarm.spec.js +89 -0
- package/dist/test/client.obliterateFarm.spec.js.map +1 -0
- package/dist/test/client.reconnectFarm.spec.js +1 -1
- package/dist/test/client.reconnectFarm.spec.js.map +1 -1
- package/dist/test/client.searchForMarker.spec.js +2 -2
- package/dist/test/client.searchForMarker.spec.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.d.ts +7 -2
- package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/dist/test/mergeTreeOperationRunner.js +31 -14
- package/dist/test/mergeTreeOperationRunner.js.map +1 -1
- package/dist/test/obliterate.concurrent.spec.js +45 -1
- package/dist/test/obliterate.concurrent.spec.js.map +1 -1
- package/dist/test/obliterate.rangeExpansion.spec.js +81 -5
- package/dist/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/dist/test/obliterate.spec.js +3 -3
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/obliterateOperations.d.ts +15 -0
- package/dist/test/obliterateOperations.d.ts.map +1 -0
- package/dist/test/obliterateOperations.js +132 -0
- package/dist/test/obliterateOperations.js.map +1 -0
- package/dist/test/partialSyncHelper.d.ts +42 -0
- package/dist/test/partialSyncHelper.d.ts.map +1 -0
- package/dist/test/partialSyncHelper.js +96 -0
- package/dist/test/partialSyncHelper.js.map +1 -0
- package/dist/test/revertibles.spec.js +3 -3
- package/dist/test/revertibles.spec.js.map +1 -1
- package/dist/test/sortedSegmentSet.spec.js +21 -0
- package/dist/test/sortedSegmentSet.spec.js.map +1 -1
- package/dist/test/testClient.d.ts +1 -1
- package/dist/test/testClient.d.ts.map +1 -1
- package/dist/test/testClient.js +1 -0
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testUtils.js +2 -2
- package/dist/test/testUtils.js.map +1 -1
- package/lib/attributionCollection.js +5 -7
- package/lib/attributionCollection.js.map +1 -1
- package/lib/localReference.js +6 -8
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +69 -34
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +15 -4
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +1 -1
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/partialLengths.d.ts +114 -144
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +432 -525
- package/lib/partialLengths.js.map +1 -1
- package/lib/perspective.d.ts +10 -1
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +10 -1
- package/lib/perspective.js.map +1 -1
- package/lib/properties.d.ts.map +1 -1
- package/lib/properties.js +2 -3
- package/lib/properties.js.map +1 -1
- package/lib/revertibles.js +3 -3
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentInfos.d.ts +3 -0
- package/lib/segmentInfos.d.ts.map +1 -1
- package/lib/segmentInfos.js.map +1 -1
- package/lib/segmentPropertiesManager.js +3 -3
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotLoader.js +2 -2
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts +5 -3
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js +33 -41
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/sortedSet.d.ts +20 -3
- package/lib/sortedSet.d.ts.map +1 -1
- package/lib/sortedSet.js +23 -14
- package/lib/sortedSet.js.map +1 -1
- package/lib/test/Snapshot.perf.spec.js +1 -1
- package/lib/test/Snapshot.perf.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +20 -0
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.js +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/lib/test/client.attributionFarm.spec.js +1 -1
- package/lib/test/client.attributionFarm.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +48 -0
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.obliterateFarm.spec.d.ts +12 -0
- package/lib/test/client.obliterateFarm.spec.d.ts.map +1 -0
- package/lib/test/client.obliterateFarm.spec.js +88 -0
- package/lib/test/client.obliterateFarm.spec.js.map +1 -0
- package/lib/test/client.reconnectFarm.spec.js +1 -1
- package/lib/test/client.reconnectFarm.spec.js.map +1 -1
- package/lib/test/client.searchForMarker.spec.js +2 -2
- package/lib/test/client.searchForMarker.spec.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.d.ts +7 -2
- package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/lib/test/mergeTreeOperationRunner.js +31 -14
- package/lib/test/mergeTreeOperationRunner.js.map +1 -1
- package/lib/test/obliterate.concurrent.spec.js +45 -1
- package/lib/test/obliterate.concurrent.spec.js.map +1 -1
- package/lib/test/obliterate.rangeExpansion.spec.js +81 -5
- package/lib/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/lib/test/obliterate.spec.js +3 -3
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/obliterateOperations.d.ts +15 -0
- package/lib/test/obliterateOperations.d.ts.map +1 -0
- package/lib/test/obliterateOperations.js +123 -0
- package/lib/test/obliterateOperations.js.map +1 -0
- package/lib/test/partialSyncHelper.d.ts +42 -0
- package/lib/test/partialSyncHelper.d.ts.map +1 -0
- package/lib/test/partialSyncHelper.js +92 -0
- package/lib/test/partialSyncHelper.js.map +1 -0
- package/lib/test/revertibles.spec.js +3 -3
- package/lib/test/revertibles.spec.js.map +1 -1
- package/lib/test/sortedSegmentSet.spec.js +21 -0
- package/lib/test/sortedSegmentSet.spec.js.map +1 -1
- package/lib/test/testClient.d.ts +1 -1
- package/lib/test/testClient.d.ts.map +1 -1
- package/lib/test/testClient.js +1 -0
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testUtils.js +2 -2
- package/lib/test/testUtils.js.map +1 -1
- package/package.json +21 -79
- package/src/mergeTree.ts +80 -28
- package/src/mergeTreeNodes.ts +15 -4
- package/src/partialLengths.ts +559 -776
- package/src/perspective.ts +10 -1
- package/src/properties.ts +2 -3
- package/src/segmentInfos.ts +3 -0
- package/src/snapshotLoader.ts +1 -1
- package/src/sortedSegmentSet.ts +41 -50
- package/src/sortedSet.ts +32 -16
package/src/perspective.ts
CHANGED
|
@@ -35,7 +35,8 @@ export interface SeqTime {
|
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
37
|
* Implementation of {@link Perspective}.
|
|
38
|
-
*
|
|
38
|
+
* @privateRemarks
|
|
39
|
+
* TODO:AB#29765: This class does not support non-local-client perspectives, but should.
|
|
39
40
|
*/
|
|
40
41
|
export class PerspectiveImpl implements Perspective {
|
|
41
42
|
/**
|
|
@@ -85,6 +86,8 @@ export class PerspectiveImpl implements Perspective {
|
|
|
85
86
|
* @param seq - The latest sequence number to consider.
|
|
86
87
|
* @param localSeq - The latest local sequence number to consider.
|
|
87
88
|
* @returns true iff this segment was removed in the given perspective.
|
|
89
|
+
* @privateRemarks
|
|
90
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
88
91
|
*/
|
|
89
92
|
export function wasRemovedBefore(
|
|
90
93
|
seg: SegmentWithInfo<IInsertionInfo & IRemovalInfo>,
|
|
@@ -106,6 +109,8 @@ export function wasRemovedBefore(
|
|
|
106
109
|
* @param refSeq - The latest sequence number to consider.
|
|
107
110
|
* @param localSeq - The latest local sequence number to consider.
|
|
108
111
|
* @returns true iff this segment was moved (aka obliterated) in the given perspective.
|
|
112
|
+
* @privateRemarks
|
|
113
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
109
114
|
*/
|
|
110
115
|
export function wasMovedBefore(
|
|
111
116
|
seg: SegmentWithInfo<IInsertionInfo & IMoveInfo>,
|
|
@@ -123,6 +128,8 @@ export function wasMovedBefore(
|
|
|
123
128
|
|
|
124
129
|
/**
|
|
125
130
|
* See {@link wasRemovedBefore} and {@link wasMovedBefore}.
|
|
131
|
+
* @privateRemarks
|
|
132
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
126
133
|
*/
|
|
127
134
|
export function wasRemovedOrMovedBefore(seg: ISegmentLeaf, seqTime: SeqTime): boolean {
|
|
128
135
|
return (
|
|
@@ -138,6 +145,8 @@ export function wasRemovedOrMovedBefore(seg: ISegmentLeaf, seqTime: SeqTime): bo
|
|
|
138
145
|
* @param seqTime - The latest sequence number and local sequence number to consider.
|
|
139
146
|
* @returns true iff this segment was inserted before the given perspective,
|
|
140
147
|
* and it was not removed or moved in the given perspective.
|
|
148
|
+
* @privateRemarks
|
|
149
|
+
* TODO:AB#29765: This function does not support non-local-client perspectives, but should.
|
|
141
150
|
*/
|
|
142
151
|
export function isSegmentPresent(seg: ISegmentLeaf, seqTime: SeqTime): boolean {
|
|
143
152
|
const { refSeq, localSeq } = seqTime;
|
package/src/properties.ts
CHANGED
|
@@ -119,10 +119,9 @@ export function extendIfUndefined<T>(
|
|
|
119
119
|
extension: MapLike<T> | undefined,
|
|
120
120
|
): MapLike<T> {
|
|
121
121
|
if (extension !== undefined) {
|
|
122
|
-
|
|
123
|
-
for (const key in extension) {
|
|
122
|
+
for (const [key, value] of Object.entries(extension)) {
|
|
124
123
|
if (base[key] === undefined) {
|
|
125
|
-
base[key] =
|
|
124
|
+
base[key] = value;
|
|
126
125
|
}
|
|
127
126
|
}
|
|
128
127
|
}
|
package/src/segmentInfos.ts
CHANGED
|
@@ -310,6 +310,9 @@ export interface IMoveInfo {
|
|
|
310
310
|
* If a segment is moved on insertion, its length is only ever visible to
|
|
311
311
|
* the client that inserted the segment. This is relevant in partial length
|
|
312
312
|
* calculations
|
|
313
|
+
*
|
|
314
|
+
* @privateRemarks
|
|
315
|
+
* TODO:AB#29553: This property is not persisted in the summary, but it should be.
|
|
313
316
|
*/
|
|
314
317
|
wasMovedOnInsert: boolean;
|
|
315
318
|
}
|
package/src/snapshotLoader.ts
CHANGED
|
@@ -140,7 +140,7 @@ export class SnapshotLoader {
|
|
|
140
140
|
movedClientIds: spec.movedClientIds.map((id) =>
|
|
141
141
|
this.client.getOrAddShortClientId(id),
|
|
142
142
|
),
|
|
143
|
-
//
|
|
143
|
+
// TODO:AB#29553: This property should be derived from segment data, not hard-coded.
|
|
144
144
|
wasMovedOnInsert: false,
|
|
145
145
|
});
|
|
146
146
|
}
|
package/src/sortedSegmentSet.ts
CHANGED
|
@@ -28,11 +28,10 @@ export type SortedSegmentSetItem =
|
|
|
28
28
|
*
|
|
29
29
|
* @internal
|
|
30
30
|
*/
|
|
31
|
-
|
|
32
31
|
export class SortedSegmentSet<
|
|
33
32
|
T extends SortedSegmentSetItem = ISegmentInternal,
|
|
34
|
-
> extends SortedSet<T
|
|
35
|
-
|
|
33
|
+
> extends SortedSet<T> {
|
|
34
|
+
private getOrdinal(item: T): string {
|
|
36
35
|
const maybeRef = item as Partial<LocalReferencePosition>;
|
|
37
36
|
if (maybeRef.getSegment !== undefined && maybeRef.isLeaf?.() === false) {
|
|
38
37
|
const lref = maybeRef as LocalReferencePosition;
|
|
@@ -49,55 +48,47 @@ export class SortedSegmentSet<
|
|
|
49
48
|
return toMergeNodeInfo(item)?.ordinal ?? "";
|
|
50
49
|
}
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
private getOffset(item: T): number {
|
|
52
|
+
const maybeRef = item as Partial<LocalReferencePosition>;
|
|
53
|
+
if (maybeRef.getSegment !== undefined && maybeRef.isLeaf?.() === false) {
|
|
54
|
+
const lref = maybeRef as LocalReferencePosition;
|
|
55
|
+
return lref.getOffset();
|
|
55
56
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
protected compare(a: T, b: T): number {
|
|
61
|
+
const aOrdinal = this.getOrdinal(a);
|
|
62
|
+
const bOrdinal = this.getOrdinal(b);
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
for (
|
|
91
|
-
index + 1;
|
|
92
|
-
index < this.keySortedItems.length &&
|
|
93
|
-
this.getKey(this.keySortedItems[index]) === itemKey;
|
|
94
|
-
index++
|
|
95
|
-
) {
|
|
96
|
-
if (this.keySortedItems[index] === item) {
|
|
97
|
-
return { exists: true, index };
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return { exists: false, index };
|
|
64
|
+
if (aOrdinal < bOrdinal) {
|
|
65
|
+
return -1;
|
|
66
|
+
}
|
|
67
|
+
if (aOrdinal > bOrdinal) {
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
return this.getOffset(a) - this.getOffset(b);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
protected onFindEquivalent(item: T, startIndex: number): { exists: boolean; index: number } {
|
|
74
|
+
// SortedSegmentSet may contain multiple items with the same key (e.g. a local ref at offset 0 and the segment it is on).
|
|
75
|
+
// Items should compare as reference-equal, so we do a linear walk to find the actual item in this case.
|
|
76
|
+
let index = startIndex;
|
|
77
|
+
if (item === this.sortedItems[index]) {
|
|
78
|
+
return { exists: true, index };
|
|
79
|
+
}
|
|
80
|
+
for (let b = index - 1; b >= 0 && this.compare(item, this.sortedItems[b]) === 0; b--) {
|
|
81
|
+
if (this.sortedItems[b] === item) {
|
|
82
|
+
return { exists: true, index: b };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
for (
|
|
86
|
+
index + 1;
|
|
87
|
+
index < this.sortedItems.length && this.compare(item, this.sortedItems[index]) === 0;
|
|
88
|
+
index++
|
|
89
|
+
) {
|
|
90
|
+
if (this.sortedItems[index] === item) {
|
|
91
|
+
return { exists: true, index };
|
|
101
92
|
}
|
|
102
93
|
}
|
|
103
94
|
return { exists: false, index };
|
package/src/sortedSet.ts
CHANGED
|
@@ -6,32 +6,38 @@
|
|
|
6
6
|
/**
|
|
7
7
|
* @internal
|
|
8
8
|
*/
|
|
9
|
-
export abstract class SortedSet<T
|
|
10
|
-
|
|
9
|
+
export abstract class SortedSet<T> {
|
|
10
|
+
/**
|
|
11
|
+
* Standard comparator semantics:
|
|
12
|
+
* - If a \< b, return a negative number
|
|
13
|
+
* - If a \> b, return a positive number
|
|
14
|
+
* - If a and b are equivalent, return 0
|
|
15
|
+
*/
|
|
16
|
+
protected abstract compare(a: T, b: T): number;
|
|
11
17
|
|
|
12
|
-
protected readonly
|
|
18
|
+
protected readonly sortedItems: T[] = [];
|
|
13
19
|
|
|
14
20
|
public get size(): number {
|
|
15
|
-
return this.
|
|
21
|
+
return this.sortedItems.length;
|
|
16
22
|
}
|
|
17
23
|
|
|
18
24
|
public get items(): readonly T[] {
|
|
19
|
-
return this.
|
|
25
|
+
return this.sortedItems;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
public addOrUpdate(newItem: T, update?: (existingItem: T, newItem: T) => void): void {
|
|
23
29
|
const position = this.findItemPosition(newItem);
|
|
24
30
|
if (position.exists) {
|
|
25
|
-
update?.(this.
|
|
31
|
+
update?.(this.sortedItems[position.index], newItem);
|
|
26
32
|
} else {
|
|
27
|
-
this.
|
|
33
|
+
this.sortedItems.splice(position.index, 0, newItem);
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
|
|
31
37
|
public remove(item: T): boolean {
|
|
32
38
|
const position = this.findItemPosition(item);
|
|
33
39
|
if (position.exists) {
|
|
34
|
-
this.
|
|
40
|
+
this.sortedItems.splice(position.index, 1);
|
|
35
41
|
return true;
|
|
36
42
|
}
|
|
37
43
|
return false;
|
|
@@ -43,31 +49,41 @@ export abstract class SortedSet<T, U extends string | number> {
|
|
|
43
49
|
}
|
|
44
50
|
|
|
45
51
|
protected findItemPosition(item: T): { exists: boolean; index: number } {
|
|
46
|
-
if (this.
|
|
52
|
+
if (this.sortedItems.length === 0) {
|
|
47
53
|
return { exists: false, index: 0 };
|
|
48
54
|
}
|
|
49
55
|
let start = 0;
|
|
50
|
-
let end = this.
|
|
51
|
-
const itemKey = this.getKey(item);
|
|
56
|
+
let end = this.sortedItems.length - 1;
|
|
52
57
|
let index = -1;
|
|
53
58
|
|
|
54
59
|
while (start <= end) {
|
|
55
60
|
index = start + Math.floor((end - start) / 2);
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
61
|
+
const compareResult = this.compare(item, this.sortedItems[index]);
|
|
62
|
+
if (compareResult < 0) {
|
|
58
63
|
if (start === index) {
|
|
59
64
|
return { exists: false, index };
|
|
60
65
|
}
|
|
61
66
|
end = index - 1;
|
|
62
|
-
} else if (
|
|
67
|
+
} else if (compareResult > 0) {
|
|
63
68
|
if (index === end) {
|
|
64
69
|
return { exists: false, index: index + 1 };
|
|
65
70
|
}
|
|
66
71
|
start = index + 1;
|
|
67
|
-
} else if (
|
|
68
|
-
return
|
|
72
|
+
} else if (compareResult === 0) {
|
|
73
|
+
return this.onFindEquivalent(item, index);
|
|
69
74
|
}
|
|
70
75
|
}
|
|
71
76
|
return { exists: false, index };
|
|
72
77
|
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Invoked when `findItemPosition` finds an equivalent item (i.e. `compare` returns 0 between that item and the search item).
|
|
81
|
+
*
|
|
82
|
+
* By default, `SortedSet` assumes that equivalent items are equal and returns the found index.
|
|
83
|
+
* @param item - The item that is being searched for (argument to `findItemPosition`)
|
|
84
|
+
* @param index - The index of the equivalent item in the sorted set
|
|
85
|
+
*/
|
|
86
|
+
protected onFindEquivalent(item: T, index: number): { exists: boolean; index: number } {
|
|
87
|
+
return { exists: true, index };
|
|
88
|
+
}
|
|
73
89
|
}
|