@fluidframework/merge-tree 0.51.2 → 0.52.1
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/collections.d.ts +41 -92
- package/dist/collections.d.ts.map +1 -1
- package/dist/collections.js +4 -334
- package/dist/collections.js.map +1 -1
- package/dist/index.d.ts +10 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -12
- package/dist/index.js.map +1 -1
- package/dist/localReference.d.ts +2 -2
- package/dist/localReference.d.ts.map +1 -1
- package/dist/localReference.js +0 -1
- package/dist/localReference.js.map +1 -1
- package/dist/snapshotV1.d.ts +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts +7 -28
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js.map +1 -1
- package/lib/collections.d.ts +41 -92
- package/lib/collections.d.ts.map +1 -1
- package/lib/collections.js +5 -326
- package/lib/collections.js.map +1 -1
- package/lib/index.d.ts +10 -11
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +10 -11
- package/lib/index.js.map +1 -1
- package/lib/localReference.d.ts +2 -2
- package/lib/localReference.d.ts.map +1 -1
- package/lib/localReference.js +0 -1
- package/lib/localReference.js.map +1 -1
- package/lib/snapshotV1.d.ts +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts +7 -28
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js.map +1 -1
- package/package.json +9 -8
- package/src/collections.ts +109 -470
- package/src/index.ts +10 -11
- package/src/localReference.ts +3 -4
- package/src/snapshotV1.ts +1 -1
- package/src/snapshotlegacy.ts +9 -22
package/dist/collections.js
CHANGED
|
@@ -4,12 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.TST = exports.IntervalTree = exports.
|
|
8
|
-
/* eslint-disable @typescript-eslint/consistent-type-assertions, eqeqeq, object-shorthand */
|
|
9
|
-
/* eslint-disable no-bitwise */
|
|
10
|
-
/* Remove once strictNullCheck is enabled */
|
|
11
|
-
const common_utils_1 = require("@fluidframework/common-utils");
|
|
12
|
-
const mergeTree_1 = require("./mergeTree");
|
|
7
|
+
exports.TST = exports.IntervalTree = exports.integerRangeToString = exports.RedBlackTree = exports.RBColor = exports.Heap = exports.List = exports.ListMakeHead = exports.Stack = void 0;
|
|
13
8
|
class Stack {
|
|
14
9
|
constructor() {
|
|
15
10
|
this.items = [];
|
|
@@ -41,11 +36,9 @@ function ListRemoveEntry(entry) {
|
|
|
41
36
|
}
|
|
42
37
|
return (entry);
|
|
43
38
|
}
|
|
44
|
-
exports.ListRemoveEntry = ListRemoveEntry;
|
|
45
39
|
function ListMakeEntry(data) {
|
|
46
40
|
return new List(false, data);
|
|
47
41
|
}
|
|
48
|
-
exports.ListMakeEntry = ListMakeEntry;
|
|
49
42
|
function ListMakeHead() {
|
|
50
43
|
return new List(true, undefined);
|
|
51
44
|
}
|
|
@@ -127,13 +120,6 @@ class List {
|
|
|
127
120
|
empty() {
|
|
128
121
|
return (this.next === this);
|
|
129
122
|
}
|
|
130
|
-
pushEntry(entry) {
|
|
131
|
-
entry.isHead = false;
|
|
132
|
-
entry.next = this.next;
|
|
133
|
-
entry.prev = this;
|
|
134
|
-
this.next = entry;
|
|
135
|
-
entry.next.prev = entry;
|
|
136
|
-
}
|
|
137
123
|
push(data) {
|
|
138
124
|
const entry = ListMakeEntry(data);
|
|
139
125
|
entry.data = data;
|
|
@@ -143,47 +129,8 @@ class List {
|
|
|
143
129
|
this.next = entry;
|
|
144
130
|
entry.next.prev = entry;
|
|
145
131
|
}
|
|
146
|
-
popEntry(head) {
|
|
147
|
-
if (this.next.isHead) {
|
|
148
|
-
return undefined;
|
|
149
|
-
}
|
|
150
|
-
else {
|
|
151
|
-
return ListRemoveEntry(this.next);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
insertEntry(entry) {
|
|
155
|
-
entry.isHead = false;
|
|
156
|
-
this.prev.next = entry;
|
|
157
|
-
entry.next = this;
|
|
158
|
-
entry.prev = this.prev;
|
|
159
|
-
this.prev = entry;
|
|
160
|
-
return entry;
|
|
161
|
-
}
|
|
162
|
-
insertAfter(data) {
|
|
163
|
-
const entry = ListMakeEntry(data);
|
|
164
|
-
entry.next = this.next;
|
|
165
|
-
entry.prev = this;
|
|
166
|
-
this.next = entry;
|
|
167
|
-
entry.next.prev = entry;
|
|
168
|
-
return (entry);
|
|
169
|
-
}
|
|
170
|
-
insertBefore(data) {
|
|
171
|
-
const entry = ListMakeEntry(data);
|
|
172
|
-
return this.insertEntryBefore(entry);
|
|
173
|
-
}
|
|
174
|
-
insertEntryBefore(entry) {
|
|
175
|
-
this.prev.next = entry;
|
|
176
|
-
entry.next = this;
|
|
177
|
-
entry.prev = this.prev;
|
|
178
|
-
this.prev = entry;
|
|
179
|
-
return (entry);
|
|
180
|
-
}
|
|
181
132
|
}
|
|
182
133
|
exports.List = List;
|
|
183
|
-
exports.numberComparer = {
|
|
184
|
-
min: Number.MIN_VALUE,
|
|
185
|
-
compare: (a, b) => a - b,
|
|
186
|
-
};
|
|
187
134
|
class Heap {
|
|
188
135
|
constructor(a, comp) {
|
|
189
136
|
this.comp = comp;
|
|
@@ -236,94 +183,6 @@ class Heap {
|
|
|
236
183
|
}
|
|
237
184
|
}
|
|
238
185
|
exports.Heap = Heap;
|
|
239
|
-
// For testing
|
|
240
|
-
function LinearDictionary(compareKeys) {
|
|
241
|
-
const props = [];
|
|
242
|
-
const compareProps = (a, b) => compareKeys(a.key, b.key);
|
|
243
|
-
function diag() {
|
|
244
|
-
console.log(`size is ${props.length}`);
|
|
245
|
-
}
|
|
246
|
-
function mapRange(action, accum, start, end) {
|
|
247
|
-
let _start = start;
|
|
248
|
-
let _end = end;
|
|
249
|
-
if (props.length !== 0) {
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
if (_start === undefined) {
|
|
253
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
254
|
-
_start = min().key;
|
|
255
|
-
}
|
|
256
|
-
if (_end === undefined) {
|
|
257
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
258
|
-
_end = max().key;
|
|
259
|
-
}
|
|
260
|
-
for (let i = 0, len = props.length; i < len; i++) {
|
|
261
|
-
if (compareKeys(_start, props[i].key) <= 0) {
|
|
262
|
-
const ecmp = compareKeys(_end, props[i].key);
|
|
263
|
-
if (ecmp < 0) {
|
|
264
|
-
break;
|
|
265
|
-
}
|
|
266
|
-
if (!action(props[i], accum)) {
|
|
267
|
-
break;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
function map(action, accum) {
|
|
273
|
-
mapRange(action, accum);
|
|
274
|
-
}
|
|
275
|
-
function min() {
|
|
276
|
-
if (props.length > 0) {
|
|
277
|
-
return props[0];
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
function max() {
|
|
281
|
-
if (props.length > 0) {
|
|
282
|
-
return props[props.length - 1];
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
function get(key) {
|
|
286
|
-
for (let i = 0, len = props.length; i < len; i++) {
|
|
287
|
-
if (props[i].key == key) {
|
|
288
|
-
return props[i];
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
function put(key, data) {
|
|
293
|
-
if (key !== undefined) {
|
|
294
|
-
if (data === undefined) {
|
|
295
|
-
remove(key);
|
|
296
|
-
}
|
|
297
|
-
else {
|
|
298
|
-
props.push({ key, data });
|
|
299
|
-
props.sort(compareProps); // Go to insertion sort if too slow
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
function remove(key) {
|
|
304
|
-
if (key !== undefined) {
|
|
305
|
-
for (let i = 0, len = props.length; i < len; i++) {
|
|
306
|
-
if (props[i].key == key) {
|
|
307
|
-
props[i] = props[len - 1];
|
|
308
|
-
props.length--;
|
|
309
|
-
props.sort(compareProps);
|
|
310
|
-
break;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
return {
|
|
316
|
-
min: min,
|
|
317
|
-
max: max,
|
|
318
|
-
map: map,
|
|
319
|
-
mapRange: mapRange,
|
|
320
|
-
remove: remove,
|
|
321
|
-
get: get,
|
|
322
|
-
put: put,
|
|
323
|
-
diag: diag,
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
exports.LinearDictionary = LinearDictionary;
|
|
327
186
|
var RBColor;
|
|
328
187
|
(function (RBColor) {
|
|
329
188
|
RBColor[RBColor["RED"] = 0] = "RED";
|
|
@@ -499,18 +358,6 @@ class RedBlackTree {
|
|
|
499
358
|
this.aug.update(node);
|
|
500
359
|
}
|
|
501
360
|
}
|
|
502
|
-
removeMin() {
|
|
503
|
-
if (this.root) {
|
|
504
|
-
if ((!this.isRed(this.root.left)) && (!this.isRed(this.root.right))) {
|
|
505
|
-
this.root.color = 0 /* RED */;
|
|
506
|
-
}
|
|
507
|
-
this.root = this.nodeRemoveMin(this.root);
|
|
508
|
-
if (this.root) {
|
|
509
|
-
this.root.color = 1 /* BLACK */;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
// TODO: error on empty
|
|
513
|
-
}
|
|
514
361
|
nodeRemoveMin(node) {
|
|
515
362
|
let _node = node;
|
|
516
363
|
if (_node.left) {
|
|
@@ -522,33 +369,6 @@ class RedBlackTree {
|
|
|
522
369
|
return this.balance(_node);
|
|
523
370
|
}
|
|
524
371
|
}
|
|
525
|
-
removeMax() {
|
|
526
|
-
if (this.root) {
|
|
527
|
-
if ((!this.isRed(this.root.left)) && (!this.isRed(this.root.right))) {
|
|
528
|
-
this.root.color = 0 /* RED */;
|
|
529
|
-
}
|
|
530
|
-
this.root = this.nodeRemoveMax(this.root);
|
|
531
|
-
if (this.root) {
|
|
532
|
-
this.root.color = 1 /* BLACK */;
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
// TODO: error on empty
|
|
536
|
-
}
|
|
537
|
-
nodeRemoveMax(node) {
|
|
538
|
-
let _node = node;
|
|
539
|
-
if (this.isRed(_node.left)) {
|
|
540
|
-
_node = this.rotateRight(_node);
|
|
541
|
-
}
|
|
542
|
-
if (!_node.right) {
|
|
543
|
-
return undefined;
|
|
544
|
-
}
|
|
545
|
-
if ((!this.isRed(_node.right)) && (!this.isRed(_node.right.left))) {
|
|
546
|
-
_node = this.moveRedRight(_node);
|
|
547
|
-
}
|
|
548
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
549
|
-
_node.right = this.nodeRemoveMax(_node.right);
|
|
550
|
-
return this.balance(_node);
|
|
551
|
-
}
|
|
552
372
|
remove(key) {
|
|
553
373
|
if (key !== undefined) {
|
|
554
374
|
if (!this.contains(key)) {
|
|
@@ -886,122 +706,12 @@ class RedBlackTree {
|
|
|
886
706
|
}
|
|
887
707
|
}
|
|
888
708
|
exports.RedBlackTree = RedBlackTree;
|
|
889
|
-
/**
|
|
890
|
-
* Union of two ranges; assumes for both ranges start \<= end.
|
|
891
|
-
* @param a - A range
|
|
892
|
-
* @param b - A range
|
|
893
|
-
*/
|
|
894
|
-
function integerRangeUnion(a, b) {
|
|
895
|
-
return {
|
|
896
|
-
start: Math.min(a.start, b.start),
|
|
897
|
-
end: Math.max(a.end, b.end),
|
|
898
|
-
};
|
|
899
|
-
}
|
|
900
|
-
exports.integerRangeUnion = integerRangeUnion;
|
|
901
|
-
function integerRangeOverlaps(a, b) {
|
|
902
|
-
return (a.start < b.end) && (a.end > b.start);
|
|
903
|
-
}
|
|
904
|
-
exports.integerRangeOverlaps = integerRangeOverlaps;
|
|
905
|
-
function integerRangeComparer(a, b) {
|
|
906
|
-
if (a.start === b.start) {
|
|
907
|
-
return a.end - b.end;
|
|
908
|
-
}
|
|
909
|
-
else {
|
|
910
|
-
return a.start - b.start;
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
exports.integerRangeComparer = integerRangeComparer;
|
|
914
|
-
const integerRangeCopy = (r) => ({ start: r.start, end: r.end });
|
|
915
|
-
exports.integerRangeCopy = integerRangeCopy;
|
|
916
709
|
const integerRangeToString = (range) => `[${range.start},${range.end})`;
|
|
917
710
|
exports.integerRangeToString = integerRangeToString;
|
|
918
|
-
// TODO: handle duplicate keys
|
|
919
|
-
class IntegerRangeTree {
|
|
920
|
-
constructor() {
|
|
921
|
-
this.ranges = new RedBlackTree(integerRangeComparer, this);
|
|
922
|
-
this.diag = false;
|
|
923
|
-
}
|
|
924
|
-
remove(r) {
|
|
925
|
-
this.ranges.remove(r);
|
|
926
|
-
}
|
|
927
|
-
put(r) {
|
|
928
|
-
this.ranges.put(r, { minmax: exports.integerRangeCopy(r) });
|
|
929
|
-
}
|
|
930
|
-
toString() {
|
|
931
|
-
return this.nodeToString(this.ranges.root);
|
|
932
|
-
}
|
|
933
|
-
nodeToString(node) {
|
|
934
|
-
let buf = "";
|
|
935
|
-
let indentAmt = 0;
|
|
936
|
-
const actions = {
|
|
937
|
-
pre: (n) => {
|
|
938
|
-
let red = "";
|
|
939
|
-
if (n.color === 0 /* RED */) {
|
|
940
|
-
red = "R ";
|
|
941
|
-
}
|
|
942
|
-
buf += mergeTree_1.internedSpaces(indentAmt);
|
|
943
|
-
buf += `${red}key: ${exports.integerRangeToString(n.key)} minmax: ${exports.integerRangeToString(n.data.minmax)}\n`;
|
|
944
|
-
indentAmt += 2;
|
|
945
|
-
return true;
|
|
946
|
-
},
|
|
947
|
-
post: (n) => {
|
|
948
|
-
indentAmt -= 2;
|
|
949
|
-
return true;
|
|
950
|
-
},
|
|
951
|
-
showStructure: true,
|
|
952
|
-
};
|
|
953
|
-
this.ranges.nodeWalk(node, actions);
|
|
954
|
-
return buf;
|
|
955
|
-
}
|
|
956
|
-
matchPos(pos) {
|
|
957
|
-
return this.match({ start: pos, end: pos + 1 });
|
|
958
|
-
}
|
|
959
|
-
match(r) {
|
|
960
|
-
return this.ranges.gather(r, this);
|
|
961
|
-
}
|
|
962
|
-
matchNode(node, key) {
|
|
963
|
-
return !!node && integerRangeOverlaps(node.key, key);
|
|
964
|
-
}
|
|
965
|
-
continueSubtree(node, key) {
|
|
966
|
-
const cont = !!node && integerRangeOverlaps(node.data.minmax, key);
|
|
967
|
-
if (this.diag && (!cont)) {
|
|
968
|
-
if (node) {
|
|
969
|
-
console.log(`skipping subtree of size ${node.size} key ${exports.integerRangeToString(key)}`);
|
|
970
|
-
console.log(this.nodeToString(node));
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
return cont;
|
|
974
|
-
}
|
|
975
|
-
update(node) {
|
|
976
|
-
if (node.left && node.right) {
|
|
977
|
-
node.data.minmax = integerRangeUnion(node.key, integerRangeUnion(node.left.data.minmax, node.right.data.minmax));
|
|
978
|
-
}
|
|
979
|
-
else {
|
|
980
|
-
if (node.left) {
|
|
981
|
-
node.data.minmax = integerRangeUnion(node.key, node.left.data.minmax);
|
|
982
|
-
}
|
|
983
|
-
else if (node.right) {
|
|
984
|
-
node.data.minmax = integerRangeUnion(node.key, node.right.data.minmax);
|
|
985
|
-
}
|
|
986
|
-
else {
|
|
987
|
-
node.data.minmax = exports.integerRangeCopy(node.key);
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
exports.IntegerRangeTree = IntegerRangeTree;
|
|
993
711
|
const intervalComparer = (a, b) => a.compare(b);
|
|
994
|
-
exports.intervalComparer = intervalComparer;
|
|
995
712
|
class IntervalTree {
|
|
996
713
|
constructor() {
|
|
997
|
-
this.intervals = new RedBlackTree(
|
|
998
|
-
this.diag = false;
|
|
999
|
-
this.timePut = false;
|
|
1000
|
-
this.putTime = 0;
|
|
1001
|
-
this.putCount = 0;
|
|
1002
|
-
}
|
|
1003
|
-
printTiming() {
|
|
1004
|
-
console.log(`put total = ${this.putTime} avg=${(this.putTime / this.putCount).toFixed(2)}`);
|
|
714
|
+
this.intervals = new RedBlackTree(intervalComparer, this);
|
|
1005
715
|
}
|
|
1006
716
|
remove(x) {
|
|
1007
717
|
this.intervals.remove(x);
|
|
@@ -1019,15 +729,7 @@ class IntervalTree {
|
|
|
1019
729
|
};
|
|
1020
730
|
};
|
|
1021
731
|
}
|
|
1022
|
-
|
|
1023
|
-
const trace = common_utils_1.Trace.start();
|
|
1024
|
-
this.intervals.put(x, { minmax: x.clone() }, rbConflict);
|
|
1025
|
-
this.putTime += trace.trace().duration * 1000;
|
|
1026
|
-
this.putCount++;
|
|
1027
|
-
}
|
|
1028
|
-
else {
|
|
1029
|
-
this.intervals.put(x, { minmax: x.clone() }, rbConflict);
|
|
1030
|
-
}
|
|
732
|
+
this.intervals.put(x, { minmax: x.clone() }, rbConflict);
|
|
1031
733
|
}
|
|
1032
734
|
map(fn) {
|
|
1033
735
|
const actions = {
|
|
@@ -1066,14 +768,7 @@ class IntervalTree {
|
|
|
1066
768
|
return !!node && node.key.overlaps(key);
|
|
1067
769
|
}
|
|
1068
770
|
continueSubtree(node, key) {
|
|
1069
|
-
|
|
1070
|
-
if (this.diag && (!cont)) {
|
|
1071
|
-
if (node) {
|
|
1072
|
-
console.log(`skipping subtree of size ${node.size} key ${key.toString()}`);
|
|
1073
|
-
// console.log(this.nodeToString(node));
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
return cont;
|
|
771
|
+
return !!node && node.data.minmax.overlaps(key);
|
|
1077
772
|
}
|
|
1078
773
|
update(node) {
|
|
1079
774
|
if (node.left && node.right) {
|
|
@@ -1222,26 +917,6 @@ class TST {
|
|
|
1222
917
|
this.collectPairs(x.mid, { text: prefix.text + x.c }, q);
|
|
1223
918
|
this.collectPairs(x.right, prefix, q);
|
|
1224
919
|
}
|
|
1225
|
-
patternCollect(x, prefix, d, pattern, q) {
|
|
1226
|
-
if (x === undefined) {
|
|
1227
|
-
return;
|
|
1228
|
-
}
|
|
1229
|
-
const c = pattern.charAt(d);
|
|
1230
|
-
if ((c === ".") || (c < x.c)) {
|
|
1231
|
-
this.patternCollect(x.left, prefix, d, pattern, q);
|
|
1232
|
-
}
|
|
1233
|
-
else if ((c === ".") || (c === x.c)) {
|
|
1234
|
-
if ((d === (pattern.length - 1)) && (x.val !== undefined)) {
|
|
1235
|
-
q.push(prefix.text + x.c);
|
|
1236
|
-
}
|
|
1237
|
-
else if (d < (pattern.length - 1)) {
|
|
1238
|
-
this.patternCollect(x.mid, { text: prefix.text + x.c }, d + 1, pattern, q);
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
if ((c === ".") || (c > x.c)) {
|
|
1242
|
-
this.patternCollect(x.right, prefix, d, pattern, q);
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
920
|
nodeProximity(x, prefix, d, pattern, distance, q) {
|
|
1246
921
|
if ((x === undefined) || (distance < 0)) {
|
|
1247
922
|
return;
|
|
@@ -1271,11 +946,6 @@ class TST {
|
|
|
1271
946
|
this.nodeProximity(x.right, prefix, d, pattern, distance, q);
|
|
1272
947
|
}
|
|
1273
948
|
}
|
|
1274
|
-
match(pattern) {
|
|
1275
|
-
const q = [];
|
|
1276
|
-
this.patternCollect(this.root, { text: "" }, 0, pattern, q);
|
|
1277
|
-
return q;
|
|
1278
|
-
}
|
|
1279
949
|
}
|
|
1280
950
|
exports.TST = TST;
|
|
1281
951
|
//# sourceMappingURL=collections.js.map
|