@fluid-experimental/tree 0.59.2001 → 0.59.3000

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 (258) hide show
  1. package/.eslintrc.js +2 -0
  2. package/.vscode/SharedTree.code-workspace +15 -0
  3. package/.vscode/settings.json +6 -0
  4. package/dist/ChangeCompression.js +9 -9
  5. package/dist/ChangeCompression.js.map +1 -1
  6. package/dist/ChangeTypes.d.ts +1 -6
  7. package/dist/ChangeTypes.d.ts.map +1 -1
  8. package/dist/ChangeTypes.js +5 -5
  9. package/dist/ChangeTypes.js.map +1 -1
  10. package/dist/Checkout.js +14 -14
  11. package/dist/Checkout.js.map +1 -1
  12. package/dist/Common.d.ts +21 -3
  13. package/dist/Common.d.ts.map +1 -1
  14. package/dist/Common.js +29 -4
  15. package/dist/Common.js.map +1 -1
  16. package/dist/EditLog.js +26 -25
  17. package/dist/EditLog.js.map +1 -1
  18. package/dist/EditUtilities.js +17 -17
  19. package/dist/EditUtilities.js.map +1 -1
  20. package/dist/Forest.js +31 -31
  21. package/dist/Forest.js.map +1 -1
  22. package/dist/HistoryEditFactory.js +9 -9
  23. package/dist/HistoryEditFactory.js.map +1 -1
  24. package/dist/IdConversion.js +9 -9
  25. package/dist/IdConversion.js.map +1 -1
  26. package/dist/Identifiers.d.ts +4 -0
  27. package/dist/Identifiers.d.ts.map +1 -1
  28. package/dist/Identifiers.js.map +1 -1
  29. package/dist/LogViewer.d.ts +1 -5
  30. package/dist/LogViewer.d.ts.map +1 -1
  31. package/dist/LogViewer.js +11 -19
  32. package/dist/LogViewer.js.map +1 -1
  33. package/dist/MergeHealth.js +2 -2
  34. package/dist/MergeHealth.js.map +1 -1
  35. package/dist/NodeIdUtilities.js +2 -2
  36. package/dist/NodeIdUtilities.js.map +1 -1
  37. package/dist/PayloadUtilities.js +1 -1
  38. package/dist/PayloadUtilities.js.map +1 -1
  39. package/dist/RevisionValueCache.d.ts +13 -10
  40. package/dist/RevisionValueCache.d.ts.map +1 -1
  41. package/dist/RevisionValueCache.js +14 -11
  42. package/dist/RevisionValueCache.js.map +1 -1
  43. package/dist/RevisionView.js +4 -4
  44. package/dist/RevisionView.js.map +1 -1
  45. package/dist/SerializationUtilities.js +4 -4
  46. package/dist/SerializationUtilities.js.map +1 -1
  47. package/dist/SharedTree.d.ts +93 -31
  48. package/dist/SharedTree.d.ts.map +1 -1
  49. package/dist/SharedTree.js +160 -131
  50. package/dist/SharedTree.js.map +1 -1
  51. package/dist/SharedTreeEncoder.d.ts +3 -3
  52. package/dist/SharedTreeEncoder.d.ts.map +1 -1
  53. package/dist/SharedTreeEncoder.js +36 -36
  54. package/dist/SharedTreeEncoder.js.map +1 -1
  55. package/dist/StringInterner.js +1 -1
  56. package/dist/StringInterner.js.map +1 -1
  57. package/dist/Summary.js +1 -1
  58. package/dist/Summary.js.map +1 -1
  59. package/dist/SummaryBackCompatibility.js +8 -8
  60. package/dist/SummaryBackCompatibility.js.map +1 -1
  61. package/dist/Transaction.js +1 -1
  62. package/dist/Transaction.js.map +1 -1
  63. package/dist/TransactionInternal.js +17 -17
  64. package/dist/TransactionInternal.js.map +1 -1
  65. package/dist/TreeCompressor.d.ts.map +1 -1
  66. package/dist/TreeCompressor.js +6 -8
  67. package/dist/TreeCompressor.js.map +1 -1
  68. package/dist/TreeNodeHandle.js +4 -4
  69. package/dist/TreeNodeHandle.js.map +1 -1
  70. package/dist/TreeView.js +7 -7
  71. package/dist/TreeView.js.map +1 -1
  72. package/dist/TreeViewUtilities.js +2 -2
  73. package/dist/TreeViewUtilities.js.map +1 -1
  74. package/dist/UndoRedoHandler.js +1 -1
  75. package/dist/UndoRedoHandler.js.map +1 -1
  76. package/dist/UuidUtilities.d.ts +30 -0
  77. package/dist/UuidUtilities.d.ts.map +1 -0
  78. package/dist/UuidUtilities.js +106 -0
  79. package/dist/UuidUtilities.js.map +1 -0
  80. package/dist/id-compressor/AppendOnlySortedMap.d.ts +52 -28
  81. package/dist/id-compressor/AppendOnlySortedMap.d.ts.map +1 -1
  82. package/dist/id-compressor/AppendOnlySortedMap.js +167 -90
  83. package/dist/id-compressor/AppendOnlySortedMap.js.map +1 -1
  84. package/dist/id-compressor/IdCompressor.d.ts +43 -42
  85. package/dist/id-compressor/IdCompressor.d.ts.map +1 -1
  86. package/dist/id-compressor/IdCompressor.js +179 -177
  87. package/dist/id-compressor/IdCompressor.js.map +1 -1
  88. package/dist/id-compressor/IdRange.js +1 -1
  89. package/dist/id-compressor/IdRange.js.map +1 -1
  90. package/dist/id-compressor/NumericUuid.d.ts +6 -14
  91. package/dist/id-compressor/NumericUuid.d.ts.map +1 -1
  92. package/dist/id-compressor/NumericUuid.js +15 -76
  93. package/dist/id-compressor/NumericUuid.js.map +1 -1
  94. package/dist/id-compressor/SessionIdNormalizer.d.ts +122 -0
  95. package/dist/id-compressor/SessionIdNormalizer.d.ts.map +1 -0
  96. package/dist/id-compressor/SessionIdNormalizer.js +418 -0
  97. package/dist/id-compressor/SessionIdNormalizer.js.map +1 -0
  98. package/dist/id-compressor/persisted-types/0.0.1.d.ts +6 -13
  99. package/dist/id-compressor/persisted-types/0.0.1.d.ts.map +1 -1
  100. package/dist/id-compressor/persisted-types/0.0.1.js.map +1 -1
  101. package/dist/index.d.ts +2 -2
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js.map +1 -1
  104. package/dist/persisted-types/0.1.1.d.ts +1 -6
  105. package/dist/persisted-types/0.1.1.d.ts.map +1 -1
  106. package/dist/persisted-types/0.1.1.js +3 -3
  107. package/dist/persisted-types/0.1.1.js.map +1 -1
  108. package/lib/ChangeTypes.d.ts +1 -6
  109. package/lib/ChangeTypes.d.ts.map +1 -1
  110. package/lib/Checkout.js.map +1 -1
  111. package/lib/Common.d.ts +21 -3
  112. package/lib/Common.d.ts.map +1 -1
  113. package/lib/Common.js +25 -3
  114. package/lib/Common.js.map +1 -1
  115. package/lib/EditLog.js +2 -1
  116. package/lib/EditLog.js.map +1 -1
  117. package/lib/EditUtilities.js.map +1 -1
  118. package/lib/Forest.js.map +1 -1
  119. package/lib/HistoryEditFactory.js.map +1 -1
  120. package/lib/Identifiers.d.ts +4 -0
  121. package/lib/Identifiers.d.ts.map +1 -1
  122. package/lib/Identifiers.js.map +1 -1
  123. package/lib/LogViewer.d.ts +1 -5
  124. package/lib/LogViewer.d.ts.map +1 -1
  125. package/lib/LogViewer.js +5 -13
  126. package/lib/LogViewer.js.map +1 -1
  127. package/lib/MergeHealth.js.map +1 -1
  128. package/lib/NodeIdUtilities.js.map +1 -1
  129. package/lib/RevisionValueCache.d.ts +13 -10
  130. package/lib/RevisionValueCache.d.ts.map +1 -1
  131. package/lib/RevisionValueCache.js +10 -7
  132. package/lib/RevisionValueCache.js.map +1 -1
  133. package/lib/RevisionView.js.map +1 -1
  134. package/lib/SharedTree.d.ts +93 -31
  135. package/lib/SharedTree.d.ts.map +1 -1
  136. package/lib/SharedTree.js +107 -78
  137. package/lib/SharedTree.js.map +1 -1
  138. package/lib/SharedTreeEncoder.d.ts +3 -3
  139. package/lib/SharedTreeEncoder.d.ts.map +1 -1
  140. package/lib/SharedTreeEncoder.js +4 -4
  141. package/lib/SharedTreeEncoder.js.map +1 -1
  142. package/lib/StringInterner.js.map +1 -1
  143. package/lib/Summary.js.map +1 -1
  144. package/lib/TreeCompressor.d.ts.map +1 -1
  145. package/lib/TreeCompressor.js +1 -3
  146. package/lib/TreeCompressor.js.map +1 -1
  147. package/lib/TreeNodeHandle.js.map +1 -1
  148. package/lib/TreeView.js.map +1 -1
  149. package/lib/TreeViewUtilities.js.map +1 -1
  150. package/lib/UuidUtilities.d.ts +30 -0
  151. package/lib/UuidUtilities.d.ts.map +1 -0
  152. package/lib/UuidUtilities.js +98 -0
  153. package/lib/UuidUtilities.js.map +1 -0
  154. package/lib/id-compressor/AppendOnlySortedMap.d.ts +52 -28
  155. package/lib/id-compressor/AppendOnlySortedMap.d.ts.map +1 -1
  156. package/lib/id-compressor/AppendOnlySortedMap.js +165 -88
  157. package/lib/id-compressor/AppendOnlySortedMap.js.map +1 -1
  158. package/lib/id-compressor/IdCompressor.d.ts +43 -42
  159. package/lib/id-compressor/IdCompressor.d.ts.map +1 -1
  160. package/lib/id-compressor/IdCompressor.js +97 -95
  161. package/lib/id-compressor/IdCompressor.js.map +1 -1
  162. package/lib/id-compressor/NumericUuid.d.ts +6 -14
  163. package/lib/id-compressor/NumericUuid.d.ts.map +1 -1
  164. package/lib/id-compressor/NumericUuid.js +11 -70
  165. package/lib/id-compressor/NumericUuid.js.map +1 -1
  166. package/lib/id-compressor/SessionIdNormalizer.d.ts +122 -0
  167. package/lib/id-compressor/SessionIdNormalizer.d.ts.map +1 -0
  168. package/lib/id-compressor/SessionIdNormalizer.js +414 -0
  169. package/lib/id-compressor/SessionIdNormalizer.js.map +1 -0
  170. package/lib/id-compressor/persisted-types/0.0.1.d.ts +6 -13
  171. package/lib/id-compressor/persisted-types/0.0.1.d.ts.map +1 -1
  172. package/lib/id-compressor/persisted-types/0.0.1.js.map +1 -1
  173. package/lib/index.d.ts +2 -2
  174. package/lib/index.d.ts.map +1 -1
  175. package/lib/index.js.map +1 -1
  176. package/lib/persisted-types/0.1.1.d.ts +1 -6
  177. package/lib/persisted-types/0.1.1.d.ts.map +1 -1
  178. package/lib/persisted-types/0.1.1.js.map +1 -1
  179. package/lib/test/AppendOnlySortedMap.perf.tests.d.ts +6 -0
  180. package/lib/test/AppendOnlySortedMap.perf.tests.d.ts.map +1 -0
  181. package/lib/test/AppendOnlySortedMap.perf.tests.js +49 -0
  182. package/lib/test/AppendOnlySortedMap.perf.tests.js.map +1 -0
  183. package/lib/test/AppendOnlySortedMap.tests.js +56 -14
  184. package/lib/test/AppendOnlySortedMap.tests.js.map +1 -1
  185. package/lib/test/Checkout.tests.js +2 -2
  186. package/lib/test/Checkout.tests.js.map +1 -1
  187. package/lib/test/Forest.tests.js.map +1 -1
  188. package/lib/test/IdCompressor.perf.tests.js +8 -2
  189. package/lib/test/IdCompressor.perf.tests.js.map +1 -1
  190. package/lib/test/IdCompressor.tests.js +75 -24
  191. package/lib/test/IdCompressor.tests.js.map +1 -1
  192. package/lib/test/LogViewer.tests.js +3 -5
  193. package/lib/test/LogViewer.tests.js.map +1 -1
  194. package/lib/test/NumericUuid.perf.tests.js +4 -4
  195. package/lib/test/NumericUuid.perf.tests.js.map +1 -1
  196. package/lib/test/NumericUuid.tests.js +5 -4
  197. package/lib/test/NumericUuid.tests.js.map +1 -1
  198. package/lib/test/RevisionValueCache.tests.js.map +1 -1
  199. package/lib/test/RevisionView.tests.js.map +1 -1
  200. package/lib/test/SessionIdNormalizer.tests.d.ts +6 -0
  201. package/lib/test/SessionIdNormalizer.tests.d.ts.map +1 -0
  202. package/lib/test/SessionIdNormalizer.tests.js +299 -0
  203. package/lib/test/SessionIdNormalizer.tests.js.map +1 -0
  204. package/lib/test/Summary.tests.js +1 -1
  205. package/lib/test/Summary.tests.js.map +1 -1
  206. package/lib/test/TreeCompression.tests.js +1 -1
  207. package/lib/test/TreeCompression.tests.js.map +1 -1
  208. package/lib/test/Virtualization.tests.js +1 -1
  209. package/lib/test/Virtualization.tests.js.map +1 -1
  210. package/lib/test/fuzz/Generators.d.ts +3 -14
  211. package/lib/test/fuzz/Generators.d.ts.map +1 -1
  212. package/lib/test/fuzz/Generators.js +60 -151
  213. package/lib/test/fuzz/Generators.js.map +1 -1
  214. package/lib/test/fuzz/SharedTreeFuzzTests.d.ts +10 -7
  215. package/lib/test/fuzz/SharedTreeFuzzTests.d.ts.map +1 -1
  216. package/lib/test/fuzz/SharedTreeFuzzTests.js +94 -104
  217. package/lib/test/fuzz/SharedTreeFuzzTests.js.map +1 -1
  218. package/lib/test/fuzz/Types.d.ts +2 -9
  219. package/lib/test/fuzz/Types.d.ts.map +1 -1
  220. package/lib/test/fuzz/Types.js +1 -1
  221. package/lib/test/fuzz/Types.js.map +1 -1
  222. package/lib/test/utilities/IdCompressorTestUtilities.d.ts +57 -11
  223. package/lib/test/utilities/IdCompressorTestUtilities.d.ts.map +1 -1
  224. package/lib/test/utilities/IdCompressorTestUtilities.js +112 -98
  225. package/lib/test/utilities/IdCompressorTestUtilities.js.map +1 -1
  226. package/lib/test/utilities/PendingLocalStateTests.d.ts.map +1 -1
  227. package/lib/test/utilities/PendingLocalStateTests.js +2 -1
  228. package/lib/test/utilities/PendingLocalStateTests.js.map +1 -1
  229. package/lib/test/utilities/SharedTreeTests.d.ts.map +1 -1
  230. package/lib/test/utilities/SharedTreeTests.js +30 -1
  231. package/lib/test/utilities/SharedTreeTests.js.map +1 -1
  232. package/lib/test/utilities/SharedTreeVersioningTests.d.ts.map +1 -1
  233. package/lib/test/utilities/SharedTreeVersioningTests.js +20 -0
  234. package/lib/test/utilities/SharedTreeVersioningTests.js.map +1 -1
  235. package/lib/test/utilities/SummaryLoadPerfTests.d.ts.map +1 -1
  236. package/lib/test/utilities/SummaryLoadPerfTests.js +6 -3
  237. package/lib/test/utilities/SummaryLoadPerfTests.js.map +1 -1
  238. package/lib/test/utilities/TestNode.js.map +1 -1
  239. package/lib/test/utilities/TestUtilities.d.ts +9 -1
  240. package/lib/test/utilities/TestUtilities.d.ts.map +1 -1
  241. package/lib/test/utilities/TestUtilities.js +27 -13
  242. package/lib/test/utilities/TestUtilities.js.map +1 -1
  243. package/package.json +19 -17
  244. package/src/Common.ts +42 -4
  245. package/src/EditLog.ts +1 -1
  246. package/src/Identifiers.ts +5 -0
  247. package/src/LogViewer.ts +4 -20
  248. package/src/RevisionValueCache.ts +11 -8
  249. package/src/SharedTree.ts +222 -75
  250. package/src/SharedTreeEncoder.ts +17 -11
  251. package/src/TreeCompressor.ts +2 -4
  252. package/src/UuidUtilities.ts +123 -0
  253. package/src/id-compressor/AppendOnlySortedMap.ts +183 -94
  254. package/src/id-compressor/IdCompressor.ts +144 -132
  255. package/src/id-compressor/NumericUuid.ts +11 -80
  256. package/src/id-compressor/SessionIdNormalizer.ts +497 -0
  257. package/src/id-compressor/persisted-types/0.0.1.ts +12 -15
  258. package/src/index.ts +5 -0
@@ -8,9 +8,9 @@
8
8
  */
9
9
  export declare class AppendOnlySortedMap<K, V> {
10
10
  protected readonly comparator: (a: K, b: K) => number;
11
- protected readonly elements: [K, V][];
11
+ protected readonly elements: (K | V)[];
12
12
  /**
13
- * @param comparator a comparator for keys
13
+ * @param comparator - a comparator for keys
14
14
  */
15
15
  constructor(comparator: (a: K, b: K) => number);
16
16
  /**
@@ -25,6 +25,26 @@ export declare class AppendOnlySortedMap<K, V> {
25
25
  * @returns the max key in the map.
26
26
  */
27
27
  maxKey(): K | undefined;
28
+ /**
29
+ * @returns the min value in the map.
30
+ */
31
+ minValue(): V | undefined;
32
+ /**
33
+ * @returns the min value in the map.
34
+ */
35
+ maxValue(): V | undefined;
36
+ /**
37
+ * @returns the min key in the map.
38
+ */
39
+ first(): [K, V] | undefined;
40
+ /**
41
+ * @returns the max key in the map.
42
+ */
43
+ last(): [K, V] | undefined;
44
+ /**
45
+ * Returns the element at the insertion index.
46
+ */
47
+ getAtIndex(index: number): [K, V] | undefined;
28
48
  /**
29
49
  * @returns an iterable of the entries in the map.
30
50
  */
@@ -42,25 +62,24 @@ export declare class AppendOnlySortedMap<K, V> {
42
62
  */
43
63
  entriesReversed(): IterableIterator<readonly [K, V]>;
44
64
  /**
45
- * Adds a new key/value pair to the map. `key` must be > to all keys in the map.
46
- * @param key the key to add.
47
- * @param value the value to add.
65
+ * Adds a new key/value pair to the map. `key` must be \> to all keys in the map.
66
+ * @param key - the key to add.
67
+ * @param value - the value to add.
48
68
  */
49
69
  append(key: K, value: V): void;
50
- private readonly compareKeys;
51
70
  /**
52
- * @param key the key to lookup.
71
+ * @param key - the key to lookup.
53
72
  * @returns the value associated with `key` if such an entry exists, and undefined otherwise.
54
73
  */
55
74
  get(key: K): V | undefined;
56
75
  /**
57
- * @param key the key to lookup.
76
+ * @param key - the key to lookup.
58
77
  * @returns the entry associated with `key` if such an entry exists, the entry associated with the next lower key if such an entry
59
78
  * exists, and undefined otherwise.
60
79
  */
61
80
  getPairOrNextLower(key: K): readonly [K, V] | undefined;
62
81
  /**
63
- * @param key the key to lookup.
82
+ * @param key - the key to lookup.
64
83
  * @returns the entry associated with `key` if such an entry exists, the entry associated with the next higher key if such an entry
65
84
  * exists, and undefined otherwise.
66
85
  */
@@ -69,30 +88,31 @@ export declare class AppendOnlySortedMap<K, V> {
69
88
  * Compares two `AppendOnlySortedMap`s.
70
89
  */
71
90
  equals(other: AppendOnlySortedMap<K, V>, compareValues: (a: V, b: V) => boolean): boolean;
91
+ /**
92
+ * Test-only expensive assertions to check the internal validity of the data structure.
93
+ */
94
+ assertValid(): void;
72
95
  /**
73
96
  * Queries a range of entries.
74
- * @param from the key to start the range query at, inclusive.
75
- * @param to the key to end the range query at, inclusive.
97
+ * @param from - the key to start the range query at, inclusive.
98
+ * @param to - the key to end the range query at, inclusive.
76
99
  * @returns the range of entries.
77
100
  */
78
101
  getRange(from: K, to: K): IterableIterator<readonly [K, V]>;
79
- protected getPairOrNextLowerBy<T>(search: T, comparator: (search: T, element: readonly [K, V]) => number): readonly [K, V] | undefined;
80
- private getIndexOfOrNextLower;
81
- protected getPairOrNextHigherBy<T>(search: T, comparator: (search: T, element: readonly [K, V]) => number): readonly [K, V] | undefined;
82
- private getIndexOfOrNextHigher;
102
+ protected getPairOrNextLowerBy<T>(search: T, comparator: (search: T, key: K, value: V) => number): readonly [K, V] | undefined;
103
+ private getKeyIndexOfOrNextLower;
104
+ protected getPairOrNextHigherBy<T>(search: T, comparator: (search: T, key: K, value: V) => number): readonly [K, V] | undefined;
105
+ private getKeyIndexOfOrNextHigher;
83
106
  /**
84
107
  * The value xor'd with the result index when a search fails.
85
108
  */
86
109
  static readonly failureXor = -1;
87
110
  /**
88
111
  * Performs a binary search on the sorted array.
89
- * @param elements
90
- * @param search
91
- * @param comparator
92
- * @returns the index of `search`, or (if not present) the index it would have been inserted into xor'd with `failureXor`. Note that
93
- * negating is not an adequate solution as that could result in -0.
112
+ * @returns the index of the key for `search`, or (if not present) the index it would have been inserted into xor'd
113
+ * with `failureXor`. Note that negating is not an adequate solution as that could result in -0.
94
114
  */
95
- static indexOf<T, K, V>(elements: readonly (readonly [K, V])[], search: T, comparator: (search: T, element: readonly [K, V]) => number): number;
115
+ static keyIndexOf<T, K, V>(elements: readonly (K | V)[], search: T, comparator: (search: T, key: K, value: V) => number): number;
96
116
  }
97
117
  /**
98
118
  * A map in which entries are always added in both key-sorted and value-sorted order.
@@ -101,27 +121,31 @@ export declare class AppendOnlySortedMap<K, V> {
101
121
  export declare class AppendOnlyDoublySortedMap<K, V, S> extends AppendOnlySortedMap<K, V> {
102
122
  private readonly extractSearchValue;
103
123
  private readonly valueComparator;
104
- constructor(keyComparator: (a: K, b: K) => number, extractSearchValue: (value: V) => S, valueComparator: (search: S, value: V) => number);
124
+ constructor(keyComparator: (a: K, b: K) => number, extractSearchValue: (value: V) => S, valueComparator: (search: S, value: S) => number);
105
125
  append(key: K, value: V): void;
106
126
  private readonly compareValues;
107
127
  /**
108
- * @param value the value to lookup.
128
+ * @param value - the value to lookup.
109
129
  * @returns the key associated with `value` if such an entry exists, and undefined otherwise.
110
130
  */
111
131
  getByValue(value: S): K | undefined;
112
132
  /**
113
- * @param searchValue the search value to lookup.
114
- * @returns the entry who's value, when run through the extractor provided to the constructor, matches `searchValue`. If no such entry
115
- * exists, this method returns the next lower entry as determined by the value comparator provided to the constructor. If no such entry
116
- * exists, this method returns undefined.
133
+ * @param searchValue - the search value to lookup.
134
+ * @returns the entry who's value, when run through the extractor provided to the constructor, matches
135
+ * `searchValue`. If no such entry exists, this method returns the next lower entry as determined by the value
136
+ * comparator provided to the constructor. If no such entry exists, this method returns undefined.
117
137
  */
118
138
  getPairOrNextLowerByValue(searchValue: S): readonly [K, V] | undefined;
119
139
  /**
120
- * @param searchValue the search value to lookup.
140
+ * @param searchValue - the search value to lookup.
121
141
  * @returns the entry who's value, when run through the extractor provided to the constructor, matches `searchValue`. If no such entry
122
142
  * exists, this method returns the next higher entry as determined by the value comparator provided to the constructor. If no such entry
123
143
  * exists, this method returns undefined.
124
144
  */
125
145
  getPairOrNextHigherByValue(searchValue: S): readonly [K, V] | undefined;
146
+ /**
147
+ * Test-only expensive assertions to check the internal validity of the data structure.
148
+ */
149
+ assertValid(): void;
126
150
  }
127
151
  //# sourceMappingURL=AppendOnlySortedMap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AppendOnlySortedMap.d.ts","sourceRoot":"","sources":["../../src/id-compressor/AppendOnlySortedMap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AppendOnlySortedMap.d.ts","sourceRoot":"","sources":["../../src/id-compressor/AppendOnlySortedMap.ts"],"names":[],"mappings":"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"}
@@ -3,109 +3,159 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  /* eslint-disable no-bitwise */
6
- import { fail } from '../Common';
6
+ import { assert, fail } from '../Common';
7
7
  /**
8
8
  * A map in which entries are always added in key-sorted order.
9
9
  * Supports appending and searching.
10
10
  */
11
11
  export class AppendOnlySortedMap {
12
12
  /**
13
- * @param comparator a comparator for keys
13
+ * @param comparator - a comparator for keys
14
14
  */
15
15
  constructor(comparator) {
16
16
  this.comparator = comparator;
17
17
  this.elements = [];
18
- this.compareKeys = (search, element) => {
19
- return this.comparator(search, element[0]);
20
- };
21
18
  }
22
19
  /**
23
20
  * @returns the number of entries in this map
24
21
  */
25
22
  get size() {
26
- return this.elements.length;
23
+ return this.elements.length / 2;
27
24
  }
28
25
  /**
29
26
  * @returns the min key in the map.
30
27
  */
31
28
  minKey() {
32
- var _a;
33
- return (_a = this.elements[0]) === null || _a === void 0 ? void 0 : _a[0];
29
+ return this.elements[0];
34
30
  }
35
31
  /**
36
32
  * @returns the max key in the map.
37
33
  */
38
34
  maxKey() {
39
- var _a;
40
- return (_a = this.elements[this.size - 1]) === null || _a === void 0 ? void 0 : _a[0];
35
+ return this.elements[this.elements.length - 2];
36
+ }
37
+ /**
38
+ * @returns the min value in the map.
39
+ */
40
+ minValue() {
41
+ return this.elements[1];
42
+ }
43
+ /**
44
+ * @returns the min value in the map.
45
+ */
46
+ maxValue() {
47
+ return this.elements[this.elements.length - 1];
48
+ }
49
+ /**
50
+ * @returns the min key in the map.
51
+ */
52
+ first() {
53
+ const { elements } = this;
54
+ const { length } = elements;
55
+ if (length === 0) {
56
+ return undefined;
57
+ }
58
+ return [elements[0], elements[1]];
59
+ }
60
+ /**
61
+ * @returns the max key in the map.
62
+ */
63
+ last() {
64
+ const { elements } = this;
65
+ const { length } = elements;
66
+ if (length === 0) {
67
+ return undefined;
68
+ }
69
+ const lastKeyIndex = length - 2;
70
+ return [elements[lastKeyIndex], elements[lastKeyIndex + 1]];
71
+ }
72
+ /**
73
+ * Returns the element at the insertion index.
74
+ */
75
+ getAtIndex(index) {
76
+ const realIndex = index * 2;
77
+ const { elements } = this;
78
+ if (realIndex < 0 || realIndex > elements.length - 1) {
79
+ return undefined;
80
+ }
81
+ return [elements[realIndex], elements[realIndex + 1]];
41
82
  }
42
83
  /**
43
84
  * @returns an iterable of the entries in the map.
44
85
  */
45
86
  *entries() {
46
- for (const entry of this.elements) {
47
- yield entry;
87
+ const { elements } = this;
88
+ for (let i = 0; i < elements.length; i += 2) {
89
+ yield [elements[i], elements[i + 1]];
48
90
  }
49
91
  }
50
92
  /**
51
93
  * @returns an iterable of the keys in the map.
52
94
  */
53
95
  *keys() {
54
- for (const entry of this.elements) {
55
- yield entry[0];
96
+ const { elements } = this;
97
+ for (let i = 0; i < elements.length; i += 2) {
98
+ yield elements[i];
56
99
  }
57
100
  }
58
101
  /**
59
102
  * @returns an iterable of the values in the map.
60
103
  */
61
104
  *values() {
62
- for (const entry of this.elements) {
63
- yield entry[1];
105
+ const { elements } = this;
106
+ for (let i = 0; i < elements.length; i += 2) {
107
+ yield elements[i + 1];
64
108
  }
65
109
  }
66
110
  /**
67
111
  * @returns an iterable of the entries in the map, reversed.
68
112
  */
69
113
  *entriesReversed() {
70
- for (let i = this.size - 1; i >= 0; i--) {
71
- yield this.elements[i];
114
+ const { elements } = this;
115
+ for (let i = elements.length - 2; i >= 0; i -= 2) {
116
+ yield [elements[i], elements[i + 1]];
72
117
  }
73
118
  }
74
119
  /**
75
- * Adds a new key/value pair to the map. `key` must be > to all keys in the map.
76
- * @param key the key to add.
77
- * @param value the value to add.
120
+ * Adds a new key/value pair to the map. `key` must be \> to all keys in the map.
121
+ * @param key - the key to add.
122
+ * @param value - the value to add.
78
123
  */
79
124
  append(key, value) {
80
- if (this.size !== 0 && this.comparator(key, this.elements[this.size - 1][0]) <= 0) {
125
+ const { elements } = this;
126
+ const { length } = elements;
127
+ if (length !== 0 && this.comparator(key, this.maxKey()) <= 0) {
81
128
  fail('Inserted key must be > all others in the map.');
82
129
  }
83
- this.elements.push([key, value]);
130
+ elements.push(key);
131
+ elements.push(value);
84
132
  }
85
133
  /**
86
- * @param key the key to lookup.
134
+ * @param key - the key to lookup.
87
135
  * @returns the value associated with `key` if such an entry exists, and undefined otherwise.
88
136
  */
89
137
  get(key) {
90
- var _a;
91
- const index = AppendOnlySortedMap.indexOf(this.elements, key, this.compareKeys);
92
- return (_a = this.elements[index]) === null || _a === void 0 ? void 0 : _a[1];
138
+ const index = AppendOnlySortedMap.keyIndexOf(this.elements, key, this.comparator);
139
+ if (index < 0) {
140
+ return undefined;
141
+ }
142
+ return this.elements[index + 1];
93
143
  }
94
144
  /**
95
- * @param key the key to lookup.
145
+ * @param key - the key to lookup.
96
146
  * @returns the entry associated with `key` if such an entry exists, the entry associated with the next lower key if such an entry
97
147
  * exists, and undefined otherwise.
98
148
  */
99
149
  getPairOrNextLower(key) {
100
- return this.getPairOrNextLowerBy(key, this.compareKeys);
150
+ return this.getPairOrNextLowerBy(key, this.comparator);
101
151
  }
102
152
  /**
103
- * @param key the key to lookup.
153
+ * @param key - the key to lookup.
104
154
  * @returns the entry associated with `key` if such an entry exists, the entry associated with the next higher key if such an entry
105
155
  * exists, and undefined otherwise.
106
156
  */
107
157
  getPairOrNextHigher(key) {
108
- return this.getPairOrNextHigherBy(key, this.compareKeys);
158
+ return this.getPairOrNextHigherBy(key, this.comparator);
109
159
  }
110
160
  /**
111
161
  * Compares two `AppendOnlySortedMap`s.
@@ -114,12 +164,14 @@ export class AppendOnlySortedMap {
114
164
  if (other === this) {
115
165
  return true;
116
166
  }
117
- if (this.size !== other.size) {
167
+ if (this.elements.length !== other.elements.length) {
118
168
  return false;
119
169
  }
120
- for (let i = this.size - 1; i >= 0; i--) {
121
- const [keyThis, valueThis] = this.elements[i];
122
- const [keyOther, valueOther] = other.elements[i];
170
+ for (let i = this.elements.length - 2; i >= 0; i -= 2) {
171
+ const keyThis = this.elements[i];
172
+ const valueThis = this.elements[i + 1];
173
+ const keyOther = other.elements[i];
174
+ const valueOther = other.elements[i + 1];
123
175
  if (this.comparator(keyThis, keyOther) !== 0) {
124
176
  return false;
125
177
  }
@@ -129,83 +181,95 @@ export class AppendOnlySortedMap {
129
181
  }
130
182
  return true;
131
183
  }
184
+ /**
185
+ * Test-only expensive assertions to check the internal validity of the data structure.
186
+ */
187
+ assertValid() {
188
+ let prev;
189
+ for (const kv of this.entries()) {
190
+ if (prev !== undefined) {
191
+ assert(this.comparator(kv[0], prev[0]) > 0, 'Keys in map must be sorted.');
192
+ }
193
+ prev = kv;
194
+ }
195
+ }
132
196
  /**
133
197
  * Queries a range of entries.
134
- * @param from the key to start the range query at, inclusive.
135
- * @param to the key to end the range query at, inclusive.
198
+ * @param from - the key to start the range query at, inclusive.
199
+ * @param to - the key to end the range query at, inclusive.
136
200
  * @returns the range of entries.
137
201
  */
138
202
  *getRange(from, to) {
139
- const indexFrom = this.getIndexOfOrNextHigher(from, this.compareKeys);
140
- if (indexFrom === undefined) {
203
+ const keyIndexFrom = this.getKeyIndexOfOrNextHigher(from, this.comparator);
204
+ if (keyIndexFrom === undefined) {
141
205
  return;
142
206
  }
143
- const indexTo = this.getIndexOfOrNextLower(to, this.compareKeys);
144
- if (indexTo === undefined) {
207
+ const keyIndexTo = this.getKeyIndexOfOrNextLower(to, this.comparator);
208
+ if (keyIndexTo === undefined) {
145
209
  return;
146
210
  }
147
- for (let i = indexFrom; i <= indexTo; i++) {
148
- yield this.elements[i];
211
+ for (let i = keyIndexFrom; i <= keyIndexTo; i += 2) {
212
+ yield [this.elements[i], this.elements[i + 1]];
149
213
  }
150
214
  }
151
215
  getPairOrNextLowerBy(search, comparator) {
152
- const index = this.getIndexOfOrNextLower(search, comparator);
153
- if (index === undefined) {
216
+ const keyIndex = this.getKeyIndexOfOrNextLower(search, comparator);
217
+ if (keyIndex === undefined) {
154
218
  return undefined;
155
219
  }
156
- return this.elements[index];
220
+ return [this.elements[keyIndex], this.elements[keyIndex + 1]];
157
221
  }
158
- getIndexOfOrNextLower(search, comparator) {
159
- const { size } = this;
160
- if (size === 0) {
222
+ getKeyIndexOfOrNextLower(search, comparator) {
223
+ const { elements } = this;
224
+ if (elements.length === 0) {
161
225
  return undefined;
162
226
  }
163
- let index = AppendOnlySortedMap.indexOf(this.elements, search, comparator);
164
- if (index < 0) {
165
- index ^= AppendOnlySortedMap.failureXor;
166
- if (index > 0) {
167
- return index - 1;
227
+ let keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);
228
+ if (keyIndex < 0) {
229
+ keyIndex ^= AppendOnlySortedMap.failureXor;
230
+ if (keyIndex > 0) {
231
+ return keyIndex - 2;
168
232
  }
169
233
  return undefined;
170
234
  }
171
- return index;
235
+ return keyIndex;
172
236
  }
173
237
  getPairOrNextHigherBy(search, comparator) {
174
- const index = this.getIndexOfOrNextHigher(search, comparator);
175
- if (index === undefined) {
238
+ const keyIndex = this.getKeyIndexOfOrNextHigher(search, comparator);
239
+ if (keyIndex === undefined) {
176
240
  return undefined;
177
241
  }
178
- return this.elements[index];
242
+ return [this.elements[keyIndex], this.elements[keyIndex + 1]];
179
243
  }
180
- getIndexOfOrNextHigher(search, comparator) {
181
- const { size } = this;
182
- if (size === 0) {
244
+ getKeyIndexOfOrNextHigher(search, comparator) {
245
+ const { elements } = this;
246
+ const { length } = elements;
247
+ if (length === 0) {
183
248
  return undefined;
184
249
  }
185
- let index = AppendOnlySortedMap.indexOf(this.elements, search, comparator);
186
- if (index < 0) {
187
- index ^= AppendOnlySortedMap.failureXor;
188
- if (index < size) {
189
- return index;
250
+ let keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);
251
+ if (keyIndex < 0) {
252
+ keyIndex ^= AppendOnlySortedMap.failureXor;
253
+ if (keyIndex < length) {
254
+ return keyIndex;
190
255
  }
191
256
  return undefined;
192
257
  }
193
- return index;
258
+ return keyIndex;
194
259
  }
195
260
  /**
196
261
  * Performs a binary search on the sorted array.
197
- * @param elements
198
- * @param search
199
- * @param comparator
200
- * @returns the index of `search`, or (if not present) the index it would have been inserted into xor'd with `failureXor`. Note that
201
- * negating is not an adequate solution as that could result in -0.
262
+ * @returns the index of the key for `search`, or (if not present) the index it would have been inserted into xor'd
263
+ * with `failureXor`. Note that negating is not an adequate solution as that could result in -0.
202
264
  */
203
- static indexOf(elements, search, comparator) {
265
+ static keyIndexOf(elements, search, comparator) {
266
+ // Low, high, and mid are addresses of [K,V] pairs and *not* key indices
204
267
  let low = 0;
205
- let high = elements.length;
268
+ let high = elements.length / 2;
206
269
  let mid = high >> 1;
207
270
  while (low < high) {
208
- const c = comparator(search, elements[mid]);
271
+ const keyIndex = mid * 2;
272
+ const c = comparator(search, elements[keyIndex], elements[keyIndex + 1]);
209
273
  if (c > 0) {
210
274
  low = mid + 1;
211
275
  }
@@ -213,14 +277,14 @@ export class AppendOnlySortedMap {
213
277
  high = mid;
214
278
  }
215
279
  else if (c === 0) {
216
- return mid;
280
+ return keyIndex;
217
281
  }
218
282
  else {
219
283
  fail('Invalid comparator.');
220
284
  }
221
285
  mid = (low + high) >> 1;
222
286
  }
223
- return mid ^ AppendOnlySortedMap.failureXor;
287
+ return (mid * 2) ^ AppendOnlySortedMap.failureXor;
224
288
  }
225
289
  }
226
290
  /**
@@ -236,37 +300,37 @@ export class AppendOnlyDoublySortedMap extends AppendOnlySortedMap {
236
300
  super(keyComparator);
237
301
  this.extractSearchValue = extractSearchValue;
238
302
  this.valueComparator = valueComparator;
239
- this.compareValues = (search, element) => {
240
- return this.valueComparator(search, element[1]);
303
+ this.compareValues = (search, _, value) => {
304
+ return this.valueComparator(search, this.extractSearchValue(value));
241
305
  };
242
306
  }
243
307
  append(key, value) {
244
- if (this.size !== 0 &&
245
- this.valueComparator(this.extractSearchValue(value), this.elements[this.size - 1][1]) <= 0) {
308
+ if (this.elements.length !== 0 &&
309
+ this.valueComparator(this.extractSearchValue(value), this.extractSearchValue(this.maxValue())) <= 0) {
246
310
  fail('Inserted value must be > all others in the map.');
247
311
  }
248
312
  super.append(key, value);
249
313
  }
250
314
  /**
251
- * @param value the value to lookup.
315
+ * @param value - the value to lookup.
252
316
  * @returns the key associated with `value` if such an entry exists, and undefined otherwise.
253
317
  */
254
318
  getByValue(value) {
255
319
  var _a;
256
- const index = AppendOnlySortedMap.indexOf(this.elements, value, this.compareValues);
320
+ const index = AppendOnlySortedMap.keyIndexOf(this.elements, value, this.compareValues);
257
321
  return (_a = this.elements[index]) === null || _a === void 0 ? void 0 : _a[0];
258
322
  }
259
323
  /**
260
- * @param searchValue the search value to lookup.
261
- * @returns the entry who's value, when run through the extractor provided to the constructor, matches `searchValue`. If no such entry
262
- * exists, this method returns the next lower entry as determined by the value comparator provided to the constructor. If no such entry
263
- * exists, this method returns undefined.
324
+ * @param searchValue - the search value to lookup.
325
+ * @returns the entry who's value, when run through the extractor provided to the constructor, matches
326
+ * `searchValue`. If no such entry exists, this method returns the next lower entry as determined by the value
327
+ * comparator provided to the constructor. If no such entry exists, this method returns undefined.
264
328
  */
265
329
  getPairOrNextLowerByValue(searchValue) {
266
330
  return this.getPairOrNextLowerBy(searchValue, this.compareValues);
267
331
  }
268
332
  /**
269
- * @param searchValue the search value to lookup.
333
+ * @param searchValue - the search value to lookup.
270
334
  * @returns the entry who's value, when run through the extractor provided to the constructor, matches `searchValue`. If no such entry
271
335
  * exists, this method returns the next higher entry as determined by the value comparator provided to the constructor. If no such entry
272
336
  * exists, this method returns undefined.
@@ -274,5 +338,18 @@ export class AppendOnlyDoublySortedMap extends AppendOnlySortedMap {
274
338
  getPairOrNextHigherByValue(searchValue) {
275
339
  return this.getPairOrNextHigherBy(searchValue, this.compareValues);
276
340
  }
341
+ /**
342
+ * Test-only expensive assertions to check the internal validity of the data structure.
343
+ */
344
+ assertValid() {
345
+ super.assertValid();
346
+ let prev;
347
+ for (const kv of this.entries()) {
348
+ if (prev !== undefined) {
349
+ assert(this.valueComparator(this.extractSearchValue(kv[1]), this.extractSearchValue(prev[1])) > 0, 'Values in map must be sorted.');
350
+ }
351
+ prev = kv;
352
+ }
353
+ }
277
354
  }
278
355
  //# sourceMappingURL=AppendOnlySortedMap.js.map