@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
@@ -13,102 +13,152 @@ const Common_1 = require("../Common");
13
13
  */
14
14
  class AppendOnlySortedMap {
15
15
  /**
16
- * @param comparator a comparator for keys
16
+ * @param comparator - a comparator for keys
17
17
  */
18
18
  constructor(comparator) {
19
19
  this.comparator = comparator;
20
20
  this.elements = [];
21
- this.compareKeys = (search, element) => {
22
- return this.comparator(search, element[0]);
23
- };
24
21
  }
25
22
  /**
26
23
  * @returns the number of entries in this map
27
24
  */
28
25
  get size() {
29
- return this.elements.length;
26
+ return this.elements.length / 2;
30
27
  }
31
28
  /**
32
29
  * @returns the min key in the map.
33
30
  */
34
31
  minKey() {
35
- var _a;
36
- return (_a = this.elements[0]) === null || _a === void 0 ? void 0 : _a[0];
32
+ return this.elements[0];
37
33
  }
38
34
  /**
39
35
  * @returns the max key in the map.
40
36
  */
41
37
  maxKey() {
42
- var _a;
43
- return (_a = this.elements[this.size - 1]) === null || _a === void 0 ? void 0 : _a[0];
38
+ return this.elements[this.elements.length - 2];
39
+ }
40
+ /**
41
+ * @returns the min value in the map.
42
+ */
43
+ minValue() {
44
+ return this.elements[1];
45
+ }
46
+ /**
47
+ * @returns the min value in the map.
48
+ */
49
+ maxValue() {
50
+ return this.elements[this.elements.length - 1];
51
+ }
52
+ /**
53
+ * @returns the min key in the map.
54
+ */
55
+ first() {
56
+ const { elements } = this;
57
+ const { length } = elements;
58
+ if (length === 0) {
59
+ return undefined;
60
+ }
61
+ return [elements[0], elements[1]];
62
+ }
63
+ /**
64
+ * @returns the max key in the map.
65
+ */
66
+ last() {
67
+ const { elements } = this;
68
+ const { length } = elements;
69
+ if (length === 0) {
70
+ return undefined;
71
+ }
72
+ const lastKeyIndex = length - 2;
73
+ return [elements[lastKeyIndex], elements[lastKeyIndex + 1]];
74
+ }
75
+ /**
76
+ * Returns the element at the insertion index.
77
+ */
78
+ getAtIndex(index) {
79
+ const realIndex = index * 2;
80
+ const { elements } = this;
81
+ if (realIndex < 0 || realIndex > elements.length - 1) {
82
+ return undefined;
83
+ }
84
+ return [elements[realIndex], elements[realIndex + 1]];
44
85
  }
45
86
  /**
46
87
  * @returns an iterable of the entries in the map.
47
88
  */
48
89
  *entries() {
49
- for (const entry of this.elements) {
50
- yield entry;
90
+ const { elements } = this;
91
+ for (let i = 0; i < elements.length; i += 2) {
92
+ yield [elements[i], elements[i + 1]];
51
93
  }
52
94
  }
53
95
  /**
54
96
  * @returns an iterable of the keys in the map.
55
97
  */
56
98
  *keys() {
57
- for (const entry of this.elements) {
58
- yield entry[0];
99
+ const { elements } = this;
100
+ for (let i = 0; i < elements.length; i += 2) {
101
+ yield elements[i];
59
102
  }
60
103
  }
61
104
  /**
62
105
  * @returns an iterable of the values in the map.
63
106
  */
64
107
  *values() {
65
- for (const entry of this.elements) {
66
- yield entry[1];
108
+ const { elements } = this;
109
+ for (let i = 0; i < elements.length; i += 2) {
110
+ yield elements[i + 1];
67
111
  }
68
112
  }
69
113
  /**
70
114
  * @returns an iterable of the entries in the map, reversed.
71
115
  */
72
116
  *entriesReversed() {
73
- for (let i = this.size - 1; i >= 0; i--) {
74
- yield this.elements[i];
117
+ const { elements } = this;
118
+ for (let i = elements.length - 2; i >= 0; i -= 2) {
119
+ yield [elements[i], elements[i + 1]];
75
120
  }
76
121
  }
77
122
  /**
78
- * Adds a new key/value pair to the map. `key` must be > to all keys in the map.
79
- * @param key the key to add.
80
- * @param value the value to add.
123
+ * Adds a new key/value pair to the map. `key` must be \> to all keys in the map.
124
+ * @param key - the key to add.
125
+ * @param value - the value to add.
81
126
  */
82
127
  append(key, value) {
83
- if (this.size !== 0 && this.comparator(key, this.elements[this.size - 1][0]) <= 0) {
84
- Common_1.fail('Inserted key must be > all others in the map.');
128
+ const { elements } = this;
129
+ const { length } = elements;
130
+ if (length !== 0 && this.comparator(key, this.maxKey()) <= 0) {
131
+ (0, Common_1.fail)('Inserted key must be > all others in the map.');
85
132
  }
86
- this.elements.push([key, value]);
133
+ elements.push(key);
134
+ elements.push(value);
87
135
  }
88
136
  /**
89
- * @param key the key to lookup.
137
+ * @param key - the key to lookup.
90
138
  * @returns the value associated with `key` if such an entry exists, and undefined otherwise.
91
139
  */
92
140
  get(key) {
93
- var _a;
94
- const index = AppendOnlySortedMap.indexOf(this.elements, key, this.compareKeys);
95
- return (_a = this.elements[index]) === null || _a === void 0 ? void 0 : _a[1];
141
+ const index = AppendOnlySortedMap.keyIndexOf(this.elements, key, this.comparator);
142
+ if (index < 0) {
143
+ return undefined;
144
+ }
145
+ return this.elements[index + 1];
96
146
  }
97
147
  /**
98
- * @param key the key to lookup.
148
+ * @param key - the key to lookup.
99
149
  * @returns the entry associated with `key` if such an entry exists, the entry associated with the next lower key if such an entry
100
150
  * exists, and undefined otherwise.
101
151
  */
102
152
  getPairOrNextLower(key) {
103
- return this.getPairOrNextLowerBy(key, this.compareKeys);
153
+ return this.getPairOrNextLowerBy(key, this.comparator);
104
154
  }
105
155
  /**
106
- * @param key the key to lookup.
156
+ * @param key - the key to lookup.
107
157
  * @returns the entry associated with `key` if such an entry exists, the entry associated with the next higher key if such an entry
108
158
  * exists, and undefined otherwise.
109
159
  */
110
160
  getPairOrNextHigher(key) {
111
- return this.getPairOrNextHigherBy(key, this.compareKeys);
161
+ return this.getPairOrNextHigherBy(key, this.comparator);
112
162
  }
113
163
  /**
114
164
  * Compares two `AppendOnlySortedMap`s.
@@ -117,12 +167,14 @@ class AppendOnlySortedMap {
117
167
  if (other === this) {
118
168
  return true;
119
169
  }
120
- if (this.size !== other.size) {
170
+ if (this.elements.length !== other.elements.length) {
121
171
  return false;
122
172
  }
123
- for (let i = this.size - 1; i >= 0; i--) {
124
- const [keyThis, valueThis] = this.elements[i];
125
- const [keyOther, valueOther] = other.elements[i];
173
+ for (let i = this.elements.length - 2; i >= 0; i -= 2) {
174
+ const keyThis = this.elements[i];
175
+ const valueThis = this.elements[i + 1];
176
+ const keyOther = other.elements[i];
177
+ const valueOther = other.elements[i + 1];
126
178
  if (this.comparator(keyThis, keyOther) !== 0) {
127
179
  return false;
128
180
  }
@@ -132,83 +184,95 @@ class AppendOnlySortedMap {
132
184
  }
133
185
  return true;
134
186
  }
187
+ /**
188
+ * Test-only expensive assertions to check the internal validity of the data structure.
189
+ */
190
+ assertValid() {
191
+ let prev;
192
+ for (const kv of this.entries()) {
193
+ if (prev !== undefined) {
194
+ (0, Common_1.assert)(this.comparator(kv[0], prev[0]) > 0, 'Keys in map must be sorted.');
195
+ }
196
+ prev = kv;
197
+ }
198
+ }
135
199
  /**
136
200
  * Queries a range of entries.
137
- * @param from the key to start the range query at, inclusive.
138
- * @param to the key to end the range query at, inclusive.
201
+ * @param from - the key to start the range query at, inclusive.
202
+ * @param to - the key to end the range query at, inclusive.
139
203
  * @returns the range of entries.
140
204
  */
141
205
  *getRange(from, to) {
142
- const indexFrom = this.getIndexOfOrNextHigher(from, this.compareKeys);
143
- if (indexFrom === undefined) {
206
+ const keyIndexFrom = this.getKeyIndexOfOrNextHigher(from, this.comparator);
207
+ if (keyIndexFrom === undefined) {
144
208
  return;
145
209
  }
146
- const indexTo = this.getIndexOfOrNextLower(to, this.compareKeys);
147
- if (indexTo === undefined) {
210
+ const keyIndexTo = this.getKeyIndexOfOrNextLower(to, this.comparator);
211
+ if (keyIndexTo === undefined) {
148
212
  return;
149
213
  }
150
- for (let i = indexFrom; i <= indexTo; i++) {
151
- yield this.elements[i];
214
+ for (let i = keyIndexFrom; i <= keyIndexTo; i += 2) {
215
+ yield [this.elements[i], this.elements[i + 1]];
152
216
  }
153
217
  }
154
218
  getPairOrNextLowerBy(search, comparator) {
155
- const index = this.getIndexOfOrNextLower(search, comparator);
156
- if (index === undefined) {
219
+ const keyIndex = this.getKeyIndexOfOrNextLower(search, comparator);
220
+ if (keyIndex === undefined) {
157
221
  return undefined;
158
222
  }
159
- return this.elements[index];
223
+ return [this.elements[keyIndex], this.elements[keyIndex + 1]];
160
224
  }
161
- getIndexOfOrNextLower(search, comparator) {
162
- const { size } = this;
163
- if (size === 0) {
225
+ getKeyIndexOfOrNextLower(search, comparator) {
226
+ const { elements } = this;
227
+ if (elements.length === 0) {
164
228
  return undefined;
165
229
  }
166
- let index = AppendOnlySortedMap.indexOf(this.elements, search, comparator);
167
- if (index < 0) {
168
- index ^= AppendOnlySortedMap.failureXor;
169
- if (index > 0) {
170
- return index - 1;
230
+ let keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);
231
+ if (keyIndex < 0) {
232
+ keyIndex ^= AppendOnlySortedMap.failureXor;
233
+ if (keyIndex > 0) {
234
+ return keyIndex - 2;
171
235
  }
172
236
  return undefined;
173
237
  }
174
- return index;
238
+ return keyIndex;
175
239
  }
176
240
  getPairOrNextHigherBy(search, comparator) {
177
- const index = this.getIndexOfOrNextHigher(search, comparator);
178
- if (index === undefined) {
241
+ const keyIndex = this.getKeyIndexOfOrNextHigher(search, comparator);
242
+ if (keyIndex === undefined) {
179
243
  return undefined;
180
244
  }
181
- return this.elements[index];
245
+ return [this.elements[keyIndex], this.elements[keyIndex + 1]];
182
246
  }
183
- getIndexOfOrNextHigher(search, comparator) {
184
- const { size } = this;
185
- if (size === 0) {
247
+ getKeyIndexOfOrNextHigher(search, comparator) {
248
+ const { elements } = this;
249
+ const { length } = elements;
250
+ if (length === 0) {
186
251
  return undefined;
187
252
  }
188
- let index = AppendOnlySortedMap.indexOf(this.elements, search, comparator);
189
- if (index < 0) {
190
- index ^= AppendOnlySortedMap.failureXor;
191
- if (index < size) {
192
- return index;
253
+ let keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);
254
+ if (keyIndex < 0) {
255
+ keyIndex ^= AppendOnlySortedMap.failureXor;
256
+ if (keyIndex < length) {
257
+ return keyIndex;
193
258
  }
194
259
  return undefined;
195
260
  }
196
- return index;
261
+ return keyIndex;
197
262
  }
198
263
  /**
199
264
  * Performs a binary search on the sorted array.
200
- * @param elements
201
- * @param search
202
- * @param comparator
203
- * @returns the index of `search`, or (if not present) the index it would have been inserted into xor'd with `failureXor`. Note that
204
- * negating is not an adequate solution as that could result in -0.
265
+ * @returns the index of the key for `search`, or (if not present) the index it would have been inserted into xor'd
266
+ * with `failureXor`. Note that negating is not an adequate solution as that could result in -0.
205
267
  */
206
- static indexOf(elements, search, comparator) {
268
+ static keyIndexOf(elements, search, comparator) {
269
+ // Low, high, and mid are addresses of [K,V] pairs and *not* key indices
207
270
  let low = 0;
208
- let high = elements.length;
271
+ let high = elements.length / 2;
209
272
  let mid = high >> 1;
210
273
  while (low < high) {
211
- const c = comparator(search, elements[mid]);
274
+ const keyIndex = mid * 2;
275
+ const c = comparator(search, elements[keyIndex], elements[keyIndex + 1]);
212
276
  if (c > 0) {
213
277
  low = mid + 1;
214
278
  }
@@ -216,14 +280,14 @@ class AppendOnlySortedMap {
216
280
  high = mid;
217
281
  }
218
282
  else if (c === 0) {
219
- return mid;
283
+ return keyIndex;
220
284
  }
221
285
  else {
222
- Common_1.fail('Invalid comparator.');
286
+ (0, Common_1.fail)('Invalid comparator.');
223
287
  }
224
288
  mid = (low + high) >> 1;
225
289
  }
226
- return mid ^ AppendOnlySortedMap.failureXor;
290
+ return (mid * 2) ^ AppendOnlySortedMap.failureXor;
227
291
  }
228
292
  }
229
293
  exports.AppendOnlySortedMap = AppendOnlySortedMap;
@@ -240,37 +304,37 @@ class AppendOnlyDoublySortedMap extends AppendOnlySortedMap {
240
304
  super(keyComparator);
241
305
  this.extractSearchValue = extractSearchValue;
242
306
  this.valueComparator = valueComparator;
243
- this.compareValues = (search, element) => {
244
- return this.valueComparator(search, element[1]);
307
+ this.compareValues = (search, _, value) => {
308
+ return this.valueComparator(search, this.extractSearchValue(value));
245
309
  };
246
310
  }
247
311
  append(key, value) {
248
- if (this.size !== 0 &&
249
- this.valueComparator(this.extractSearchValue(value), this.elements[this.size - 1][1]) <= 0) {
250
- Common_1.fail('Inserted value must be > all others in the map.');
312
+ if (this.elements.length !== 0 &&
313
+ this.valueComparator(this.extractSearchValue(value), this.extractSearchValue(this.maxValue())) <= 0) {
314
+ (0, Common_1.fail)('Inserted value must be > all others in the map.');
251
315
  }
252
316
  super.append(key, value);
253
317
  }
254
318
  /**
255
- * @param value the value to lookup.
319
+ * @param value - the value to lookup.
256
320
  * @returns the key associated with `value` if such an entry exists, and undefined otherwise.
257
321
  */
258
322
  getByValue(value) {
259
323
  var _a;
260
- const index = AppendOnlySortedMap.indexOf(this.elements, value, this.compareValues);
324
+ const index = AppendOnlySortedMap.keyIndexOf(this.elements, value, this.compareValues);
261
325
  return (_a = this.elements[index]) === null || _a === void 0 ? void 0 : _a[0];
262
326
  }
263
327
  /**
264
- * @param searchValue the search value to lookup.
265
- * @returns the entry who's value, when run through the extractor provided to the constructor, matches `searchValue`. If no such entry
266
- * exists, this method returns the next lower entry as determined by the value comparator provided to the constructor. If no such entry
267
- * exists, this method returns undefined.
328
+ * @param searchValue - the search value to lookup.
329
+ * @returns the entry who's value, when run through the extractor provided to the constructor, matches
330
+ * `searchValue`. If no such entry exists, this method returns the next lower entry as determined by the value
331
+ * comparator provided to the constructor. If no such entry exists, this method returns undefined.
268
332
  */
269
333
  getPairOrNextLowerByValue(searchValue) {
270
334
  return this.getPairOrNextLowerBy(searchValue, this.compareValues);
271
335
  }
272
336
  /**
273
- * @param searchValue the search value to lookup.
337
+ * @param searchValue - the search value to lookup.
274
338
  * @returns the entry who's value, when run through the extractor provided to the constructor, matches `searchValue`. If no such entry
275
339
  * exists, this method returns the next higher entry as determined by the value comparator provided to the constructor. If no such entry
276
340
  * exists, this method returns undefined.
@@ -278,6 +342,19 @@ class AppendOnlyDoublySortedMap extends AppendOnlySortedMap {
278
342
  getPairOrNextHigherByValue(searchValue) {
279
343
  return this.getPairOrNextHigherBy(searchValue, this.compareValues);
280
344
  }
345
+ /**
346
+ * Test-only expensive assertions to check the internal validity of the data structure.
347
+ */
348
+ assertValid() {
349
+ super.assertValid();
350
+ let prev;
351
+ for (const kv of this.entries()) {
352
+ if (prev !== undefined) {
353
+ (0, Common_1.assert)(this.valueComparator(this.extractSearchValue(kv[1]), this.extractSearchValue(prev[1])) > 0, 'Values in map must be sorted.');
354
+ }
355
+ prev = kv;
356
+ }
357
+ }
281
358
  }
282
359
  exports.AppendOnlyDoublySortedMap = AppendOnlyDoublySortedMap;
283
360
  //# sourceMappingURL=AppendOnlySortedMap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AppendOnlySortedMap.js","sourceRoot":"","sources":["../../src/id-compressor/AppendOnlySortedMap.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+BAA+B;AAE/B,sCAAiC;AAEjC;;;GAGG;AACH,MAAa,mBAAmB;IAG/B;;OAEG;IACH,YAAsC,UAAkC;QAAlC,eAAU,GAAV,UAAU,CAAwB;QALrD,aAAQ,GAAa,EAAE,CAAC;QA4E1B,gBAAW,GAAG,CAAC,MAAS,EAAE,OAAwB,EAAU,EAAE;YAC9E,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC;IAzEyE,CAAC;IAE5E;;OAEG;IACH,IAAW,IAAI;QACd,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,MAAM;;QACZ,aAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,0CAAG,CAAC,EAAE;IAC9B,CAAC;IAED;;OAEG;IACI,MAAM;;QACZ,aAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,0CAAG,CAAC,EAAE;IAC1C,CAAC;IAED;;OAEG;IACI,CAAC,OAAO;QACd,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClC,MAAM,KAAK,CAAC;SACZ;IACF,CAAC;IAED;;OAEG;IACI,CAAC,IAAI;QACX,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;SACf;IACF,CAAC;IAED;;OAEG;IACI,CAAC,MAAM;QACb,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE;YAClC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;SACf;IACF,CAAC;IAED;;OAEG;IACI,CAAC,eAAe;QACtB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;YACxC,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;SACvB;IACF,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,GAAM,EAAE,KAAQ;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;YAClF,aAAI,CAAC,+CAA+C,CAAC,CAAC;SACtD;QACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAClC,CAAC;IAMD;;;OAGG;IACI,GAAG,CAAC,GAAM;;QAChB,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAChF,aAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,0CAAG,CAAC,EAAE;IAClC,CAAC;IAED;;;;OAIG;IACI,kBAAkB,CAAC,GAAM;QAC/B,OAAO,IAAI,CAAC,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACzD,CAAC;IAED;;;;OAIG;IACI,mBAAmB,CAAC,GAAM;QAChC,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAgC,EAAE,aAAsC;QACrF,IAAI,KAAK,KAAK,IAAI,EAAE;YACnB,OAAO,IAAI,CAAC;SACZ;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE;YAC7B,OAAO,KAAK,CAAC;SACb;QAED,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE;YACxC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACjD,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE;gBAC7C,OAAO,KAAK,CAAC;aACb;YACD,IAAI,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE;gBAC1C,OAAO,KAAK,CAAC;aACb;SACD;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAED;;;;;OAKG;IACI,CAAC,QAAQ,CAAC,IAAO,EAAE,EAAK;QAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACtE,IAAI,SAAS,KAAK,SAAS,EAAE;YAC5B,OAAO;SACP;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,qBAAqB,CAAC,EAAE,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACjE,IAAI,OAAO,KAAK,SAAS,EAAE;YAC1B,OAAO;SACP;QAED,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,EAAE;YAC1C,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;SACvB;IACF,CAAC;IAES,oBAAoB,CAC7B,MAAS,EACT,UAA2D;QAE3D,MAAM,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC7D,IAAI,KAAK,KAAK,SAAS,EAAE;YACxB,OAAO,SAAS,CAAC;SACjB;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAEO,qBAAqB,CAC5B,MAAS,EACT,UAA2D;QAE3D,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QACtB,IAAI,IAAI,KAAK,CAAC,EAAE;YACf,OAAO,SAAS,CAAC;SACjB;QACD,IAAI,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC3E,IAAI,KAAK,GAAG,CAAC,EAAE;YACd,KAAK,IAAI,mBAAmB,CAAC,UAAU,CAAC;YACxC,IAAI,KAAK,GAAG,CAAC,EAAE;gBACd,OAAO,KAAK,GAAG,CAAC,CAAC;aACjB;YACD,OAAO,SAAS,CAAC;SACjB;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAES,qBAAqB,CAC9B,MAAS,EACT,UAA2D;QAE3D,MAAM,KAAK,GAAG,IAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC9D,IAAI,KAAK,KAAK,SAAS,EAAE;YACxB,OAAO,SAAS,CAAC;SACjB;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAEO,sBAAsB,CAC7B,MAAS,EACT,UAA2D;QAE3D,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;QACtB,IAAI,IAAI,KAAK,CAAC,EAAE;YACf,OAAO,SAAS,CAAC;SACjB;QACD,IAAI,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;QAC3E,IAAI,KAAK,GAAG,CAAC,EAAE;YACd,KAAK,IAAI,mBAAmB,CAAC,UAAU,CAAC;YACxC,IAAI,KAAK,GAAG,IAAI,EAAE;gBACjB,OAAO,KAAK,CAAC;aACb;YACD,OAAO,SAAS,CAAC;SACjB;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IAOD;;;;;;;OAOG;IACI,MAAM,CAAC,OAAO,CACpB,QAAsC,EACtC,MAAS,EACT,UAA2D;QAE3D,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,IAAI,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC3B,IAAI,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC;QACpB,OAAO,GAAG,GAAG,IAAI,EAAE;YAClB,MAAM,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG,CAAC,EAAE;gBACV,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC;aACd;iBAAM,IAAI,CAAC,GAAG,CAAC,EAAE;gBACjB,IAAI,GAAG,GAAG,CAAC;aACX;iBAAM,IAAI,CAAC,KAAK,CAAC,EAAE;gBACnB,OAAO,GAAG,CAAC;aACX;iBAAM;gBACN,aAAI,CAAC,qBAAqB,CAAC,CAAC;aAC5B;YACD,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;SACxB;QACD,OAAO,GAAG,GAAG,mBAAmB,CAAC,UAAU,CAAC;IAC7C,CAAC;;AA7PF,kDA8PC;AApCA;;GAEG;AACoB,8BAAU,GAAG,CAAC,CAAC,CAAC;AAmCxC;;;GAGG;AACH,MAAa,yBAAmC,SAAQ,mBAAyB;IAChF,YACC,aAAqC,EACpB,kBAAmC,EACnC,eAAgD;QAEjE,KAAK,CAAC,aAAa,CAAC,CAAC;QAHJ,uBAAkB,GAAlB,kBAAkB,CAAiB;QACnC,oBAAe,GAAf,eAAe,CAAiC;QAejD,kBAAa,GAAG,CAAC,MAAS,EAAE,OAAwB,EAAU,EAAE;YAChF,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACjD,CAAC,CAAC;IAdF,CAAC;IAEM,MAAM,CAAC,GAAM,EAAE,KAAQ;QAC7B,IACC,IAAI,CAAC,IAAI,KAAK,CAAC;YACf,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EACzF;YACD,aAAI,CAAC,iDAAiD,CAAC,CAAC;SACxD;QACD,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;IAMD;;;OAGG;IACI,UAAU,CAAC,KAAQ;;QACzB,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACpF,aAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,0CAAG,CAAC,EAAE;IAClC,CAAC;IAED;;;;;OAKG;IACI,yBAAyB,CAAC,WAAc;QAC9C,OAAO,IAAI,CAAC,oBAAoB,CAAC,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACnE,CAAC;IAED;;;;;OAKG;IACI,0BAA0B,CAAC,WAAc;QAC/C,OAAO,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACpE,CAAC;CACD;AAnDD,8DAmDC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable no-bitwise */\n\nimport { fail } from '../Common';\n\n/**\n * A map in which entries are always added in key-sorted order.\n * Supports appending and searching.\n */\nexport class AppendOnlySortedMap<K, V> {\n\tprotected readonly elements: [K, V][] = [];\n\n\t/**\n\t * @param comparator a comparator for keys\n\t */\n\tpublic constructor(protected readonly comparator: (a: K, b: K) => number) {}\n\n\t/**\n\t * @returns the number of entries in this map\n\t */\n\tpublic get size(): number {\n\t\treturn this.elements.length;\n\t}\n\n\t/**\n\t * @returns the min key in the map.\n\t */\n\tpublic minKey(): K | undefined {\n\t\treturn this.elements[0]?.[0];\n\t}\n\n\t/**\n\t * @returns the max key in the map.\n\t */\n\tpublic maxKey(): K | undefined {\n\t\treturn this.elements[this.size - 1]?.[0];\n\t}\n\n\t/**\n\t * @returns an iterable of the entries in the map.\n\t */\n\tpublic *entries(): IterableIterator<readonly [K, V]> {\n\t\tfor (const entry of this.elements) {\n\t\t\tyield entry;\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the keys in the map.\n\t */\n\tpublic *keys(): IterableIterator<K> {\n\t\tfor (const entry of this.elements) {\n\t\t\tyield entry[0];\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the values in the map.\n\t */\n\tpublic *values(): IterableIterator<V> {\n\t\tfor (const entry of this.elements) {\n\t\t\tyield entry[1];\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the entries in the map, reversed.\n\t */\n\tpublic *entriesReversed(): IterableIterator<readonly [K, V]> {\n\t\tfor (let i = this.size - 1; i >= 0; i--) {\n\t\t\tyield this.elements[i];\n\t\t}\n\t}\n\n\t/**\n\t * Adds a new key/value pair to the map. `key` must be > to all keys in the map.\n\t * @param key the key to add.\n\t * @param value the value to add.\n\t */\n\tpublic append(key: K, value: V): void {\n\t\tif (this.size !== 0 && this.comparator(key, this.elements[this.size - 1][0]) <= 0) {\n\t\t\tfail('Inserted key must be > all others in the map.');\n\t\t}\n\t\tthis.elements.push([key, value]);\n\t}\n\n\tprivate readonly compareKeys = (search: K, element: readonly [K, V]): number => {\n\t\treturn this.comparator(search, element[0]);\n\t};\n\n\t/**\n\t * @param key the key to lookup.\n\t * @returns the value associated with `key` if such an entry exists, and undefined otherwise.\n\t */\n\tpublic get(key: K): V | undefined {\n\t\tconst index = AppendOnlySortedMap.indexOf(this.elements, key, this.compareKeys);\n\t\treturn this.elements[index]?.[1];\n\t}\n\n\t/**\n\t * @param key the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next lower key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextLower(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextLowerBy(key, this.compareKeys);\n\t}\n\n\t/**\n\t * @param key the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next higher key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextHigher(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextHigherBy(key, this.compareKeys);\n\t}\n\n\t/**\n\t * Compares two `AppendOnlySortedMap`s.\n\t */\n\tpublic equals(other: AppendOnlySortedMap<K, V>, compareValues: (a: V, b: V) => boolean): boolean {\n\t\tif (other === this) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (this.size !== other.size) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = this.size - 1; i >= 0; i--) {\n\t\t\tconst [keyThis, valueThis] = this.elements[i];\n\t\t\tconst [keyOther, valueOther] = other.elements[i];\n\t\t\tif (this.comparator(keyThis, keyOther) !== 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!compareValues(valueThis, valueOther)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Queries a range of entries.\n\t * @param from the key to start the range query at, inclusive.\n\t * @param to the key to end the range query at, inclusive.\n\t * @returns the range of entries.\n\t */\n\tpublic *getRange(from: K, to: K): IterableIterator<readonly [K, V]> {\n\t\tconst indexFrom = this.getIndexOfOrNextHigher(from, this.compareKeys);\n\t\tif (indexFrom === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst indexTo = this.getIndexOfOrNextLower(to, this.compareKeys);\n\t\tif (indexTo === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = indexFrom; i <= indexTo; i++) {\n\t\t\tyield this.elements[i];\n\t\t}\n\t}\n\n\tprotected getPairOrNextLowerBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, element: readonly [K, V]) => number\n\t): readonly [K, V] | undefined {\n\t\tconst index = this.getIndexOfOrNextLower(search, comparator);\n\t\tif (index === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this.elements[index];\n\t}\n\n\tprivate getIndexOfOrNextLower<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, element: readonly [K, V]) => number\n\t): number | undefined {\n\t\tconst { size } = this;\n\t\tif (size === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet index = AppendOnlySortedMap.indexOf(this.elements, search, comparator);\n\t\tif (index < 0) {\n\t\t\tindex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (index > 0) {\n\t\t\t\treturn index - 1;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn index;\n\t}\n\n\tprotected getPairOrNextHigherBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, element: readonly [K, V]) => number\n\t): readonly [K, V] | undefined {\n\t\tconst index = this.getIndexOfOrNextHigher(search, comparator);\n\t\tif (index === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn this.elements[index];\n\t}\n\n\tprivate getIndexOfOrNextHigher<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, element: readonly [K, V]) => number\n\t): number | undefined {\n\t\tconst { size } = this;\n\t\tif (size === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet index = AppendOnlySortedMap.indexOf(this.elements, search, comparator);\n\t\tif (index < 0) {\n\t\t\tindex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (index < size) {\n\t\t\t\treturn index;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn index;\n\t}\n\n\t/**\n\t * The value xor'd with the result index when a search fails.\n\t */\n\tpublic static readonly failureXor = -1;\n\n\t/**\n\t * Performs a binary search on the sorted array.\n\t * @param elements\n\t * @param search\n\t * @param comparator\n\t * @returns the index of `search`, or (if not present) the index it would have been inserted into xor'd with `failureXor`. Note that\n\t * negating is not an adequate solution as that could result in -0.\n\t */\n\tpublic static indexOf<T, K, V>(\n\t\telements: readonly (readonly [K, V])[],\n\t\tsearch: T,\n\t\tcomparator: (search: T, element: readonly [K, V]) => number\n\t): number {\n\t\tlet low = 0;\n\t\tlet high = elements.length;\n\t\tlet mid = high >> 1;\n\t\twhile (low < high) {\n\t\t\tconst c = comparator(search, elements[mid]);\n\t\t\tif (c > 0) {\n\t\t\t\tlow = mid + 1;\n\t\t\t} else if (c < 0) {\n\t\t\t\thigh = mid;\n\t\t\t} else if (c === 0) {\n\t\t\t\treturn mid;\n\t\t\t} else {\n\t\t\t\tfail('Invalid comparator.');\n\t\t\t}\n\t\t\tmid = (low + high) >> 1;\n\t\t}\n\t\treturn mid ^ AppendOnlySortedMap.failureXor;\n\t}\n}\n\n/**\n * A map in which entries are always added in both key-sorted and value-sorted order.\n * Supports appending and searching.\n */\nexport class AppendOnlyDoublySortedMap<K, V, S> extends AppendOnlySortedMap<K, V> {\n\tpublic constructor(\n\t\tkeyComparator: (a: K, b: K) => number,\n\t\tprivate readonly extractSearchValue: (value: V) => S,\n\t\tprivate readonly valueComparator: (search: S, value: V) => number\n\t) {\n\t\tsuper(keyComparator);\n\t}\n\n\tpublic append(key: K, value: V): void {\n\t\tif (\n\t\t\tthis.size !== 0 &&\n\t\t\tthis.valueComparator(this.extractSearchValue(value), this.elements[this.size - 1][1]) <= 0\n\t\t) {\n\t\t\tfail('Inserted value must be > all others in the map.');\n\t\t}\n\t\tsuper.append(key, value);\n\t}\n\n\tprivate readonly compareValues = (search: S, element: readonly [K, V]): number => {\n\t\treturn this.valueComparator(search, element[1]);\n\t};\n\n\t/**\n\t * @param value the value to lookup.\n\t * @returns the key associated with `value` if such an entry exists, and undefined otherwise.\n\t */\n\tpublic getByValue(value: S): K | undefined {\n\t\tconst index = AppendOnlySortedMap.indexOf(this.elements, value, this.compareValues);\n\t\treturn this.elements[index]?.[0];\n\t}\n\n\t/**\n\t * @param searchValue the search value to lookup.\n\t * @returns the entry who's value, when run through the extractor provided to the constructor, matches `searchValue`. If no such entry\n\t * exists, this method returns the next lower entry as determined by the value comparator provided to the constructor. If no such entry\n\t * exists, this method returns undefined.\n\t */\n\tpublic getPairOrNextLowerByValue(searchValue: S): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextLowerBy(searchValue, this.compareValues);\n\t}\n\n\t/**\n\t * @param searchValue the search value to lookup.\n\t * @returns the entry who's value, when run through the extractor provided to the constructor, matches `searchValue`. If no such entry\n\t * exists, this method returns the next higher entry as determined by the value comparator provided to the constructor. If no such entry\n\t * exists, this method returns undefined.\n\t */\n\tpublic getPairOrNextHigherByValue(searchValue: S): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextHigherBy(searchValue, this.compareValues);\n\t}\n}\n"]}
1
+ {"version":3,"file":"AppendOnlySortedMap.js","sourceRoot":"","sources":["../../src/id-compressor/AppendOnlySortedMap.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable no-bitwise */\n\nimport { assert, fail } from '../Common';\n\n/**\n * A map in which entries are always added in key-sorted order.\n * Supports appending and searching.\n */\nexport class AppendOnlySortedMap<K, V> {\n\tprotected readonly elements: (K | V)[] = [];\n\n\t/**\n\t * @param comparator - a comparator for keys\n\t */\n\tpublic constructor(protected readonly comparator: (a: K, b: K) => number) {}\n\n\t/**\n\t * @returns the number of entries in this map\n\t */\n\tpublic get size(): number {\n\t\treturn this.elements.length / 2;\n\t}\n\n\t/**\n\t * @returns the min key in the map.\n\t */\n\tpublic minKey(): K | undefined {\n\t\treturn this.elements[0] as K | undefined;\n\t}\n\n\t/**\n\t * @returns the max key in the map.\n\t */\n\tpublic maxKey(): K | undefined {\n\t\treturn this.elements[this.elements.length - 2] as K | undefined;\n\t}\n\n\t/**\n\t * @returns the min value in the map.\n\t */\n\tpublic minValue(): V | undefined {\n\t\treturn this.elements[1] as V | undefined;\n\t}\n\n\t/**\n\t * @returns the min value in the map.\n\t */\n\tpublic maxValue(): V | undefined {\n\t\treturn this.elements[this.elements.length - 1] as V | undefined;\n\t}\n\n\t/**\n\t * @returns the min key in the map.\n\t */\n\tpublic first(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[0] as K, elements[1] as V];\n\t}\n\n\t/**\n\t * @returns the max key in the map.\n\t */\n\tpublic last(): [K, V] | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst lastKeyIndex = length - 2;\n\t\treturn [elements[lastKeyIndex] as K, elements[lastKeyIndex + 1] as V];\n\t}\n\n\t/**\n\t * Returns the element at the insertion index.\n\t */\n\tpublic getAtIndex(index: number): [K, V] | undefined {\n\t\tconst realIndex = index * 2;\n\t\tconst { elements } = this;\n\t\tif (realIndex < 0 || realIndex > elements.length - 1) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn [elements[realIndex] as K, elements[realIndex + 1] as V];\n\t}\n\n\t/**\n\t * @returns an iterable of the entries in the map.\n\t */\n\tpublic *entries(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the keys in the map.\n\t */\n\tpublic *keys(): IterableIterator<K> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i] as K;\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the values in the map.\n\t */\n\tpublic *values(): IterableIterator<V> {\n\t\tconst { elements } = this;\n\t\tfor (let i = 0; i < elements.length; i += 2) {\n\t\t\tyield elements[i + 1] as V;\n\t\t}\n\t}\n\n\t/**\n\t * @returns an iterable of the entries in the map, reversed.\n\t */\n\tpublic *entriesReversed(): IterableIterator<readonly [K, V]> {\n\t\tconst { elements } = this;\n\t\tfor (let i = elements.length - 2; i >= 0; i -= 2) {\n\t\t\tyield [elements[i] as K, elements[i + 1] as V];\n\t\t}\n\t}\n\n\t/**\n\t * Adds a new key/value pair to the map. `key` must be \\> to all keys in the map.\n\t * @param key - the key to add.\n\t * @param value - the value to add.\n\t */\n\tpublic append(key: K, value: V): void {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length !== 0 && this.comparator(key, this.maxKey() as K) <= 0) {\n\t\t\tfail('Inserted key must be > all others in the map.');\n\t\t}\n\t\telements.push(key);\n\t\telements.push(value);\n\t}\n\n\t/**\n\t * @param key - the key to lookup.\n\t * @returns the value associated with `key` if such an entry exists, and undefined otherwise.\n\t */\n\tpublic get(key: K): V | undefined {\n\t\tconst index = AppendOnlySortedMap.keyIndexOf(this.elements, key, this.comparator);\n\t\tif (index < 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\treturn this.elements[index + 1] as V;\n\t}\n\n\t/**\n\t * @param key - the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next lower key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextLower(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextLowerBy(key, this.comparator);\n\t}\n\n\t/**\n\t * @param key - the key to lookup.\n\t * @returns the entry associated with `key` if such an entry exists, the entry associated with the next higher key if such an entry\n\t * exists, and undefined otherwise.\n\t */\n\tpublic getPairOrNextHigher(key: K): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextHigherBy(key, this.comparator);\n\t}\n\n\t/**\n\t * Compares two `AppendOnlySortedMap`s.\n\t */\n\tpublic equals(other: AppendOnlySortedMap<K, V>, compareValues: (a: V, b: V) => boolean): boolean {\n\t\tif (other === this) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (this.elements.length !== other.elements.length) {\n\t\t\treturn false;\n\t\t}\n\n\t\tfor (let i = this.elements.length - 2; i >= 0; i -= 2) {\n\t\t\tconst keyThis = this.elements[i] as K;\n\t\t\tconst valueThis = this.elements[i + 1] as V;\n\t\t\tconst keyOther = other.elements[i] as K;\n\t\t\tconst valueOther = other.elements[i + 1] as V;\n\t\t\tif (this.comparator(keyThis, keyOther) !== 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!compareValues(valueThis, valueOther)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Test-only expensive assertions to check the internal validity of the data structure.\n\t */\n\tpublic assertValid(): void {\n\t\tlet prev: readonly [K, unknown] | undefined;\n\t\tfor (const kv of this.entries()) {\n\t\t\tif (prev !== undefined) {\n\t\t\t\tassert(this.comparator(kv[0], prev[0]) > 0, 'Keys in map must be sorted.');\n\t\t\t}\n\t\t\tprev = kv;\n\t\t}\n\t}\n\n\t/**\n\t * Queries a range of entries.\n\t * @param from - the key to start the range query at, inclusive.\n\t * @param to - the key to end the range query at, inclusive.\n\t * @returns the range of entries.\n\t */\n\tpublic *getRange(from: K, to: K): IterableIterator<readonly [K, V]> {\n\t\tconst keyIndexFrom = this.getKeyIndexOfOrNextHigher(from, this.comparator);\n\t\tif (keyIndexFrom === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst keyIndexTo = this.getKeyIndexOfOrNextLower(to, this.comparator);\n\t\tif (keyIndexTo === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (let i = keyIndexFrom; i <= keyIndexTo; i += 2) {\n\t\t\tyield [this.elements[i] as K, this.elements[i + 1] as V];\n\t\t}\n\t}\n\n\tprotected getPairOrNextLowerBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextLower(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextLower<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tif (elements.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex > 0) {\n\t\t\t\treturn keyIndex - 2;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\tprotected getPairOrNextHigherBy<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number\n\t): readonly [K, V] | undefined {\n\t\tconst keyIndex = this.getKeyIndexOfOrNextHigher(search, comparator);\n\t\tif (keyIndex === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn [this.elements[keyIndex] as K, this.elements[keyIndex + 1] as V];\n\t}\n\n\tprivate getKeyIndexOfOrNextHigher<T>(\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number\n\t): number | undefined {\n\t\tconst { elements } = this;\n\t\tconst { length } = elements;\n\t\tif (length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tlet keyIndex = AppendOnlySortedMap.keyIndexOf(elements, search, comparator);\n\t\tif (keyIndex < 0) {\n\t\t\tkeyIndex ^= AppendOnlySortedMap.failureXor;\n\t\t\tif (keyIndex < length) {\n\t\t\t\treturn keyIndex;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn keyIndex;\n\t}\n\n\t/**\n\t * The value xor'd with the result index when a search fails.\n\t */\n\tpublic static readonly failureXor = -1;\n\n\t/**\n\t * Performs a binary search on the sorted array.\n\t * @returns the index of the key for `search`, or (if not present) the index it would have been inserted into xor'd\n\t * with `failureXor`. Note that negating is not an adequate solution as that could result in -0.\n\t */\n\tpublic static keyIndexOf<T, K, V>(\n\t\telements: readonly (K | V)[],\n\t\tsearch: T,\n\t\tcomparator: (search: T, key: K, value: V) => number\n\t): number {\n\t\t// Low, high, and mid are addresses of [K,V] pairs and *not* key indices\n\t\tlet low = 0;\n\t\tlet high = elements.length / 2;\n\t\tlet mid = high >> 1;\n\t\twhile (low < high) {\n\t\t\tconst keyIndex = mid * 2;\n\t\t\tconst c = comparator(search, elements[keyIndex] as K, elements[keyIndex + 1] as V);\n\t\t\tif (c > 0) {\n\t\t\t\tlow = mid + 1;\n\t\t\t} else if (c < 0) {\n\t\t\t\thigh = mid;\n\t\t\t} else if (c === 0) {\n\t\t\t\treturn keyIndex;\n\t\t\t} else {\n\t\t\t\tfail('Invalid comparator.');\n\t\t\t}\n\t\t\tmid = (low + high) >> 1;\n\t\t}\n\t\treturn (mid * 2) ^ AppendOnlySortedMap.failureXor;\n\t}\n}\n\n/**\n * A map in which entries are always added in both key-sorted and value-sorted order.\n * Supports appending and searching.\n */\nexport class AppendOnlyDoublySortedMap<K, V, S> extends AppendOnlySortedMap<K, V> {\n\tpublic constructor(\n\t\tkeyComparator: (a: K, b: K) => number,\n\t\tprivate readonly extractSearchValue: (value: V) => S,\n\t\tprivate readonly valueComparator: (search: S, value: S) => number\n\t) {\n\t\tsuper(keyComparator);\n\t}\n\n\tpublic append(key: K, value: V): void {\n\t\tif (\n\t\t\tthis.elements.length !== 0 &&\n\t\t\tthis.valueComparator(this.extractSearchValue(value), this.extractSearchValue(this.maxValue() as V)) <= 0\n\t\t) {\n\t\t\tfail('Inserted value must be > all others in the map.');\n\t\t}\n\t\tsuper.append(key, value);\n\t}\n\n\tprivate readonly compareValues = (search: S, _: K, value: V): number => {\n\t\treturn this.valueComparator(search, this.extractSearchValue(value));\n\t};\n\n\t/**\n\t * @param value - the value to lookup.\n\t * @returns the key associated with `value` if such an entry exists, and undefined otherwise.\n\t */\n\tpublic getByValue(value: S): K | undefined {\n\t\tconst index = AppendOnlySortedMap.keyIndexOf(this.elements, value, this.compareValues);\n\t\treturn this.elements[index]?.[0];\n\t}\n\n\t/**\n\t * @param searchValue - the search value to lookup.\n\t * @returns the entry who's value, when run through the extractor provided to the constructor, matches\n\t * `searchValue`. If no such entry exists, this method returns the next lower entry as determined by the value\n\t * comparator provided to the constructor. If no such entry exists, this method returns undefined.\n\t */\n\tpublic getPairOrNextLowerByValue(searchValue: S): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextLowerBy(searchValue, this.compareValues);\n\t}\n\n\t/**\n\t * @param searchValue - the search value to lookup.\n\t * @returns the entry who's value, when run through the extractor provided to the constructor, matches `searchValue`. If no such entry\n\t * exists, this method returns the next higher entry as determined by the value comparator provided to the constructor. If no such entry\n\t * exists, this method returns undefined.\n\t */\n\tpublic getPairOrNextHigherByValue(searchValue: S): readonly [K, V] | undefined {\n\t\treturn this.getPairOrNextHigherBy(searchValue, this.compareValues);\n\t}\n\n\t/**\n\t * Test-only expensive assertions to check the internal validity of the data structure.\n\t */\n\tpublic assertValid(): void {\n\t\tsuper.assertValid();\n\t\tlet prev: readonly [unknown, V] | undefined;\n\t\tfor (const kv of this.entries()) {\n\t\t\tif (prev !== undefined) {\n\t\t\t\tassert(\n\t\t\t\t\tthis.valueComparator(this.extractSearchValue(kv[1]), this.extractSearchValue(prev[1])) > 0,\n\t\t\t\t\t'Values in map must be sorted.'\n\t\t\t\t);\n\t\t\t}\n\t\t\tprev = kv;\n\t\t}\n\t}\n}\n"]}