@fluidframework/merge-tree 1.2.7 → 2.0.0-dev.1.3.0.96595

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/.mocharc.js +12 -0
  2. package/README.md +2 -2
  3. package/dist/MergeTreeTextHelper.d.ts +23 -0
  4. package/dist/MergeTreeTextHelper.d.ts.map +1 -0
  5. package/dist/MergeTreeTextHelper.js +133 -0
  6. package/dist/MergeTreeTextHelper.js.map +1 -0
  7. package/dist/base.d.ts +2 -26
  8. package/dist/base.d.ts.map +1 -1
  9. package/dist/base.js.map +1 -1
  10. package/dist/client.d.ts +27 -16
  11. package/dist/client.d.ts.map +1 -1
  12. package/dist/client.js +81 -101
  13. package/dist/client.js.map +1 -1
  14. package/dist/collections/heap.d.ts +28 -0
  15. package/dist/collections/heap.d.ts.map +1 -0
  16. package/dist/collections/heap.js +65 -0
  17. package/dist/collections/heap.js.map +1 -0
  18. package/dist/collections/index.d.ts +11 -0
  19. package/dist/collections/index.d.ts.map +1 -0
  20. package/dist/collections/index.js +23 -0
  21. package/dist/collections/index.js.map +1 -0
  22. package/dist/collections/intervalTree.d.ts +60 -0
  23. package/dist/collections/intervalTree.d.ts.map +1 -0
  24. package/dist/collections/intervalTree.js +99 -0
  25. package/dist/collections/intervalTree.js.map +1 -0
  26. package/dist/collections/list.d.ts +39 -0
  27. package/dist/collections/list.d.ts.map +1 -0
  28. package/dist/collections/list.js +155 -0
  29. package/dist/collections/list.js.map +1 -0
  30. package/dist/collections/rbTree.d.ts +154 -0
  31. package/dist/collections/rbTree.d.ts.map +1 -0
  32. package/dist/{collections.js → collections/rbTree.js} +15 -478
  33. package/dist/collections/rbTree.js.map +1 -0
  34. package/dist/collections/stack.d.ts +16 -0
  35. package/dist/collections/stack.d.ts.map +1 -0
  36. package/dist/collections/stack.js +30 -0
  37. package/dist/collections/stack.js.map +1 -0
  38. package/dist/collections/tst.d.ts +55 -0
  39. package/dist/collections/tst.d.ts.map +1 -0
  40. package/dist/collections/tst.js +171 -0
  41. package/dist/collections/tst.js.map +1 -0
  42. package/dist/index.d.ts +3 -1
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +4 -2
  45. package/dist/index.js.map +1 -1
  46. package/dist/localReference.d.ts +48 -99
  47. package/dist/localReference.d.ts.map +1 -1
  48. package/dist/localReference.js +132 -169
  49. package/dist/localReference.js.map +1 -1
  50. package/dist/mergeTree.d.ts +71 -302
  51. package/dist/mergeTree.d.ts.map +1 -1
  52. package/dist/mergeTree.js +395 -642
  53. package/dist/mergeTree.js.map +1 -1
  54. package/dist/mergeTreeDeltaCallback.d.ts +1 -1
  55. package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
  56. package/dist/mergeTreeDeltaCallback.js.map +1 -1
  57. package/dist/mergeTreeNodes.d.ts +344 -0
  58. package/dist/mergeTreeNodes.d.ts.map +1 -0
  59. package/dist/mergeTreeNodes.js +383 -0
  60. package/dist/mergeTreeNodes.js.map +1 -0
  61. package/dist/mergeTreeTracking.d.ts +1 -1
  62. package/dist/mergeTreeTracking.d.ts.map +1 -1
  63. package/dist/mergeTreeTracking.js.map +1 -1
  64. package/dist/opBuilder.d.ts +1 -1
  65. package/dist/opBuilder.d.ts.map +1 -1
  66. package/dist/opBuilder.js.map +1 -1
  67. package/dist/partialLengths.d.ts +188 -18
  68. package/dist/partialLengths.d.ts.map +1 -1
  69. package/dist/partialLengths.js +495 -253
  70. package/dist/partialLengths.js.map +1 -1
  71. package/dist/properties.d.ts.map +1 -1
  72. package/dist/properties.js.map +1 -1
  73. package/dist/referencePositions.d.ts +6 -26
  74. package/dist/referencePositions.d.ts.map +1 -1
  75. package/dist/referencePositions.js +3 -20
  76. package/dist/referencePositions.js.map +1 -1
  77. package/dist/segmentGroupCollection.d.ts +3 -1
  78. package/dist/segmentGroupCollection.d.ts.map +1 -1
  79. package/dist/segmentGroupCollection.js +14 -1
  80. package/dist/segmentGroupCollection.js.map +1 -1
  81. package/dist/segmentPropertiesManager.d.ts +10 -1
  82. package/dist/segmentPropertiesManager.d.ts.map +1 -1
  83. package/dist/segmentPropertiesManager.js +42 -13
  84. package/dist/segmentPropertiesManager.js.map +1 -1
  85. package/dist/snapshotChunks.d.ts +2 -1
  86. package/dist/snapshotChunks.d.ts.map +1 -1
  87. package/dist/snapshotChunks.js.map +1 -1
  88. package/dist/snapshotLoader.d.ts.map +1 -1
  89. package/dist/snapshotLoader.js.map +1 -1
  90. package/dist/snapshotV1.d.ts +1 -1
  91. package/dist/snapshotV1.d.ts.map +1 -1
  92. package/dist/snapshotV1.js +1 -1
  93. package/dist/snapshotV1.js.map +1 -1
  94. package/dist/snapshotlegacy.d.ts +5 -1
  95. package/dist/snapshotlegacy.d.ts.map +1 -1
  96. package/dist/snapshotlegacy.js +4 -0
  97. package/dist/snapshotlegacy.js.map +1 -1
  98. package/dist/sortedSegmentSet.d.ts +1 -1
  99. package/dist/sortedSegmentSet.d.ts.map +1 -1
  100. package/dist/sortedSegmentSet.js.map +1 -1
  101. package/dist/textSegment.d.ts +7 -7
  102. package/dist/textSegment.d.ts.map +1 -1
  103. package/dist/textSegment.js +3 -125
  104. package/dist/textSegment.js.map +1 -1
  105. package/{DEV.md → docs/DEV.md} +2 -2
  106. package/docs/Obliterate.md +639 -0
  107. package/{REFERENCEPOSITIONS.md → docs/REFERENCEPOSITIONS.md} +2 -2
  108. package/lib/MergeTreeTextHelper.d.ts +23 -0
  109. package/lib/MergeTreeTextHelper.d.ts.map +1 -0
  110. package/lib/MergeTreeTextHelper.js +129 -0
  111. package/lib/MergeTreeTextHelper.js.map +1 -0
  112. package/lib/base.d.ts +2 -26
  113. package/lib/base.d.ts.map +1 -1
  114. package/lib/base.js.map +1 -1
  115. package/lib/client.d.ts +27 -16
  116. package/lib/client.d.ts.map +1 -1
  117. package/lib/client.js +79 -99
  118. package/lib/client.js.map +1 -1
  119. package/lib/collections/heap.d.ts +28 -0
  120. package/lib/collections/heap.d.ts.map +1 -0
  121. package/lib/collections/heap.js +61 -0
  122. package/lib/collections/heap.js.map +1 -0
  123. package/lib/collections/index.d.ts +11 -0
  124. package/lib/collections/index.d.ts.map +1 -0
  125. package/lib/collections/index.js +11 -0
  126. package/lib/collections/index.js.map +1 -0
  127. package/lib/collections/intervalTree.d.ts +60 -0
  128. package/lib/collections/intervalTree.d.ts.map +1 -0
  129. package/lib/collections/intervalTree.js +94 -0
  130. package/lib/collections/intervalTree.js.map +1 -0
  131. package/lib/collections/list.d.ts +39 -0
  132. package/lib/collections/list.d.ts.map +1 -0
  133. package/lib/collections/list.js +149 -0
  134. package/lib/collections/list.js.map +1 -0
  135. package/lib/collections/rbTree.d.ts +154 -0
  136. package/lib/collections/rbTree.d.ts.map +1 -0
  137. package/lib/{collections.js → collections/rbTree.js} +14 -469
  138. package/lib/collections/rbTree.js.map +1 -0
  139. package/lib/collections/stack.d.ts +16 -0
  140. package/lib/collections/stack.d.ts.map +1 -0
  141. package/lib/collections/stack.js +26 -0
  142. package/lib/collections/stack.js.map +1 -0
  143. package/lib/collections/tst.d.ts +55 -0
  144. package/lib/collections/tst.d.ts.map +1 -0
  145. package/lib/collections/tst.js +167 -0
  146. package/lib/collections/tst.js.map +1 -0
  147. package/lib/index.d.ts +3 -1
  148. package/lib/index.d.ts.map +1 -1
  149. package/lib/index.js +3 -1
  150. package/lib/index.js.map +1 -1
  151. package/lib/localReference.d.ts +48 -99
  152. package/lib/localReference.d.ts.map +1 -1
  153. package/lib/localReference.js +132 -170
  154. package/lib/localReference.js.map +1 -1
  155. package/lib/mergeTree.d.ts +71 -302
  156. package/lib/mergeTree.d.ts.map +1 -1
  157. package/lib/mergeTree.js +371 -607
  158. package/lib/mergeTree.js.map +1 -1
  159. package/lib/mergeTreeDeltaCallback.d.ts +1 -1
  160. package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
  161. package/lib/mergeTreeDeltaCallback.js.map +1 -1
  162. package/lib/mergeTreeNodes.d.ts +344 -0
  163. package/lib/mergeTreeNodes.d.ts.map +1 -0
  164. package/lib/mergeTreeNodes.js +369 -0
  165. package/lib/mergeTreeNodes.js.map +1 -0
  166. package/lib/mergeTreeTracking.d.ts +1 -1
  167. package/lib/mergeTreeTracking.d.ts.map +1 -1
  168. package/lib/mergeTreeTracking.js.map +1 -1
  169. package/lib/opBuilder.d.ts +1 -1
  170. package/lib/opBuilder.d.ts.map +1 -1
  171. package/lib/opBuilder.js.map +1 -1
  172. package/lib/partialLengths.d.ts +188 -18
  173. package/lib/partialLengths.d.ts.map +1 -1
  174. package/lib/partialLengths.js +491 -249
  175. package/lib/partialLengths.js.map +1 -1
  176. package/lib/properties.d.ts.map +1 -1
  177. package/lib/properties.js.map +1 -1
  178. package/lib/referencePositions.d.ts +6 -26
  179. package/lib/referencePositions.d.ts.map +1 -1
  180. package/lib/referencePositions.js +3 -20
  181. package/lib/referencePositions.js.map +1 -1
  182. package/lib/segmentGroupCollection.d.ts +3 -1
  183. package/lib/segmentGroupCollection.d.ts.map +1 -1
  184. package/lib/segmentGroupCollection.js +14 -1
  185. package/lib/segmentGroupCollection.js.map +1 -1
  186. package/lib/segmentPropertiesManager.d.ts +10 -1
  187. package/lib/segmentPropertiesManager.d.ts.map +1 -1
  188. package/lib/segmentPropertiesManager.js +42 -13
  189. package/lib/segmentPropertiesManager.js.map +1 -1
  190. package/lib/snapshotChunks.d.ts +2 -1
  191. package/lib/snapshotChunks.d.ts.map +1 -1
  192. package/lib/snapshotChunks.js.map +1 -1
  193. package/lib/snapshotLoader.d.ts.map +1 -1
  194. package/lib/snapshotLoader.js.map +1 -1
  195. package/lib/snapshotV1.d.ts +1 -1
  196. package/lib/snapshotV1.d.ts.map +1 -1
  197. package/lib/snapshotV1.js +1 -1
  198. package/lib/snapshotV1.js.map +1 -1
  199. package/lib/snapshotlegacy.d.ts +5 -1
  200. package/lib/snapshotlegacy.d.ts.map +1 -1
  201. package/lib/snapshotlegacy.js +4 -0
  202. package/lib/snapshotlegacy.js.map +1 -1
  203. package/lib/sortedSegmentSet.d.ts +1 -1
  204. package/lib/sortedSegmentSet.d.ts.map +1 -1
  205. package/lib/sortedSegmentSet.js.map +1 -1
  206. package/lib/textSegment.d.ts +7 -7
  207. package/lib/textSegment.d.ts.map +1 -1
  208. package/lib/textSegment.js +1 -122
  209. package/lib/textSegment.js.map +1 -1
  210. package/package.json +99 -20
  211. package/src/MergeTreeTextHelper.ts +170 -0
  212. package/src/base.ts +2 -35
  213. package/src/client.ts +91 -111
  214. package/src/collections/heap.ts +75 -0
  215. package/src/collections/index.ts +11 -0
  216. package/src/collections/intervalTree.ts +146 -0
  217. package/src/collections/list.ts +165 -0
  218. package/src/{collections.ts → collections/rbTree.ts} +84 -563
  219. package/src/collections/stack.ts +27 -0
  220. package/src/collections/tst.ts +212 -0
  221. package/src/index.ts +8 -2
  222. package/src/localReference.ts +152 -203
  223. package/src/mergeTree.ts +578 -996
  224. package/src/mergeTreeDeltaCallback.ts +1 -1
  225. package/src/mergeTreeNodes.ts +752 -0
  226. package/src/mergeTreeTracking.ts +1 -1
  227. package/src/opBuilder.ts +1 -1
  228. package/src/partialLengths.ts +631 -258
  229. package/src/properties.ts +1 -0
  230. package/src/referencePositions.ts +10 -44
  231. package/src/segmentGroupCollection.ts +17 -2
  232. package/src/segmentPropertiesManager.ts +46 -12
  233. package/src/snapshotChunks.ts +2 -1
  234. package/src/snapshotLoader.ts +2 -1
  235. package/src/snapshotV1.ts +3 -3
  236. package/src/snapshotlegacy.ts +6 -2
  237. package/src/sortedSegmentSet.ts +1 -1
  238. package/src/textSegment.ts +10 -157
  239. package/dist/collections.d.ts +0 -197
  240. package/dist/collections.d.ts.map +0 -1
  241. package/dist/collections.js.map +0 -1
  242. package/lib/collections.d.ts +0 -197
  243. package/lib/collections.d.ts.map +0 -1
  244. package/lib/collections.js.map +0 -1
@@ -7,250 +7,22 @@
7
7
 
8
8
  /* Remove once strictNullCheck is enabled */
9
9
 
10
- import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
11
- import {
12
- ConflictAction,
13
- IIntegerRange,
14
- KeyComparer,
15
- PropertyAction,
16
- SortedDictionary,
17
- } from "./base";
18
-
19
- export class Stack<T> {
20
- public items: T[] = [];
21
- public push(val: T) {
22
- this.items.push(val);
23
- }
24
-
25
- public empty() {
26
- return this.items.length === 0;
27
- }
28
-
29
- public top(): T | undefined {
30
- return this.items[this.items.length - 1];
31
- }
32
-
33
- public pop(): T | undefined {
34
- return this.items.pop();
35
- }
36
- }
37
-
38
- export function ListRemoveEntry<U>(entry: List<U>): List<U> | undefined {
39
- if (entry === undefined) {
40
- return undefined;
41
- } else if (entry.isHead) {
42
- return undefined;
43
- } else {
44
- entry.next.prev = entry.prev;
45
- entry.prev.next = entry.next;
46
- }
47
- return (entry);
48
- }
49
-
50
- function ListMakeEntry<U>(data: U): List<U> {
51
- return new List<U>(false, data);
52
- }
53
-
54
- export function ListMakeHead<U>(): List<U> {
55
- return new List<U>(true, undefined);
56
- }
57
-
58
- export class List<T> {
59
- public next: List<T>;
60
- public prev: List<T>;
61
-
62
- constructor(public isHead: boolean, public data: T | undefined) {
63
- this.prev = this;
64
- this.next = this;
65
- }
66
-
67
- public clear(): void {
68
- if (this.isHead) {
69
- this.prev = this;
70
- this.next = this;
71
- }
72
- }
73
-
74
- private add(data: T): List<T> {
75
- const entry = ListMakeEntry(data);
76
- this.prev.next = entry;
77
- entry.next = this;
78
- entry.prev = this.prev;
79
- this.prev = entry;
80
- return (entry);
81
- }
82
-
83
- public dequeue(): T | undefined {
84
- if (!this.empty()) {
85
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
86
- const removedEntry = ListRemoveEntry(this.next)!;
87
- return removedEntry.data;
88
- }
89
- }
90
-
91
- public enqueue(data: T): List<T> {
92
- return this.add(data);
93
- }
94
-
95
- public walk(fn: (data: T, l: List<T>) => void): void {
96
- for (let entry = this.next; !(entry.isHead); entry = entry.next) {
97
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
98
- fn(entry.data!, entry);
99
- }
100
- }
101
-
102
- public some(fn: (data: T, l: List<T>) => boolean, rev?: boolean): T[] {
103
- const rtn: T[] = [];
104
- const start = rev ? this.prev : this.next;
105
- for (let entry = start; !(entry.isHead); entry = rev ? entry.prev : entry.next) {
106
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
107
- const data = entry.data!;
108
- if (fn(data, entry)) {
109
- if (rev) {
110
- // preserve list order when in reverse
111
- rtn.unshift(data);
112
- } else {
113
- rtn.push(data);
114
- }
115
- }
116
- }
117
- return rtn;
118
- }
119
-
120
- public count(): number {
121
- let entry: List<T>;
122
- let i: number;
123
-
124
- entry = this.next;
125
- for (i = 0; !(entry.isHead); i++) {
126
- entry = entry.next;
127
- }
128
- return (i);
129
- }
130
-
131
- public first(): T | undefined {
132
- if (!this.empty()) {
133
- return (this.next.data);
134
- }
135
- }
136
-
137
- public last(): T | undefined {
138
- if (!this.empty()) {
139
- return (this.prev.data);
140
- }
141
- }
142
-
143
- public empty(): boolean {
144
- return (this.next === this);
145
- }
146
-
147
- /**
148
- * @deprecated - use unshift
149
- */
150
- public push(data: T): void {
151
- this.unshift(data);
152
- }
153
-
154
- public unshift(data: T): void {
155
- const entry = ListMakeEntry(data);
156
- entry.data = data;
157
- entry.isHead = false;
158
- entry.next = this.next;
159
- entry.prev = this;
160
- this.next = entry;
161
- entry.next.prev = entry;
162
- }
163
-
164
- public [Symbol.iterator]() {
165
- // eslint-disable-next-line @typescript-eslint/no-this-alias
166
- let node: List<T> | undefined = this;
167
- const iterator: IterableIterator<T> = {
168
- next(): IteratorResult<T> {
169
- while (node && node.next.isHead === false) {
170
- node = node.next;
171
- if (node.data !== undefined) {
172
- return { value: node.data, done: false };
173
- }
174
- }
175
- return { value: undefined, done: true };
176
- },
177
- [Symbol.iterator]() {
178
- return this;
179
- },
180
- };
181
- return iterator;
182
- }
183
- }
184
-
185
- export interface Comparer<T> {
186
- compare(a: T, b: T): number;
187
- min: T;
188
- }
189
-
190
- export class Heap<T> {
191
- private L: T[];
192
- public count() {
193
- return this.L.length - 1;
194
- }
195
- constructor(a: T[], public comp: Comparer<T>) {
196
- this.L = [comp.min];
197
- for (let i = 0, len = a.length; i < len; i++) {
198
- this.add(a[i]);
199
- }
200
- }
201
- public peek() {
202
- return this.L[1];
203
- }
204
-
205
- public get() {
206
- const x = this.L[1];
207
- this.L[1] = this.L[this.count()];
208
- this.L.pop();
209
- this.fixDown(1);
210
- return x;
211
- }
212
-
213
- public add(x: T) {
214
- this.L.push(x);
215
- this.fixup(this.count());
216
- }
217
-
218
- /* eslint-disable no-bitwise */
219
- private fixup(k: number) {
220
- let _k = k;
221
- while (_k > 1 && (this.comp.compare(this.L[_k >> 1], this.L[_k]) > 0)) {
222
- const tmp = this.L[_k >> 1];
223
- this.L[_k >> 1] = this.L[_k];
224
- this.L[_k] = tmp;
225
- _k = _k >> 1;
226
- }
227
- }
228
-
229
- private fixDown(k: number) {
230
- let _k = k;
231
- while ((_k << 1) <= (this.count())) {
232
- let j = _k << 1;
233
- if ((j < this.count()) && (this.comp.compare(this.L[j], this.L[j + 1]) > 0)) {
234
- j++;
235
- }
236
- if (this.comp.compare(this.L[_k], this.L[j]) <= 0) {
237
- break;
238
- }
239
- const tmp = this.L[_k];
240
- this.L[_k] = this.L[j];
241
- this.L[j] = tmp;
242
- _k = j;
243
- }
244
- }
245
- /* eslint-enable no-bitwise */
246
- }
247
-
10
+ /**
11
+ * @internal
12
+ */
248
13
  export const RBColor = {
249
14
  RED: 0,
250
15
  BLACK: 1,
251
16
  } as const;
17
+
18
+ /**
19
+ * @internal
20
+ */
252
21
  export type RBColor = typeof RBColor[keyof typeof RBColor];
253
22
 
23
+ /**
24
+ * @internal
25
+ */
254
26
  export interface RBNode<TKey, TData> {
255
27
  key: TKey;
256
28
  data: TData;
@@ -259,16 +31,23 @@ export interface RBNode<TKey, TData> {
259
31
  color: RBColor;
260
32
  size: number;
261
33
  }
262
-
34
+ /**
35
+ * @internal
36
+ */
263
37
  export interface IRBAugmentation<TKey, TData> {
264
38
  update(node: RBNode<TKey, TData>): void;
265
39
  }
266
-
40
+ /**
41
+ * @internal
42
+ */
267
43
  export interface IRBMatcher<TKey, TData> {
268
44
  continueSubtree(node: RBNode<TKey, TData> | undefined, key: TKey): boolean;
269
45
  matchNode(node: RBNode<TKey, TData> | undefined, key: TKey): boolean;
270
46
  }
271
47
 
48
+ /**
49
+ * @internal
50
+ */
272
51
  export interface RBNodeActions<TKey, TData> {
273
52
  infix?(node: RBNode<TKey, TData>): boolean;
274
53
  pre?(node: RBNode<TKey, TData>): boolean;
@@ -276,6 +55,66 @@ export interface RBNodeActions<TKey, TData> {
276
55
  showStructure?: boolean;
277
56
  }
278
57
 
58
+ /**
59
+ * @internal
60
+ */
61
+ export interface KeyComparer<TKey> {
62
+ // eslint-disable-next-line @typescript-eslint/prefer-function-type
63
+ (a: TKey, b: TKey): number;
64
+ }
65
+
66
+ /**
67
+ * @internal
68
+ */
69
+ export interface Property<TKey, TData> {
70
+ key: TKey;
71
+ data: TData;
72
+ }
73
+
74
+ /**
75
+ * @internal
76
+ */
77
+ export interface PropertyAction<TKey, TData> {
78
+ // eslint-disable-next-line @typescript-eslint/prefer-function-type
79
+ <TAccum>(p: Property<TKey, TData>, accum?: TAccum): boolean;
80
+ }
81
+
82
+ /**
83
+ * @internal
84
+ */
85
+ export interface QProperty<TKey, TData> {
86
+ key?: TKey;
87
+ data?: TData;
88
+ }
89
+
90
+ /**
91
+ * @internal
92
+ */
93
+ export type ConflictAction<TKey, TData> =
94
+ (key: TKey, currentKey: TKey, data: TData, currentData: TData) => QProperty<TKey, TData>;
95
+
96
+ /**
97
+ * @internal
98
+ */
99
+ export interface SortedDictionary<TKey, TData> extends Dictionary<TKey, TData> {
100
+ max(): Property<TKey, TData> | undefined;
101
+ min(): Property<TKey, TData> | undefined;
102
+ mapRange<TAccum>(action: PropertyAction<TKey, TData>, accum?: TAccum, start?: TKey, end?: TKey): void;
103
+ }
104
+
105
+ /**
106
+ * @internal
107
+ */
108
+ export interface Dictionary<TKey, TData> {
109
+ get(key: TKey): Property<TKey, TData> | undefined;
110
+ put(key: TKey, data: TData, conflict?: ConflictAction<TKey, TData>): void;
111
+ remove(key: TKey): void;
112
+ map<TAccum>(action: PropertyAction<TKey, TData>, accum?: TAccum): void;
113
+ }
114
+
115
+ /**
116
+ * @internal
117
+ */
279
118
  export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData> {
280
119
  private root: RBNode<TKey, TData> | undefined;
281
120
 
@@ -438,11 +277,7 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
438
277
  if (kd.key) {
439
278
  _node.key = kd.key;
440
279
  }
441
- if (kd.data) {
442
- _node.data = kd.data;
443
- } else {
444
- _node.data = data;
445
- }
280
+ _node.data = kd.data ? kd.data : data;
446
281
  } else {
447
282
  _node.data = data;
448
283
  }
@@ -564,11 +399,7 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
564
399
  return this.nodeFloor(node.left, key);
565
400
  } else {
566
401
  const rightFloor = this.nodeFloor(node.right, key);
567
- if (rightFloor) {
568
- return rightFloor;
569
- } else {
570
- return node;
571
- }
402
+ return rightFloor ? rightFloor : node;
572
403
  }
573
404
  }
574
405
  }
@@ -588,11 +419,7 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
588
419
  return this.nodeCeil(node.right, key);
589
420
  } else {
590
421
  const leftCeil = this.nodeCeil(node.left, key);
591
- if (leftCeil) {
592
- return leftCeil;
593
- } else {
594
- return node;
595
- }
422
+ return leftCeil ? leftCeil : node;
596
423
  }
597
424
  }
598
425
  }
@@ -604,11 +431,7 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
604
431
  }
605
432
 
606
433
  private nodeMin(node: RBNode<TKey, TData>): RBNode<TKey, TData> {
607
- if (!node.left) {
608
- return node;
609
- } else {
610
- return this.nodeMin(node.left);
611
- }
434
+ return !node.left ? node : this.nodeMin(node.left);
612
435
  }
613
436
 
614
437
  public max() {
@@ -618,11 +441,7 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
618
441
  }
619
442
 
620
443
  private nodeMax(node: RBNode<TKey, TData>): RBNode<TKey, TData> {
621
- if (!node.right) {
622
- return node;
623
- } else {
624
- return this.nodeMax(node.right);
625
- }
444
+ return !node.right ? node : this.nodeMax(node.right);
626
445
  }
627
446
 
628
447
  private rotateRight(node: RBNode<TKey, TData>) {
@@ -837,301 +656,3 @@ export class RedBlackTree<TKey, TData> implements SortedDictionary<TKey, TData>
837
656
  return go;
838
657
  }
839
658
  }
840
-
841
- export interface AugmentedIntervalNode {
842
- minmax: IInterval;
843
- }
844
-
845
- export const integerRangeToString = (range: IIntegerRange) => `[${range.start},${range.end})`;
846
-
847
- export interface IInterval {
848
- clone(): IInterval;
849
- compare(b: IInterval): number;
850
- compareStart(b: IInterval): number;
851
- compareEnd(b: IInterval): number;
852
- modify(label: string, start: number, end: number, op?: ISequencedDocumentMessage): IInterval | undefined;
853
- overlaps(b: IInterval): boolean;
854
- union(b: IInterval): IInterval;
855
- }
856
-
857
- const intervalComparer = (a: IInterval, b: IInterval) => a.compare(b);
858
- export type IntervalNode<T extends IInterval> = RBNode<T, AugmentedIntervalNode>;
859
- export type IntervalConflictResolver<TInterval> = (a: TInterval, b: TInterval) => TInterval;
860
-
861
- export class IntervalTree<T extends IInterval> implements IRBAugmentation<T, AugmentedIntervalNode>,
862
- IRBMatcher<T, AugmentedIntervalNode> {
863
- public intervals = new RedBlackTree<T, AugmentedIntervalNode>(intervalComparer, this);
864
-
865
- public remove(x: T) {
866
- this.intervals.remove(x);
867
- }
868
-
869
- public removeExisting(x: T) {
870
- this.intervals.removeExisting(x);
871
- }
872
-
873
- public put(x: T, conflict?: IntervalConflictResolver<T>) {
874
- let rbConflict: ConflictAction<T, AugmentedIntervalNode> | undefined;
875
- if (conflict) {
876
- rbConflict = (key: T, currentKey: T) => {
877
- const ival = conflict(key, currentKey);
878
- return {
879
- key: ival,
880
- };
881
- };
882
- }
883
- this.intervals.put(x, { minmax: x.clone() }, rbConflict);
884
- }
885
-
886
- public map(fn: (x: T) => void) {
887
- const actions = <RBNodeActions<T, AugmentedIntervalNode>>{
888
- infix: (node) => {
889
- fn(node.key);
890
- return true;
891
- },
892
- showStructure: true,
893
- };
894
- this.intervals.walk(actions);
895
- }
896
-
897
- public mapUntil(fn: (X: T) => boolean) {
898
- const actions = <RBNodeActions<T, AugmentedIntervalNode>>{
899
- infix: (node) => {
900
- return fn(node.key);
901
- },
902
- showStructure: true,
903
- };
904
- this.intervals.walk(actions);
905
- }
906
-
907
- public mapBackward(fn: (x: T) => void) {
908
- const actions = <RBNodeActions<T, AugmentedIntervalNode>>{
909
- infix: (node) => {
910
- fn(node.key);
911
- return true;
912
- },
913
- showStructure: true,
914
- };
915
- this.intervals.walkBackward(actions);
916
- }
917
-
918
- // TODO: toString()
919
- public match(x: T) {
920
- return this.intervals.gather(x, this);
921
- }
922
-
923
- public matchNode(node: IntervalNode<T> | undefined, key: T) {
924
- return !!node && node.key.overlaps(key);
925
- }
926
-
927
- public continueSubtree(node: IntervalNode<T> | undefined, key: T) {
928
- return !!node && node.data.minmax.overlaps(key);
929
- }
930
-
931
- public update(node: IntervalNode<T>) {
932
- if (node.left && node.right) {
933
- node.data.minmax = node.key.union(
934
- node.left.data.minmax.union(node.right.data.minmax));
935
- } else {
936
- if (node.left) {
937
- node.data.minmax = node.key.union(node.left.data.minmax);
938
- } else if (node.right) {
939
- node.data.minmax = node.key.union(node.right.data.minmax);
940
- } else {
941
- node.data.minmax = node.key.clone();
942
- }
943
- }
944
- }
945
- }
946
-
947
- export interface TSTResult<T> {
948
- key: string;
949
- val: T;
950
- }
951
-
952
- export interface TSTNode<T> {
953
- c: string;
954
- left?: TSTNode<T>;
955
- mid?: TSTNode<T>;
956
- right?: TSTNode<T>;
957
- val?: T;
958
- }
959
-
960
- interface TSTPrefix {
961
- text: string;
962
- }
963
-
964
- export interface ProxString<T> {
965
- text: string;
966
- invDistance: number;
967
- val: T;
968
- }
969
-
970
- export class TST<T> {
971
- private n = 0;
972
- private root: TSTNode<T> | undefined;
973
-
974
- public size() {
975
- return this.n;
976
- }
977
-
978
- private contains(key: string) {
979
- return this.get(key);
980
- }
981
-
982
- public get(key: string) {
983
- const x = this.nodeGet(this.root, key, 0);
984
- if (x === undefined) {
985
- return undefined;
986
- }
987
- return x.val;
988
- }
989
-
990
- private nodeGet(x: TSTNode<T> | undefined, key: string, d: number): TSTNode<T> | undefined {
991
- if (x === undefined) {
992
- return undefined;
993
- }
994
- const c = key.charAt(d);
995
- if (c < x.c) {
996
- return this.nodeGet(x.left, key, d);
997
- } else if (c > x.c) {
998
- return this.nodeGet(x.right, key, d);
999
- } else if (d < (key.length - 1)) {
1000
- return this.nodeGet(x.mid, key, d + 1);
1001
- } else { return x; }
1002
- }
1003
-
1004
- public put(key: string, val: T) {
1005
- if (!this.contains(key)) {
1006
- this.n++;
1007
- }
1008
- this.root = this.nodePut(this.root, key, val, 0);
1009
- }
1010
-
1011
- private nodePut(x: TSTNode<T> | undefined, key: string, val: T, d: number) {
1012
- let _x = x;
1013
- const c = key.charAt(d);
1014
- if (_x === undefined) {
1015
- _x = { c };
1016
- }
1017
- if (c < _x.c) {
1018
- _x.left = this.nodePut(_x.left, key, val, d);
1019
- } else if (c > _x.c) {
1020
- _x.right = this.nodePut(_x.right, key, val, d);
1021
- } else if (d < (key.length - 1)) {
1022
- _x.mid = this.nodePut(_x.mid, key, val, d + 1);
1023
- } else {
1024
- _x.val = val;
1025
- }
1026
- return _x;
1027
- }
1028
-
1029
- public neighbors(text: string, distance = 2) {
1030
- let q = <ProxString<T>[]>[];
1031
- this.nodeProximity(this.root, { text: "" }, 0, text, distance, q);
1032
- q = q.filter((value) => (value.text.length > 0));
1033
- return q;
1034
- }
1035
-
1036
- public keysWithPrefix(text: string) {
1037
- const q = <string[]>[];
1038
- const x = this.nodeGet(this.root, text, 0);
1039
- if (x === undefined) {
1040
- return q;
1041
- }
1042
- if (x.val !== undefined) {
1043
- q.push(text);
1044
- }
1045
- this.collect(x.mid, { text }, q);
1046
- return q;
1047
- }
1048
-
1049
- private collect(x: TSTNode<T> | undefined, prefix: TSTPrefix, q: string[]) {
1050
- if (x === undefined) {
1051
- return;
1052
- }
1053
- this.collect(x.left, prefix, q);
1054
- if (x.val !== undefined) {
1055
- q.push(prefix.text + x.c);
1056
- }
1057
- this.collect(x.mid, { text: prefix.text + x.c }, q);
1058
- this.collect(x.right, prefix, q);
1059
- }
1060
-
1061
- private mapNode(x: TSTNode<T> | undefined, prefix: TSTPrefix, fn: (key: string, val: T) => void) {
1062
- if (x === undefined) {
1063
- return;
1064
- }
1065
- const key = prefix.text + x.c;
1066
- this.mapNode(x.left, prefix, fn);
1067
- if (x.val) {
1068
- fn(key, x.val);
1069
- }
1070
- this.mapNode(x.mid, { text: key }, fn);
1071
- this.mapNode(x.right, prefix, fn);
1072
- }
1073
-
1074
- public map(fn: (key: string, val: T) => void) {
1075
- this.mapNode(this.root, { text: "" }, fn);
1076
- }
1077
-
1078
- public pairsWithPrefix(text: string) {
1079
- const q = <TSTResult<T>[]>[];
1080
- const x = this.nodeGet(this.root, text, 0);
1081
- if (x === undefined) {
1082
- return q;
1083
- }
1084
- if (x.val !== undefined) {
1085
- q.push({ key: text, val: x.val });
1086
- }
1087
- this.collectPairs(x.mid, { text }, q);
1088
- return q;
1089
- }
1090
-
1091
- private collectPairs(x: TSTNode<T> | undefined, prefix: TSTPrefix, q: TSTResult<T>[]) {
1092
- if (x === undefined) {
1093
- return;
1094
- }
1095
- this.collectPairs(x.left, prefix, q);
1096
- if (x.val !== undefined) {
1097
- q.push({ key: prefix.text + x.c, val: x.val });
1098
- }
1099
- this.collectPairs(x.mid, { text: prefix.text + x.c }, q);
1100
- this.collectPairs(x.right, prefix, q);
1101
- }
1102
-
1103
- private nodeProximity(
1104
- x: TSTNode<T> | undefined,
1105
- prefix: TSTPrefix,
1106
- d: number,
1107
- pattern: string,
1108
- distance: number,
1109
- q: ProxString<T>[]) {
1110
- if ((x === undefined) || (distance < 0)) {
1111
- return;
1112
- }
1113
- const c = pattern.charAt(d);
1114
- if ((distance > 0) || (c < x.c)) {
1115
- this.nodeProximity(x.left, prefix, d, pattern, distance, q);
1116
- }
1117
- if (x.val !== undefined) {
1118
- const remD = distance - (pattern.length - d);
1119
- if (remD >= 0) {
1120
- let invD = distance;
1121
- if (c !== x.c) {
1122
- invD--;
1123
- }
1124
- q.push({ text: prefix.text + x.c, val: x.val, invDistance: invD });
1125
- }
1126
- }
1127
- const recurD = (d < (pattern.length - 1)) ? d + 1 : d;
1128
- if (c === x.c) {
1129
- this.nodeProximity(x.mid, { text: prefix.text + x.c }, recurD, pattern, distance, q);
1130
- } else {
1131
- this.nodeProximity(x.mid, { text: prefix.text + x.c }, recurD, pattern, distance - 1, q);
1132
- }
1133
- if ((distance > 0) || (c > x.c)) {
1134
- this.nodeProximity(x.right, prefix, d, pattern, distance, q);
1135
- }
1136
- }
1137
- }