@fluidframework/tree 2.13.0 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (360) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/api-report/tree.alpha.api.md +22 -12
  3. package/api-report/tree.beta.api.md +9 -5
  4. package/api-report/tree.legacy.alpha.api.md +15 -5
  5. package/api-report/tree.legacy.public.api.md +9 -5
  6. package/api-report/tree.public.api.md +9 -5
  7. package/assertTagging.config.mjs +14 -0
  8. package/dist/alpha.d.ts +3 -0
  9. package/dist/core/index.d.ts +2 -2
  10. package/dist/core/index.d.ts.map +1 -1
  11. package/dist/core/index.js +6 -4
  12. package/dist/core/index.js.map +1 -1
  13. package/dist/core/rebase/index.d.ts +2 -2
  14. package/dist/core/rebase/index.d.ts.map +1 -1
  15. package/dist/core/rebase/index.js +5 -1
  16. package/dist/core/rebase/index.js.map +1 -1
  17. package/dist/core/rebase/types.d.ts +5 -4
  18. package/dist/core/rebase/types.d.ts.map +1 -1
  19. package/dist/core/rebase/types.js +29 -1
  20. package/dist/core/rebase/types.js.map +1 -1
  21. package/dist/core/rebase/utils.d.ts +10 -0
  22. package/dist/core/rebase/utils.d.ts.map +1 -1
  23. package/dist/core/rebase/utils.js +22 -1
  24. package/dist/core/rebase/utils.js.map +1 -1
  25. package/dist/core/tree/delta.d.ts +21 -26
  26. package/dist/core/tree/delta.d.ts.map +1 -1
  27. package/dist/core/tree/delta.js.map +1 -1
  28. package/dist/core/tree/deltaUtil.d.ts +1 -3
  29. package/dist/core/tree/deltaUtil.d.ts.map +1 -1
  30. package/dist/core/tree/deltaUtil.js +2 -14
  31. package/dist/core/tree/deltaUtil.js.map +1 -1
  32. package/dist/core/tree/index.d.ts +1 -1
  33. package/dist/core/tree/index.d.ts.map +1 -1
  34. package/dist/core/tree/index.js +1 -3
  35. package/dist/core/tree/index.js.map +1 -1
  36. package/dist/core/tree/visitDelta.d.ts.map +1 -1
  37. package/dist/core/tree/visitDelta.js +82 -80
  38. package/dist/core/tree/visitDelta.js.map +1 -1
  39. package/dist/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  40. package/dist/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  41. package/dist/feature-libraries/deltaUtils.d.ts.map +1 -1
  42. package/dist/feature-libraries/deltaUtils.js +13 -0
  43. package/dist/feature-libraries/deltaUtils.js.map +1 -1
  44. package/dist/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  45. package/dist/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  46. package/dist/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  47. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts +5 -5
  48. package/dist/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  49. package/dist/feature-libraries/modular-schema/crossFieldQueries.js +2 -9
  50. package/dist/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  51. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts +19 -2
  52. package/dist/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  53. package/dist/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  54. package/dist/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  55. package/dist/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  56. package/dist/feature-libraries/modular-schema/index.d.ts +2 -2
  57. package/dist/feature-libraries/modular-schema/index.d.ts.map +1 -1
  58. package/dist/feature-libraries/modular-schema/index.js.map +1 -1
  59. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
  60. package/dist/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  61. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js +8 -8
  62. package/dist/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  63. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts +4 -4
  64. package/dist/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  65. package/dist/feature-libraries/modular-schema/modularChangeFamily.js +105 -199
  66. package/dist/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  67. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts +11 -20
  68. package/dist/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  69. package/dist/feature-libraries/modular-schema/modularChangeTypes.js +20 -0
  70. package/dist/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  71. package/dist/feature-libraries/optional-field/optionalField.d.ts +3 -3
  72. package/dist/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  73. package/dist/feature-libraries/optional-field/optionalField.js.map +1 -1
  74. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
  75. package/dist/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  76. package/dist/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  77. package/dist/feature-libraries/sequence-field/rebase.js +4 -4
  78. package/dist/feature-libraries/sequence-field/rebase.js.map +1 -1
  79. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  80. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  81. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  82. package/dist/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  83. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
  84. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  85. package/dist/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  86. package/dist/feature-libraries/sequence-field/utils.js +36 -4
  87. package/dist/feature-libraries/sequence-field/utils.js.map +1 -1
  88. package/dist/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  89. package/dist/feature-libraries/treeCursorUtils.js +5 -2
  90. package/dist/feature-libraries/treeCursorUtils.js.map +1 -1
  91. package/dist/index.d.ts +26 -2
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +6 -2
  94. package/dist/index.js.map +1 -1
  95. package/dist/legacy.d.ts +3 -1
  96. package/dist/package.json +2 -1
  97. package/dist/packageVersion.d.ts +1 -1
  98. package/dist/packageVersion.js +1 -1
  99. package/dist/packageVersion.js.map +1 -1
  100. package/dist/shared-tree/index.d.ts +2 -1
  101. package/dist/shared-tree/index.d.ts.map +1 -1
  102. package/dist/shared-tree/index.js +7 -2
  103. package/dist/shared-tree/index.js.map +1 -1
  104. package/dist/shared-tree/publicContracts.d.ts +18 -0
  105. package/dist/shared-tree/publicContracts.d.ts.map +1 -0
  106. package/dist/shared-tree/publicContracts.js +24 -0
  107. package/dist/shared-tree/publicContracts.js.map +1 -0
  108. package/dist/shared-tree/sharedTree.d.ts +38 -18
  109. package/dist/shared-tree/sharedTree.d.ts.map +1 -1
  110. package/dist/shared-tree/sharedTree.js +41 -40
  111. package/dist/shared-tree/sharedTree.js.map +1 -1
  112. package/dist/shared-tree/treeCheckout.d.ts.map +1 -1
  113. package/dist/shared-tree/treeCheckout.js +12 -8
  114. package/dist/shared-tree/treeCheckout.js.map +1 -1
  115. package/dist/simple-tree/api/schemaFactory.d.ts +2 -0
  116. package/dist/simple-tree/api/schemaFactory.d.ts.map +1 -1
  117. package/dist/simple-tree/api/schemaFactory.js +2 -0
  118. package/dist/simple-tree/api/schemaFactory.js.map +1 -1
  119. package/dist/simple-tree/api/tree.d.ts +4 -0
  120. package/dist/simple-tree/api/tree.d.ts.map +1 -1
  121. package/dist/simple-tree/api/tree.js.map +1 -1
  122. package/dist/simple-tree/api/treeNodeApi.js +1 -1
  123. package/dist/simple-tree/api/treeNodeApi.js.map +1 -1
  124. package/dist/simple-tree/arrayNode.js +1 -1
  125. package/dist/simple-tree/arrayNode.js.map +1 -1
  126. package/dist/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  127. package/dist/simple-tree/core/getOrCreateNode.js +1 -1
  128. package/dist/simple-tree/core/getOrCreateNode.js.map +1 -1
  129. package/dist/simple-tree/core/index.d.ts +1 -1
  130. package/dist/simple-tree/core/index.d.ts.map +1 -1
  131. package/dist/simple-tree/core/index.js +2 -2
  132. package/dist/simple-tree/core/index.js.map +1 -1
  133. package/dist/simple-tree/core/treeNodeKernel.d.ts +2 -6
  134. package/dist/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  135. package/dist/simple-tree/core/treeNodeKernel.js +10 -13
  136. package/dist/simple-tree/core/treeNodeKernel.js.map +1 -1
  137. package/dist/simple-tree/proxies.js +1 -1
  138. package/dist/simple-tree/proxies.js.map +1 -1
  139. package/dist/simple-tree/toMapTree.js +1 -1
  140. package/dist/simple-tree/toMapTree.js.map +1 -1
  141. package/dist/util/bTreeUtils.d.ts +10 -0
  142. package/dist/util/bTreeUtils.d.ts.map +1 -0
  143. package/dist/util/bTreeUtils.js +52 -0
  144. package/dist/util/bTreeUtils.js.map +1 -0
  145. package/dist/util/idAllocator.d.ts +0 -2
  146. package/dist/util/idAllocator.d.ts.map +1 -1
  147. package/dist/util/idAllocator.js +0 -2
  148. package/dist/util/idAllocator.js.map +1 -1
  149. package/dist/util/index.d.ts +2 -1
  150. package/dist/util/index.d.ts.map +1 -1
  151. package/dist/util/index.js +5 -1
  152. package/dist/util/index.js.map +1 -1
  153. package/dist/util/rangeMap.d.ts +61 -30
  154. package/dist/util/rangeMap.d.ts.map +1 -1
  155. package/dist/util/rangeMap.js +189 -117
  156. package/dist/util/rangeMap.js.map +1 -1
  157. package/dist/util/utils.d.ts +4 -1
  158. package/dist/util/utils.d.ts.map +1 -1
  159. package/dist/util/utils.js +7 -1
  160. package/dist/util/utils.js.map +1 -1
  161. package/lib/alpha.d.ts +3 -0
  162. package/lib/core/index.d.ts +2 -2
  163. package/lib/core/index.d.ts.map +1 -1
  164. package/lib/core/index.js +2 -2
  165. package/lib/core/index.js.map +1 -1
  166. package/lib/core/rebase/index.d.ts +2 -2
  167. package/lib/core/rebase/index.d.ts.map +1 -1
  168. package/lib/core/rebase/index.js +2 -2
  169. package/lib/core/rebase/index.js.map +1 -1
  170. package/lib/core/rebase/types.d.ts +5 -4
  171. package/lib/core/rebase/types.d.ts.map +1 -1
  172. package/lib/core/rebase/types.js +26 -1
  173. package/lib/core/rebase/types.js.map +1 -1
  174. package/lib/core/rebase/utils.d.ts +10 -0
  175. package/lib/core/rebase/utils.d.ts.map +1 -1
  176. package/lib/core/rebase/utils.js +20 -0
  177. package/lib/core/rebase/utils.js.map +1 -1
  178. package/lib/core/tree/delta.d.ts +21 -26
  179. package/lib/core/tree/delta.d.ts.map +1 -1
  180. package/lib/core/tree/delta.js.map +1 -1
  181. package/lib/core/tree/deltaUtil.d.ts +1 -3
  182. package/lib/core/tree/deltaUtil.d.ts.map +1 -1
  183. package/lib/core/tree/deltaUtil.js +1 -12
  184. package/lib/core/tree/deltaUtil.js.map +1 -1
  185. package/lib/core/tree/index.d.ts +1 -1
  186. package/lib/core/tree/index.d.ts.map +1 -1
  187. package/lib/core/tree/index.js +1 -1
  188. package/lib/core/tree/index.js.map +1 -1
  189. package/lib/core/tree/visitDelta.d.ts.map +1 -1
  190. package/lib/core/tree/visitDelta.js +82 -80
  191. package/lib/core/tree/visitDelta.js.map +1 -1
  192. package/lib/feature-libraries/default-schema/defaultFieldKinds.d.ts.map +1 -1
  193. package/lib/feature-libraries/default-schema/defaultFieldKinds.js.map +1 -1
  194. package/lib/feature-libraries/deltaUtils.d.ts.map +1 -1
  195. package/lib/feature-libraries/deltaUtils.js +13 -0
  196. package/lib/feature-libraries/deltaUtils.js.map +1 -1
  197. package/lib/feature-libraries/forest-summary/forestSummarizer.d.ts.map +1 -1
  198. package/lib/feature-libraries/forest-summary/forestSummarizer.js +1 -6
  199. package/lib/feature-libraries/forest-summary/forestSummarizer.js.map +1 -1
  200. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts +5 -5
  201. package/lib/feature-libraries/modular-schema/crossFieldQueries.d.ts.map +1 -1
  202. package/lib/feature-libraries/modular-schema/crossFieldQueries.js +2 -9
  203. package/lib/feature-libraries/modular-schema/crossFieldQueries.js.map +1 -1
  204. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts +19 -2
  205. package/lib/feature-libraries/modular-schema/fieldChangeHandler.d.ts.map +1 -1
  206. package/lib/feature-libraries/modular-schema/fieldChangeHandler.js.map +1 -1
  207. package/lib/feature-libraries/modular-schema/genericFieldKind.d.ts.map +1 -1
  208. package/lib/feature-libraries/modular-schema/genericFieldKind.js.map +1 -1
  209. package/lib/feature-libraries/modular-schema/index.d.ts +2 -2
  210. package/lib/feature-libraries/modular-schema/index.d.ts.map +1 -1
  211. package/lib/feature-libraries/modular-schema/index.js.map +1 -1
  212. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts +1 -1
  213. package/lib/feature-libraries/modular-schema/modularChangeCodecs.d.ts.map +1 -1
  214. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js +4 -4
  215. package/lib/feature-libraries/modular-schema/modularChangeCodecs.js.map +1 -1
  216. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts +4 -4
  217. package/lib/feature-libraries/modular-schema/modularChangeFamily.d.ts.map +1 -1
  218. package/lib/feature-libraries/modular-schema/modularChangeFamily.js +74 -166
  219. package/lib/feature-libraries/modular-schema/modularChangeFamily.js.map +1 -1
  220. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts +11 -20
  221. package/lib/feature-libraries/modular-schema/modularChangeTypes.d.ts.map +1 -1
  222. package/lib/feature-libraries/modular-schema/modularChangeTypes.js +18 -1
  223. package/lib/feature-libraries/modular-schema/modularChangeTypes.js.map +1 -1
  224. package/lib/feature-libraries/optional-field/optionalField.d.ts +3 -3
  225. package/lib/feature-libraries/optional-field/optionalField.d.ts.map +1 -1
  226. package/lib/feature-libraries/optional-field/optionalField.js.map +1 -1
  227. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts +1 -1
  228. package/lib/feature-libraries/sequence-field/moveEffectTable.d.ts.map +1 -1
  229. package/lib/feature-libraries/sequence-field/moveEffectTable.js.map +1 -1
  230. package/lib/feature-libraries/sequence-field/rebase.js +4 -4
  231. package/lib/feature-libraries/sequence-field/rebase.js.map +1 -1
  232. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js +1 -1
  233. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV1.js.map +1 -1
  234. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js +1 -1
  235. package/lib/feature-libraries/sequence-field/sequenceFieldCodecV2.js.map +1 -1
  236. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts +2 -3
  237. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.d.ts.map +1 -1
  238. package/lib/feature-libraries/sequence-field/sequenceFieldToDelta.js.map +1 -1
  239. package/lib/feature-libraries/sequence-field/utils.js +36 -4
  240. package/lib/feature-libraries/sequence-field/utils.js.map +1 -1
  241. package/lib/feature-libraries/treeCursorUtils.d.ts.map +1 -1
  242. package/lib/feature-libraries/treeCursorUtils.js +6 -3
  243. package/lib/feature-libraries/treeCursorUtils.js.map +1 -1
  244. package/lib/index.d.ts +26 -2
  245. package/lib/index.d.ts.map +1 -1
  246. package/lib/index.js +1 -1
  247. package/lib/index.js.map +1 -1
  248. package/lib/legacy.d.ts +3 -1
  249. package/lib/packageVersion.d.ts +1 -1
  250. package/lib/packageVersion.js +1 -1
  251. package/lib/packageVersion.js.map +1 -1
  252. package/lib/shared-tree/index.d.ts +2 -1
  253. package/lib/shared-tree/index.d.ts.map +1 -1
  254. package/lib/shared-tree/index.js +2 -1
  255. package/lib/shared-tree/index.js.map +1 -1
  256. package/lib/shared-tree/publicContracts.d.ts +18 -0
  257. package/lib/shared-tree/publicContracts.d.ts.map +1 -0
  258. package/lib/shared-tree/publicContracts.js +21 -0
  259. package/lib/shared-tree/publicContracts.js.map +1 -0
  260. package/lib/shared-tree/sharedTree.d.ts +38 -18
  261. package/lib/shared-tree/sharedTree.d.ts.map +1 -1
  262. package/lib/shared-tree/sharedTree.js +40 -39
  263. package/lib/shared-tree/sharedTree.js.map +1 -1
  264. package/lib/shared-tree/treeCheckout.d.ts.map +1 -1
  265. package/lib/shared-tree/treeCheckout.js +13 -9
  266. package/lib/shared-tree/treeCheckout.js.map +1 -1
  267. package/lib/simple-tree/api/schemaFactory.d.ts +2 -0
  268. package/lib/simple-tree/api/schemaFactory.d.ts.map +1 -1
  269. package/lib/simple-tree/api/schemaFactory.js +2 -0
  270. package/lib/simple-tree/api/schemaFactory.js.map +1 -1
  271. package/lib/simple-tree/api/tree.d.ts +4 -0
  272. package/lib/simple-tree/api/tree.d.ts.map +1 -1
  273. package/lib/simple-tree/api/tree.js.map +1 -1
  274. package/lib/simple-tree/api/treeNodeApi.js +1 -1
  275. package/lib/simple-tree/api/treeNodeApi.js.map +1 -1
  276. package/lib/simple-tree/arrayNode.js +1 -1
  277. package/lib/simple-tree/arrayNode.js.map +1 -1
  278. package/lib/simple-tree/core/getOrCreateNode.d.ts.map +1 -1
  279. package/lib/simple-tree/core/getOrCreateNode.js +2 -2
  280. package/lib/simple-tree/core/getOrCreateNode.js.map +1 -1
  281. package/lib/simple-tree/core/index.d.ts +1 -1
  282. package/lib/simple-tree/core/index.d.ts.map +1 -1
  283. package/lib/simple-tree/core/index.js +1 -1
  284. package/lib/simple-tree/core/index.js.map +1 -1
  285. package/lib/simple-tree/core/treeNodeKernel.d.ts +2 -6
  286. package/lib/simple-tree/core/treeNodeKernel.d.ts.map +1 -1
  287. package/lib/simple-tree/core/treeNodeKernel.js +9 -11
  288. package/lib/simple-tree/core/treeNodeKernel.js.map +1 -1
  289. package/lib/simple-tree/proxies.js +2 -2
  290. package/lib/simple-tree/proxies.js.map +1 -1
  291. package/lib/simple-tree/toMapTree.js +1 -1
  292. package/lib/simple-tree/toMapTree.js.map +1 -1
  293. package/lib/util/bTreeUtils.d.ts +10 -0
  294. package/lib/util/bTreeUtils.d.ts.map +1 -0
  295. package/lib/util/bTreeUtils.js +47 -0
  296. package/lib/util/bTreeUtils.js.map +1 -0
  297. package/lib/util/idAllocator.d.ts +0 -2
  298. package/lib/util/idAllocator.d.ts.map +1 -1
  299. package/lib/util/idAllocator.js +0 -2
  300. package/lib/util/idAllocator.js.map +1 -1
  301. package/lib/util/index.d.ts +2 -1
  302. package/lib/util/index.d.ts.map +1 -1
  303. package/lib/util/index.js +2 -1
  304. package/lib/util/index.js.map +1 -1
  305. package/lib/util/rangeMap.d.ts +61 -30
  306. package/lib/util/rangeMap.d.ts.map +1 -1
  307. package/lib/util/rangeMap.js +188 -117
  308. package/lib/util/rangeMap.js.map +1 -1
  309. package/lib/util/utils.d.ts +4 -1
  310. package/lib/util/utils.d.ts.map +1 -1
  311. package/lib/util/utils.js +7 -1
  312. package/lib/util/utils.js.map +1 -1
  313. package/package.json +25 -25
  314. package/src/core/index.ts +5 -2
  315. package/src/core/rebase/index.ts +5 -0
  316. package/src/core/rebase/types.ts +33 -5
  317. package/src/core/rebase/utils.ts +27 -0
  318. package/src/core/tree/delta.ts +21 -26
  319. package/src/core/tree/deltaUtil.ts +1 -16
  320. package/src/core/tree/index.ts +0 -2
  321. package/src/core/tree/visitDelta.ts +108 -97
  322. package/src/feature-libraries/default-schema/defaultFieldKinds.ts +2 -2
  323. package/src/feature-libraries/deltaUtils.ts +13 -0
  324. package/src/feature-libraries/forest-summary/forestSummarizer.ts +1 -6
  325. package/src/feature-libraries/modular-schema/crossFieldQueries.ts +12 -13
  326. package/src/feature-libraries/modular-schema/fieldChangeHandler.ts +21 -1
  327. package/src/feature-libraries/modular-schema/genericFieldKind.ts +2 -2
  328. package/src/feature-libraries/modular-schema/index.ts +2 -0
  329. package/src/feature-libraries/modular-schema/modularChangeCodecs.ts +12 -11
  330. package/src/feature-libraries/modular-schema/modularChangeFamily.ts +138 -225
  331. package/src/feature-libraries/modular-schema/modularChangeTypes.ts +40 -27
  332. package/src/feature-libraries/optional-field/optionalField.ts +3 -3
  333. package/src/feature-libraries/sequence-field/moveEffectTable.ts +1 -1
  334. package/src/feature-libraries/sequence-field/rebase.ts +9 -3
  335. package/src/feature-libraries/sequence-field/sequenceFieldCodecV1.ts +1 -1
  336. package/src/feature-libraries/sequence-field/sequenceFieldCodecV2.ts +1 -1
  337. package/src/feature-libraries/sequence-field/sequenceFieldToDelta.ts +3 -4
  338. package/src/feature-libraries/sequence-field/utils.ts +36 -4
  339. package/src/feature-libraries/treeCursorUtils.ts +10 -3
  340. package/src/index.ts +36 -6
  341. package/src/packageVersion.ts +1 -1
  342. package/src/shared-tree/index.ts +9 -1
  343. package/src/shared-tree/publicContracts.ts +24 -0
  344. package/src/shared-tree/sharedTree.ts +63 -46
  345. package/src/shared-tree/treeCheckout.ts +19 -12
  346. package/src/simple-tree/api/schemaFactory.ts +2 -0
  347. package/src/simple-tree/api/tree.ts +4 -0
  348. package/src/simple-tree/api/treeNodeApi.ts +1 -1
  349. package/src/simple-tree/arrayNode.ts +1 -1
  350. package/src/simple-tree/core/getOrCreateNode.ts +6 -2
  351. package/src/simple-tree/core/index.ts +1 -1
  352. package/src/simple-tree/core/treeNodeKernel.ts +16 -14
  353. package/src/simple-tree/proxies.ts +2 -2
  354. package/src/simple-tree/toMapTree.ts +1 -1
  355. package/src/util/bTreeUtils.ts +60 -0
  356. package/src/util/idAllocator.ts +0 -2
  357. package/src/util/index.ts +3 -0
  358. package/src/util/rangeMap.ts +237 -143
  359. package/src/util/utils.ts +10 -3
  360. package/lib/package.json +0 -3
@@ -5,7 +5,7 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.count = exports.find = exports.compareStrings = exports.transformObjectMap = exports.assertValidRangeIndices = exports.capitalize = exports.disposeSymbol = exports.compareNamed = exports.oneFromSet = exports.invertMap = exports.objectToMap = exports.assertNonNegativeSafeInteger = exports.assertValidRange = exports.assertValidIndex = exports.filterIterable = exports.mapIterable = exports.makeArray = exports.JsonCompatibleReadOnlySchema = exports.isReadonlyArray = exports.isJsonObject = exports.getOrCreate = exports.getOrAddEmptyToMap = exports.fail = exports.compareSets = exports.clone = exports.asMutable = exports.StackyIterator = exports.OffsetListFactory = exports.nestedSetContains = exports.addToNestedSet = exports.nestedMapFromFlatList = exports.nestedMapToFlatList = exports.mapNestedMap = exports.tryGetFromNestedMap = exports.tryAddToNestedMap = exports.setInNestedMap = exports.populateNestedMap = exports.SizedNestedMap = exports.forEachInNestedMap = exports.getOrDefaultInNestedMap = exports.getOrAddInNestedMap = exports.getOrAddInMapLazy = exports.getOrAddInMap = exports.deleteFromNestedMap = exports.extractFromOpaque = exports.brandOpaque = exports.brandedStringType = exports.brandedNumberType = exports.BrandedType = exports.brand = void 0;
8
- exports.breakingClass = exports.throwIfBroken = exports.breakingMethod = exports.Breakable = exports.fakeIdAllocator = exports.idAllocatorFromState = exports.idAllocatorFromMaxId = exports.RangeMap = exports.brandedSlot = exports.getOrCreateSlotContent = exports.unsafeArrayToTuple = exports.ReferenceCountedBase = exports.copyProperty = exports.defineLazyCachedProperty = exports.hasSingle = exports.hasSome = exports.getLast = void 0;
8
+ exports.mergeTupleBTrees = exports.newTupleBTree = exports.breakingClass = exports.throwIfBroken = exports.breakingMethod = exports.Breakable = exports.fakeIdAllocator = exports.idAllocatorFromState = exports.idAllocatorFromMaxId = exports.newIntegerRangeMap = exports.RangeMap = exports.brandedSlot = exports.getOrCreateSlotContent = exports.unsafeArrayToTuple = exports.ReferenceCountedBase = exports.copyProperty = exports.defineLazyCachedProperty = exports.hasSingle = exports.hasSome = exports.getLast = void 0;
9
9
  var brand_js_1 = require("./brand.js");
10
10
  Object.defineProperty(exports, "brand", { enumerable: true, get: function () { return brand_js_1.brand; } });
11
11
  Object.defineProperty(exports, "BrandedType", { enumerable: true, get: function () { return brand_js_1.BrandedType; } });
@@ -78,6 +78,7 @@ Object.defineProperty(exports, "getOrCreateSlotContent", { enumerable: true, get
78
78
  Object.defineProperty(exports, "brandedSlot", { enumerable: true, get: function () { return brandedMap_js_1.brandedSlot; } });
79
79
  var rangeMap_js_1 = require("./rangeMap.js");
80
80
  Object.defineProperty(exports, "RangeMap", { enumerable: true, get: function () { return rangeMap_js_1.RangeMap; } });
81
+ Object.defineProperty(exports, "newIntegerRangeMap", { enumerable: true, get: function () { return rangeMap_js_1.newIntegerRangeMap; } });
81
82
  var idAllocator_js_1 = require("./idAllocator.js");
82
83
  Object.defineProperty(exports, "idAllocatorFromMaxId", { enumerable: true, get: function () { return idAllocator_js_1.idAllocatorFromMaxId; } });
83
84
  Object.defineProperty(exports, "idAllocatorFromState", { enumerable: true, get: function () { return idAllocator_js_1.idAllocatorFromState; } });
@@ -87,4 +88,7 @@ Object.defineProperty(exports, "Breakable", { enumerable: true, get: function ()
87
88
  Object.defineProperty(exports, "breakingMethod", { enumerable: true, get: function () { return breakable_js_1.breakingMethod; } });
88
89
  Object.defineProperty(exports, "throwIfBroken", { enumerable: true, get: function () { return breakable_js_1.throwIfBroken; } });
89
90
  Object.defineProperty(exports, "breakingClass", { enumerable: true, get: function () { return breakable_js_1.breakingClass; } });
91
+ var bTreeUtils_js_1 = require("./bTreeUtils.js");
92
+ Object.defineProperty(exports, "newTupleBTree", { enumerable: true, get: function () { return bTreeUtils_js_1.newTupleBTree; } });
93
+ Object.defineProperty(exports, "mergeTupleBTrees", { enumerable: true, get: function () { return bTreeUtils_js_1.mergeTupleBTrees; } });
90
94
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/util/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;AAEH,uCAMoB;AALnB,iGAAA,KAAK,OAAA;AAEL,uGAAA,WAAW,OAAA;AAIZ,qDAAyE;AAAhE,oHAAA,iBAAiB,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAC7C,yCAKqB;AAJpB,wGAAA,WAAW,OAAA;AACX,8GAAA,iBAAiB,OAAA;AAIlB,+CAiBwB;AAhBvB,mHAAA,mBAAmB,OAAA;AACnB,6GAAA,aAAa,OAAA;AACb,iHAAA,iBAAiB,OAAA;AACjB,mHAAA,mBAAmB,OAAA;AACnB,uHAAA,uBAAuB,OAAA;AACvB,kHAAA,kBAAkB,OAAA;AAGlB,8GAAA,cAAc,OAAA;AACd,iHAAA,iBAAiB,OAAA;AACjB,8GAAA,cAAc,OAAA;AACd,iHAAA,iBAAiB,OAAA;AACjB,mHAAA,mBAAmB,OAAA;AACnB,4GAAA,YAAY,OAAA;AACZ,mHAAA,mBAAmB,OAAA;AACnB,qHAAA,qBAAqB,OAAA;AAEtB,+CAAmF;AAA1E,8GAAA,cAAc,OAAA;AAAkB,iHAAA,iBAAiB,OAAA;AAC1D,iDAAqE;AAA3C,kHAAA,iBAAiB,OAAA;AAiB3C,yDAAqD;AAA5C,mHAAA,cAAc,OAAA;AACvB,uCAyCoB;AAxCnB,qGAAA,SAAS,OAAA;AACT,iGAAA,KAAK,OAAA;AACL,uGAAA,WAAW,OAAA;AACX,gGAAA,IAAI,OAAA;AACJ,8GAAA,kBAAkB,OAAA;AAClB,uGAAA,WAAW,OAAA;AACX,wGAAA,YAAY,OAAA;AACZ,2GAAA,eAAe,OAAA;AAKf,wHAAA,4BAA4B,OAAA;AAC5B,qGAAA,SAAS,OAAA;AACT,uGAAA,WAAW,OAAA;AACX,0GAAA,cAAc,OAAA;AAId,4GAAA,gBAAgB,OAAA;AAChB,4GAAA,gBAAgB,OAAA;AAChB,wHAAA,4BAA4B,OAAA;AAC5B,uGAAA,WAAW,OAAA;AACX,qGAAA,SAAS,OAAA;AACT,sGAAA,UAAU,OAAA;AAEV,wGAAA,YAAY,OAAA;AACZ,yGAAA,aAAa,OAAA;AAEb,sGAAA,UAAU,OAAA;AACV,mHAAA,uBAAuB,OAAA;AACvB,8GAAA,kBAAkB,OAAA;AAClB,0GAAA,cAAc,OAAA;AACd,gGAAA,IAAI,OAAA;AACJ,iGAAA,KAAK,OAAA;AACL,mGAAA,OAAO,OAAA;AACP,mGAAA,OAAO,OAAA;AACP,qGAAA,SAAS,OAAA;AACT,oHAAA,wBAAwB,OAAA;AACxB,wGAAA,qBAAqB,OAAgB;AAEtC,+DAAqF;AAA5E,4HAAA,oBAAoB,OAAA;AAc7B,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAE3B,iDAMyB;AAFxB,uHAAA,sBAAsB,OAAA;AACtB,4GAAA,WAAW,OAAA;AAGZ,6CAGuB;AAFtB,uGAAA,QAAQ,OAAA;AAIT,mDAM0B;AAJzB,sHAAA,oBAAoB,OAAA;AACpB,sHAAA,oBAAoB,OAAA;AAEpB,iHAAA,eAAe,OAAA;AAGhB,+CAMwB;AALvB,yGAAA,SAAS,OAAA;AAET,8GAAA,cAAc,OAAA;AACd,6GAAA,aAAa,OAAA;AACb,6GAAA,aAAa,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tbrand,\n\ttype Brand,\n\tBrandedType,\n\ttype NameFromBranded,\n\ttype ValueFromBranded,\n} from \"./brand.js\";\nexport { brandedNumberType, brandedStringType } from \"./typeboxBrand.js\";\nexport {\n\tbrandOpaque,\n\textractFromOpaque,\n\ttype ExtractFromOpaque,\n\ttype Opaque,\n} from \"./opaque.js\";\nexport {\n\tdeleteFromNestedMap,\n\tgetOrAddInMap,\n\tgetOrAddInMapLazy,\n\tgetOrAddInNestedMap,\n\tgetOrDefaultInNestedMap,\n\tforEachInNestedMap,\n\ttype NestedMap,\n\ttype ReadonlyNestedMap,\n\tSizedNestedMap,\n\tpopulateNestedMap,\n\tsetInNestedMap,\n\ttryAddToNestedMap,\n\ttryGetFromNestedMap,\n\tmapNestedMap,\n\tnestedMapToFlatList,\n\tnestedMapFromFlatList,\n} from \"./nestedMap.js\";\nexport { addToNestedSet, type NestedSet, nestedSetContains } from \"./nestedSet.js\";\nexport { type OffsetList, OffsetListFactory } from \"./offsetList.js\";\nexport type {\n\tareSafelyAssignable,\n\tContravariant,\n\tCovariant,\n\teitherIsAny,\n\tEnforceTypeCheckTests,\n\tInvariant,\n\tisAny,\n\tisAssignableTo,\n\tisStrictSubset,\n\tMakeNominal,\n\trequireFalse,\n\trequireTrue,\n\trequireAssignableTo,\n\tareOnlyKeys,\n} from \"./typeCheck.js\";\nexport { StackyIterator } from \"./stackyIterator.js\";\nexport {\n\tasMutable,\n\tclone,\n\tcompareSets,\n\tfail,\n\tgetOrAddEmptyToMap,\n\tgetOrCreate,\n\tisJsonObject,\n\tisReadonlyArray,\n\ttype JsonCompatible,\n\ttype JsonCompatibleObject,\n\ttype JsonCompatibleReadOnly,\n\ttype JsonCompatibleReadOnlyObject,\n\tJsonCompatibleReadOnlySchema,\n\tmakeArray,\n\tmapIterable,\n\tfilterIterable,\n\ttype Mutable,\n\ttype Populated,\n\ttype RecursiveReadonly,\n\tassertValidIndex,\n\tassertValidRange,\n\tassertNonNegativeSafeInteger,\n\tobjectToMap,\n\tinvertMap,\n\toneFromSet,\n\ttype Named,\n\tcompareNamed,\n\tdisposeSymbol,\n\ttype IDisposable,\n\tcapitalize,\n\tassertValidRangeIndices,\n\ttransformObjectMap,\n\tcompareStrings,\n\tfind,\n\tcount,\n\tgetLast,\n\thasSome,\n\thasSingle,\n\tdefineLazyCachedProperty,\n\tcopyPropertyIfDefined as copyProperty,\n} from \"./utils.js\";\nexport { ReferenceCountedBase, type ReferenceCounted } from \"./referenceCounting.js\";\n\nexport type {\n\t_RecursiveTrick,\n\tRestrictiveReadonlyRecord,\n\tRestrictiveStringRecord,\n\t_InlineTrick,\n\tFlattenKeys,\n\tIsUnion,\n\tUnionToIntersection,\n\tUnionToTuple,\n\tPopUnion,\n} from \"./typeUtils.js\";\n\nexport { unsafeArrayToTuple } from \"./typeUtils.js\";\n\nexport {\n\ttype BrandedKey,\n\ttype BrandedKeyContent,\n\ttype BrandedMapSubset,\n\tgetOrCreateSlotContent,\n\tbrandedSlot,\n} from \"./brandedMap.js\";\n\nexport {\n\tRangeMap,\n\ttype RangeQueryResult,\n} from \"./rangeMap.js\";\n\nexport {\n\ttype IdAllocator,\n\tidAllocatorFromMaxId,\n\tidAllocatorFromState,\n\ttype IdAllocationState,\n\tfakeIdAllocator,\n} from \"./idAllocator.js\";\n\nexport {\n\tBreakable,\n\ttype WithBreakable,\n\tbreakingMethod,\n\tthrowIfBroken,\n\tbreakingClass,\n} from \"./breakable.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/util/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;AAEH,uCAMoB;AALnB,iGAAA,KAAK,OAAA;AAEL,uGAAA,WAAW,OAAA;AAIZ,qDAAyE;AAAhE,oHAAA,iBAAiB,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAC7C,yCAKqB;AAJpB,wGAAA,WAAW,OAAA;AACX,8GAAA,iBAAiB,OAAA;AAIlB,+CAiBwB;AAhBvB,mHAAA,mBAAmB,OAAA;AACnB,6GAAA,aAAa,OAAA;AACb,iHAAA,iBAAiB,OAAA;AACjB,mHAAA,mBAAmB,OAAA;AACnB,uHAAA,uBAAuB,OAAA;AACvB,kHAAA,kBAAkB,OAAA;AAGlB,8GAAA,cAAc,OAAA;AACd,iHAAA,iBAAiB,OAAA;AACjB,8GAAA,cAAc,OAAA;AACd,iHAAA,iBAAiB,OAAA;AACjB,mHAAA,mBAAmB,OAAA;AACnB,4GAAA,YAAY,OAAA;AACZ,mHAAA,mBAAmB,OAAA;AACnB,qHAAA,qBAAqB,OAAA;AAEtB,+CAAmF;AAA1E,8GAAA,cAAc,OAAA;AAAkB,iHAAA,iBAAiB,OAAA;AAC1D,iDAAqE;AAA3C,kHAAA,iBAAiB,OAAA;AAiB3C,yDAAqD;AAA5C,mHAAA,cAAc,OAAA;AACvB,uCAyCoB;AAxCnB,qGAAA,SAAS,OAAA;AACT,iGAAA,KAAK,OAAA;AACL,uGAAA,WAAW,OAAA;AACX,gGAAA,IAAI,OAAA;AACJ,8GAAA,kBAAkB,OAAA;AAClB,uGAAA,WAAW,OAAA;AACX,wGAAA,YAAY,OAAA;AACZ,2GAAA,eAAe,OAAA;AAKf,wHAAA,4BAA4B,OAAA;AAC5B,qGAAA,SAAS,OAAA;AACT,uGAAA,WAAW,OAAA;AACX,0GAAA,cAAc,OAAA;AAId,4GAAA,gBAAgB,OAAA;AAChB,4GAAA,gBAAgB,OAAA;AAChB,wHAAA,4BAA4B,OAAA;AAC5B,uGAAA,WAAW,OAAA;AACX,qGAAA,SAAS,OAAA;AACT,sGAAA,UAAU,OAAA;AAEV,wGAAA,YAAY,OAAA;AACZ,yGAAA,aAAa,OAAA;AAEb,sGAAA,UAAU,OAAA;AACV,mHAAA,uBAAuB,OAAA;AACvB,8GAAA,kBAAkB,OAAA;AAClB,0GAAA,cAAc,OAAA;AACd,gGAAA,IAAI,OAAA;AACJ,iGAAA,KAAK,OAAA;AACL,mGAAA,OAAO,OAAA;AACP,mGAAA,OAAO,OAAA;AACP,qGAAA,SAAS,OAAA;AACT,oHAAA,wBAAwB,OAAA;AACxB,wGAAA,qBAAqB,OAAgB;AAEtC,+DAAqF;AAA5E,4HAAA,oBAAoB,OAAA;AAc7B,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAE3B,iDAMyB;AAFxB,uHAAA,sBAAsB,OAAA;AACtB,4GAAA,WAAW,OAAA;AAGZ,6CAIuB;AAHtB,uGAAA,QAAQ,OAAA;AAER,iHAAA,kBAAkB,OAAA;AAGnB,mDAM0B;AAJzB,sHAAA,oBAAoB,OAAA;AACpB,sHAAA,oBAAoB,OAAA;AAEpB,iHAAA,eAAe,OAAA;AAGhB,+CAMwB;AALvB,yGAAA,SAAS,OAAA;AAET,8GAAA,cAAc,OAAA;AACd,6GAAA,aAAa,OAAA;AACb,6GAAA,aAAa,OAAA;AAGd,iDAAmF;AAAzD,8GAAA,aAAa,OAAA;AAAE,iHAAA,gBAAgB,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tbrand,\n\ttype Brand,\n\tBrandedType,\n\ttype NameFromBranded,\n\ttype ValueFromBranded,\n} from \"./brand.js\";\nexport { brandedNumberType, brandedStringType } from \"./typeboxBrand.js\";\nexport {\n\tbrandOpaque,\n\textractFromOpaque,\n\ttype ExtractFromOpaque,\n\ttype Opaque,\n} from \"./opaque.js\";\nexport {\n\tdeleteFromNestedMap,\n\tgetOrAddInMap,\n\tgetOrAddInMapLazy,\n\tgetOrAddInNestedMap,\n\tgetOrDefaultInNestedMap,\n\tforEachInNestedMap,\n\ttype NestedMap,\n\ttype ReadonlyNestedMap,\n\tSizedNestedMap,\n\tpopulateNestedMap,\n\tsetInNestedMap,\n\ttryAddToNestedMap,\n\ttryGetFromNestedMap,\n\tmapNestedMap,\n\tnestedMapToFlatList,\n\tnestedMapFromFlatList,\n} from \"./nestedMap.js\";\nexport { addToNestedSet, type NestedSet, nestedSetContains } from \"./nestedSet.js\";\nexport { type OffsetList, OffsetListFactory } from \"./offsetList.js\";\nexport type {\n\tareSafelyAssignable,\n\tContravariant,\n\tCovariant,\n\teitherIsAny,\n\tEnforceTypeCheckTests,\n\tInvariant,\n\tisAny,\n\tisAssignableTo,\n\tisStrictSubset,\n\tMakeNominal,\n\trequireFalse,\n\trequireTrue,\n\trequireAssignableTo,\n\tareOnlyKeys,\n} from \"./typeCheck.js\";\nexport { StackyIterator } from \"./stackyIterator.js\";\nexport {\n\tasMutable,\n\tclone,\n\tcompareSets,\n\tfail,\n\tgetOrAddEmptyToMap,\n\tgetOrCreate,\n\tisJsonObject,\n\tisReadonlyArray,\n\ttype JsonCompatible,\n\ttype JsonCompatibleObject,\n\ttype JsonCompatibleReadOnly,\n\ttype JsonCompatibleReadOnlyObject,\n\tJsonCompatibleReadOnlySchema,\n\tmakeArray,\n\tmapIterable,\n\tfilterIterable,\n\ttype Mutable,\n\ttype Populated,\n\ttype RecursiveReadonly,\n\tassertValidIndex,\n\tassertValidRange,\n\tassertNonNegativeSafeInteger,\n\tobjectToMap,\n\tinvertMap,\n\toneFromSet,\n\ttype Named,\n\tcompareNamed,\n\tdisposeSymbol,\n\ttype IDisposable,\n\tcapitalize,\n\tassertValidRangeIndices,\n\ttransformObjectMap,\n\tcompareStrings,\n\tfind,\n\tcount,\n\tgetLast,\n\thasSome,\n\thasSingle,\n\tdefineLazyCachedProperty,\n\tcopyPropertyIfDefined as copyProperty,\n} from \"./utils.js\";\nexport { ReferenceCountedBase, type ReferenceCounted } from \"./referenceCounting.js\";\n\nexport type {\n\t_RecursiveTrick,\n\tRestrictiveReadonlyRecord,\n\tRestrictiveStringRecord,\n\t_InlineTrick,\n\tFlattenKeys,\n\tIsUnion,\n\tUnionToIntersection,\n\tUnionToTuple,\n\tPopUnion,\n} from \"./typeUtils.js\";\n\nexport { unsafeArrayToTuple } from \"./typeUtils.js\";\n\nexport {\n\ttype BrandedKey,\n\ttype BrandedKeyContent,\n\ttype BrandedMapSubset,\n\tgetOrCreateSlotContent,\n\tbrandedSlot,\n} from \"./brandedMap.js\";\n\nexport {\n\tRangeMap,\n\ttype RangeQueryResult,\n\tnewIntegerRangeMap,\n} from \"./rangeMap.js\";\n\nexport {\n\ttype IdAllocator,\n\tidAllocatorFromMaxId,\n\tidAllocatorFromState,\n\ttype IdAllocationState,\n\tfakeIdAllocator,\n} from \"./idAllocator.js\";\n\nexport {\n\tBreakable,\n\ttype WithBreakable,\n\tbreakingMethod,\n\tthrowIfBroken,\n\tbreakingClass,\n} from \"./breakable.js\";\n\nexport { type TupleBTree, newTupleBTree, mergeTupleBTrees } from \"./bTreeUtils.js\";\n"]}
@@ -3,26 +3,58 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  /**
6
- * RangeMap represents a mapping from integers to values of type T or undefined.
6
+ * RangeMap represents a mapping from keys of type K to values of type V or undefined.
7
+ * The set of all possible keys is assumed to be fully ordered,
8
+ * and for each key there should be a single next higher key.
7
9
  * The values for a range of consecutive keys can be changed or queried in a single operation.
10
+ * The structure of the keys is described by the `offsetKey` and `subtractKeys` functions provided in the constructor.
8
11
  */
9
- export declare class RangeMap<T> {
10
- private readonly entries;
11
- constructor(initialEntries?: RangeEntry<T>[]);
12
+ export declare class RangeMap<K, V> {
13
+ private readonly offsetKey;
14
+ private readonly subtractKeys;
15
+ readonly offsetValue: (value: V, offset: number) => V;
16
+ private tree;
12
17
  /**
13
- * Retrieves all entries from the rangeMap.
14
- * @returns An array of RangeEntryResult objects, each containing the start index, length, and value of a contiguous range.
18
+ * @param offsetKey - Function which returns a new key which is `offset` keys after `key`.
19
+ * When `offset` is negative, the returned key should come before `key`.
20
+ *
21
+ * @param subtractKeys - Function which returns the difference between `b` and `a`.
22
+ * Offsetting `b` by this difference should return `a`.
23
+ * The difference can be infinite if `a` cannot be reached from `b` by offsetting,
24
+ * but the difference should still be positive if `a` is larger than `b` and negative if smaller.
25
+ *
26
+ * @param offsetValue - Function used to associate a range of values with a range of keys.
27
+ * When writing to a range of keys starting with `start`, the value of the nth key is interpreted to be
28
+ * `offsetValue(firstValue, n - 1)`.
29
+ * The same logic should be used when interpreting the values for keys after the first in a
30
+ * `RangeQueryResult` or `RangeQueryEntry`.
31
+ *
32
+ * If `offsetValue` is left unspecified, all keys in a block will be given the same value.
33
+ */
34
+ constructor(offsetKey: (key: K, offset: number) => K, subtractKeys: (a: K, b: K) => number, offsetValue?: (value: V, offset: number) => V);
35
+ /**
36
+ * Retrieves all entries from the RangeMap.
15
37
  */
16
- getAllEntries(): readonly RangeQueryResult<T>[];
38
+ entries(): RangeQueryEntry<K, V>[];
39
+ clear(): void;
40
+ /**
41
+ * Retrieves the values for all keys in the query range.
42
+ *
43
+ * @param start - The first key in the range being queried
44
+ * @param length - The length of the query range
45
+ * @returns A list of entries, each describing the value for some subrange of the query.
46
+ * The entries are in the same order as the keys, and there is an entry for every key with a non `undefined` value.
47
+ */
48
+ getAll(start: K, length: number): RangeQueryEntry<K, V>[];
17
49
  /**
18
50
  * Retrieves the value for some prefix of the query range.
19
51
  *
20
52
  * @param start - The first key in the query range.
21
53
  * @param length - The length of the query range.
22
54
  * @returns A RangeQueryResult containing the value associated with `start`,
23
- * and the number of consecutive keys with that same value.
55
+ * and the number of consecutive keys with that same value (at least 1, at most `length`).
24
56
  */
25
- get(start: number, length: number): RangeQueryResult<T>;
57
+ getFirst(start: K, length: number): RangeQueryResult<K, V>;
26
58
  /**
27
59
  * Sets the value for a specified range.
28
60
  *
@@ -30,7 +62,7 @@ export declare class RangeMap<T> {
30
62
  * @param length - The length of the range.
31
63
  * @param value - The value to associate with the range.
32
64
  */
33
- set(start: number, length: number, value: T | undefined): void;
65
+ set(start: K, length: number, value: V | undefined): void;
34
66
  /**
35
67
  * Deletes values within a specified range, updating or removing existing entries.
36
68
  *
@@ -51,35 +83,31 @@ export declare class RangeMap<T> {
51
83
  * @param start - The start of the range to delete (inclusive).
52
84
  * @param length - The length of the range to delete.
53
85
  */
54
- delete(start: number, length: number): void;
55
- }
56
- /**
57
- * Represents a contiguous range of values in the RangeMap.
58
- * This interface is used internally and should not be exposed to consumers.
59
- */
60
- interface RangeEntry<T> {
61
- /**
62
- * The starting index of the range (inclusive).
63
- */
64
- readonly start: number;
86
+ delete(start: K, length: number): void;
87
+ clone(): RangeMap<K, V>;
65
88
  /**
66
- * The length of the range.
89
+ * Returns a new map which contains the entries from both input maps.
67
90
  */
68
- readonly length: number;
69
- /**
70
- * The value associated with this range.
71
- */
72
- readonly value: T;
91
+ static union<K, V>(a: RangeMap<K, V>, b: RangeMap<K, V>): RangeMap<K, V>;
92
+ private getIntersectingEntries;
93
+ private gt;
94
+ private ge;
95
+ private lt;
96
+ private le;
73
97
  }
74
98
  /**
75
99
  * Describes the result of a range query, including the value and length of the matching prefix.
76
100
  */
77
- export interface RangeQueryResult<T> {
101
+ export interface RangeQueryResult<K, V> {
102
+ /**
103
+ * The key for the first element in the range.
104
+ */
105
+ readonly start: K;
78
106
  /**
79
107
  * The value of the first key in the query range.
80
108
  * If no matching range is found, this will be undefined.
81
109
  */
82
- readonly value: T | undefined;
110
+ readonly value: V | undefined;
83
111
  /**
84
112
  * The length of the prefix of the query range which has the same value.
85
113
  * For example, if a RangeMap has the same value for keys 5, 6, and 7,
@@ -87,5 +115,8 @@ export interface RangeQueryResult<T> {
87
115
  */
88
116
  readonly length: number;
89
117
  }
90
- export {};
118
+ export interface RangeQueryEntry<K, V> extends RangeQueryResult<K, V> {
119
+ readonly value: V;
120
+ }
121
+ export declare function newIntegerRangeMap<V>(): RangeMap<number, V>;
91
122
  //# sourceMappingURL=rangeMap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rangeMap.d.ts","sourceRoot":"","sources":["../../src/util/rangeMap.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;GAGG;AACH,qBAAa,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAEvB,cAAc,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE;IAInD;;;OAGG;IACI,aAAa,IAAI,SAAS,gBAAgB,CAAC,CAAC,CAAC,EAAE;IAItD;;;;;;;OAOG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC;IAiB9D;;;;;;OAMG;IACI,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,IAAI;IAsErE;;;;;;;;;;;;;;;;;;;OAmBG;IACI,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;CAwDlD;AAED;;;GAGG;AACH,UAAU,UAAU,CAAC,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;IAE9B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB"}
1
+ {"version":3,"file":"rangeMap.d.ts","sourceRoot":"","sources":["../../src/util/rangeMap.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH;;;;;;GAMG;AACH,qBAAa,QAAQ,CAAC,CAAC,EAAE,CAAC;IAqBxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY;aACb,WAAW,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;IAtB7D,OAAO,CAAC,IAAI,CAA0B;IAEtC;;;;;;;;;;;;;;;;OAgBG;gBAEe,SAAS,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,EACxC,YAAY,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,EACrC,WAAW,GAAE,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,KAAK,CAAwB;IAKpF;;OAEG;IACI,OAAO,IAAI,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;IASlC,KAAK,IAAI,IAAI;IAIpB;;;;;;;OAOG;IACI,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;IA2BhE;;;;;;;OAOG;IACI,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC;IAsCjE;;;;;;OAMG;IACI,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,SAAS,GAAG,IAAI;IAOhE;;;;;;;;;;;;;;;;;;;OAmBG;IACI,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IA2BtC,KAAK,IAAI,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IAM9B;;OAEG;WACW,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;IAoB/E,OAAO,CAAC,sBAAsB;IAkC9B,OAAO,CAAC,EAAE;IAIV,OAAO,CAAC,EAAE;IAIV,OAAO,CAAC,EAAE;IAIV,OAAO,CAAC,EAAE;CAGV;AAiBD;;GAEG;AACH,MAAM,WAAW,gBAAgB,CAAC,CAAC,EAAE,CAAC;IACrC;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;IAE9B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,EAAE,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC;IACpE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAE3D"}
@@ -4,22 +4,83 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.RangeMap = void 0;
7
+ exports.newIntegerRangeMap = exports.RangeMap = void 0;
8
8
  const internal_1 = require("@fluidframework/core-utils/internal");
9
+ const sorted_btree_es6_1 = require("@tylerbu/sorted-btree-es6");
9
10
  /**
10
- * RangeMap represents a mapping from integers to values of type T or undefined.
11
+ * RangeMap represents a mapping from keys of type K to values of type V or undefined.
12
+ * The set of all possible keys is assumed to be fully ordered,
13
+ * and for each key there should be a single next higher key.
11
14
  * The values for a range of consecutive keys can be changed or queried in a single operation.
15
+ * The structure of the keys is described by the `offsetKey` and `subtractKeys` functions provided in the constructor.
12
16
  */
13
17
  class RangeMap {
14
- constructor(initialEntries) {
15
- this.entries = initialEntries ? [...initialEntries] : [];
18
+ /**
19
+ * @param offsetKey - Function which returns a new key which is `offset` keys after `key`.
20
+ * When `offset` is negative, the returned key should come before `key`.
21
+ *
22
+ * @param subtractKeys - Function which returns the difference between `b` and `a`.
23
+ * Offsetting `b` by this difference should return `a`.
24
+ * The difference can be infinite if `a` cannot be reached from `b` by offsetting,
25
+ * but the difference should still be positive if `a` is larger than `b` and negative if smaller.
26
+ *
27
+ * @param offsetValue - Function used to associate a range of values with a range of keys.
28
+ * When writing to a range of keys starting with `start`, the value of the nth key is interpreted to be
29
+ * `offsetValue(firstValue, n - 1)`.
30
+ * The same logic should be used when interpreting the values for keys after the first in a
31
+ * `RangeQueryResult` or `RangeQueryEntry`.
32
+ *
33
+ * If `offsetValue` is left unspecified, all keys in a block will be given the same value.
34
+ */
35
+ constructor(offsetKey, subtractKeys, offsetValue = defaultValueOffsetFn) {
36
+ this.offsetKey = offsetKey;
37
+ this.subtractKeys = subtractKeys;
38
+ this.offsetValue = offsetValue;
39
+ this.tree = new sorted_btree_es6_1.BTree(undefined, subtractKeys);
16
40
  }
17
41
  /**
18
- * Retrieves all entries from the rangeMap.
19
- * @returns An array of RangeEntryResult objects, each containing the start index, length, and value of a contiguous range.
42
+ * Retrieves all entries from the RangeMap.
20
43
  */
21
- getAllEntries() {
22
- return this.entries;
44
+ entries() {
45
+ const entries = [];
46
+ for (const [start, entry] of this.tree.entries()) {
47
+ entries.push({ start, length: entry.length, value: entry.value });
48
+ }
49
+ return entries;
50
+ }
51
+ clear() {
52
+ this.tree.clear();
53
+ }
54
+ /**
55
+ * Retrieves the values for all keys in the query range.
56
+ *
57
+ * @param start - The first key in the range being queried
58
+ * @param length - The length of the query range
59
+ * @returns A list of entries, each describing the value for some subrange of the query.
60
+ * The entries are in the same order as the keys, and there is an entry for every key with a non `undefined` value.
61
+ */
62
+ getAll(start, length) {
63
+ const entries = this.getIntersectingEntries(start, length);
64
+ if (entries.length === 0) {
65
+ return entries;
66
+ }
67
+ const firstEntry = entries[0] ?? (0, internal_1.oob)();
68
+ const lengthBefore = this.subtractKeys(start, firstEntry.start);
69
+ if (lengthBefore > 0) {
70
+ entries[0] = {
71
+ start,
72
+ length: firstEntry.length - lengthBefore,
73
+ value: this.offsetValue(firstEntry.value, lengthBefore),
74
+ };
75
+ }
76
+ const lastEntry = entries[entries.length - 1] ?? (0, internal_1.oob)();
77
+ const lastEntryKey = this.offsetKey(lastEntry.start, lastEntry.length - 1);
78
+ const lastQueryKey = this.offsetKey(start, length - 1);
79
+ const lengthAfter = this.subtractKeys(lastEntryKey, lastQueryKey);
80
+ if (lengthAfter > 0) {
81
+ entries[entries.length - 1] = { ...lastEntry, length: lastEntry.length - lengthAfter };
82
+ }
83
+ return entries;
23
84
  }
24
85
  /**
25
86
  * Retrieves the value for some prefix of the query range.
@@ -27,21 +88,40 @@ class RangeMap {
27
88
  * @param start - The first key in the query range.
28
89
  * @param length - The length of the query range.
29
90
  * @returns A RangeQueryResult containing the value associated with `start`,
30
- * and the number of consecutive keys with that same value.
91
+ * and the number of consecutive keys with that same value (at least 1, at most `length`).
31
92
  */
32
- get(start, length) {
33
- for (const entry of this.entries) {
34
- if (entry.start > start) {
35
- return { value: undefined, length: Math.min(entry.start - start, length) };
93
+ getFirst(start, length) {
94
+ {
95
+ // We first check for an entry with a key less than or equal to `start`.
96
+ const entry = this.tree.getPairOrNextLower(start);
97
+ if (entry !== undefined) {
98
+ const entryKey = entry[0];
99
+ const { value, length: entryLength } = entry[1];
100
+ const entryLastKey = this.offsetKey(entryKey, entryLength - 1);
101
+ const lengthBeforeQuery = this.subtractKeys(start, entryKey);
102
+ const overlappingLength = Math.min(this.subtractKeys(entryLastKey, start) + 1, length);
103
+ if (overlappingLength > 0) {
104
+ return {
105
+ value: this.offsetValue(value, lengthBeforeQuery),
106
+ start,
107
+ length: overlappingLength,
108
+ };
109
+ }
36
110
  }
37
- const lastRangeKey = entry.start + entry.length - 1;
38
- if (lastRangeKey >= start) {
39
- const overlapLength = lastRangeKey - start + 1;
40
- return { value: entry.value, length: Math.min(overlapLength, length) };
111
+ }
112
+ {
113
+ // There is no value associated with `start`.
114
+ // Now we need to determine how many of the following keys are also undefined.
115
+ const key = this.tree.nextHigherKey(start);
116
+ if (key !== undefined) {
117
+ const entryKey = key;
118
+ const lastQueryKey = this.offsetKey(start, length - 1);
119
+ if (this.le(entryKey, lastQueryKey)) {
120
+ return { value: undefined, start, length: this.subtractKeys(entryKey, start) };
121
+ }
41
122
  }
123
+ return { value: undefined, start, length };
42
124
  }
43
- // There were no entries intersecting the query range, so the entire query range has undefined value.
44
- return { value: undefined, length };
45
125
  }
46
126
  /**
47
127
  * Sets the value for a specified range.
@@ -51,65 +131,10 @@ class RangeMap {
51
131
  * @param value - The value to associate with the range.
52
132
  */
53
133
  set(start, length, value) {
54
- if (value === undefined) {
55
- this.delete(start, length);
56
- return;
57
- }
58
- const end = start + length - 1;
59
- const newEntry = { start, length, value };
60
- let iBefore = -1;
61
- let iAfter = this.entries.length;
62
- for (const [i, entry] of this.entries.entries()) {
63
- const entryLastKey = entry.start + entry.length - 1;
64
- if (entryLastKey < start) {
65
- iBefore = i;
66
- }
67
- else if (entry.start > end) {
68
- iAfter = i;
69
- break;
70
- }
134
+ this.delete(start, length);
135
+ if (value !== undefined) {
136
+ this.tree.set(start, { value, length });
71
137
  }
72
- const numOverlappingEntries = iAfter - iBefore - 1;
73
- if (numOverlappingEntries === 0) {
74
- this.entries.splice(iAfter, 0, newEntry);
75
- return;
76
- }
77
- const iFirst = iBefore + 1;
78
- const firstEntry = this.entries[iFirst] ?? (0, internal_1.oob)();
79
- const iLast = iAfter - 1;
80
- const lastEntry = this.entries[iLast] ?? (0, internal_1.oob)();
81
- const lengthBeforeFirst = start - firstEntry.start;
82
- const lastEntryKey = lastEntry.start + lastEntry.length - 1;
83
- const lengthAfterLast = lastEntryKey - end;
84
- if (lengthBeforeFirst > 0 && lengthAfterLast > 0 && iFirst === iLast) {
85
- // The new entry fits in the middle of an existing entry.
86
- // We replace the existing entry with:
87
- // 1) the portion which comes before `newEntry`
88
- // 2) `newEntry`
89
- // 3) the portion which comes after `newEntry`
90
- this.entries.splice(iFirst, 1, { ...firstEntry, length: lengthBeforeFirst }, newEntry, {
91
- ...lastEntry,
92
- start: end + 1,
93
- length: lengthAfterLast,
94
- });
95
- return;
96
- }
97
- if (lengthBeforeFirst > 0) {
98
- this.entries[iFirst] = { ...firstEntry, length: lengthBeforeFirst };
99
- // The entry at `iFirst` is no longer overlapping with `newEntry`.
100
- iBefore = iFirst;
101
- }
102
- if (lengthAfterLast > 0) {
103
- this.entries[iLast] = {
104
- ...lastEntry,
105
- start: end + 1,
106
- length: lengthAfterLast,
107
- };
108
- // The entry at `iLast` is no longer overlapping with `newEntry`.
109
- iAfter = iLast;
110
- }
111
- const numContainedEntries = iAfter - iBefore - 1;
112
- this.entries.splice(iBefore + 1, numContainedEntries, newEntry);
113
138
  }
114
139
  /**
115
140
  * Deletes values within a specified range, updating or removing existing entries.
@@ -132,55 +157,102 @@ class RangeMap {
132
157
  * @param length - The length of the range to delete.
133
158
  */
134
159
  delete(start, length) {
135
- const end = start + length - 1;
136
- let iBefore = -1;
137
- let iAfter = this.entries.length;
138
- for (const [i, entry] of this.entries.entries()) {
139
- const entryLastKey = entry.start + entry.length - 1;
140
- if (entryLastKey < start) {
141
- iBefore = i;
160
+ const lastDeleteKey = this.offsetKey(start, length - 1);
161
+ for (const { start: key, length: entryLength, value } of this.getIntersectingEntries(start, length)) {
162
+ this.tree.delete(key);
163
+ const lengthBefore = this.subtractKeys(start, key);
164
+ if (lengthBefore > 0) {
165
+ // A portion of this entry comes before the deletion range, so we reinsert that portion.
166
+ this.tree.set(key, { length: lengthBefore, value });
142
167
  }
143
- else if (entry.start > end) {
144
- iAfter = i;
145
- break;
168
+ const lastEntryKey = this.offsetKey(key, entryLength - 1);
169
+ const lengthAfter = this.subtractKeys(lastEntryKey, lastDeleteKey);
170
+ if (lengthAfter > 0) {
171
+ // A portion of this entry comes after the deletion range, so we reinsert that portion.
172
+ const newKey = this.offsetKey(lastDeleteKey, 1);
173
+ const difference = this.subtractKeys(newKey, key);
174
+ this.tree.set(newKey, {
175
+ length: lengthAfter,
176
+ value: this.offsetValue(value, difference),
177
+ });
146
178
  }
147
179
  }
148
- const numOverlappingEntries = iAfter - iBefore - 1;
149
- if (numOverlappingEntries === 0) {
150
- // No entry will be removed
151
- return;
180
+ }
181
+ clone() {
182
+ const cloned = new RangeMap(this.offsetKey, this.subtractKeys, this.offsetValue);
183
+ cloned.tree = this.tree.clone();
184
+ return cloned;
185
+ }
186
+ /**
187
+ * Returns a new map which contains the entries from both input maps.
188
+ */
189
+ static union(a, b) {
190
+ (0, internal_1.assert)(a.offsetKey === b.offsetKey &&
191
+ a.subtractKeys === b.subtractKeys &&
192
+ a.offsetValue === b.offsetValue, 0xaae /* Maps should have the same behavior */);
193
+ const merged = new RangeMap(a.offsetKey, a.subtractKeys, a.offsetValue);
194
+ // TODO: Is there a good pattern that lets us make `tree` readonly?
195
+ merged.tree = a.tree.clone();
196
+ for (const [key, value] of b.tree.entries()) {
197
+ // TODO: Handle key collisions
198
+ merged.tree.set(key, value);
152
199
  }
153
- const iFirst = iBefore + 1;
154
- const iLast = iAfter - 1;
155
- for (let i = iFirst; i <= iLast; ++i) {
156
- const entry = this.entries[i] ?? (0, internal_1.oob)();
157
- const entryLastKey = entry.start + entry.length - 1;
158
- let isDirty = false;
159
- if (entry.start >= start && entryLastKey <= end) {
160
- // If the entry lies within the range to be deleted, remove it
161
- this.entries.splice(i, 1);
162
- }
163
- else {
164
- // If the entry partially or completely overlaps with the range to be deleted
165
- if (entry.start < start) {
166
- // Update the endpoint and length of the portion before the range to be deleted
167
- const lengthBefore = start - entry.start;
168
- this.entries[i] = { ...entry, length: lengthBefore };
169
- isDirty = true;
200
+ return merged;
201
+ }
202
+ getIntersectingEntries(start, length) {
203
+ const entries = [];
204
+ const lastQueryKey = this.offsetKey(start, length - 1);
205
+ {
206
+ const entry = this.tree.getPairOrNextLower(start);
207
+ if (entry !== undefined) {
208
+ const key = entry[0];
209
+ const { length: entryLength, value } = entry[1];
210
+ const lastEntryKey = this.offsetKey(key, entryLength - 1);
211
+ if (this.ge(lastEntryKey, start)) {
212
+ entries.push({ start: key, length: entryLength, value });
170
213
  }
171
- if (entryLastKey > end) {
172
- // Update the startpoint and length of the portion after the range to be deleted
173
- const newStart = end + 1;
174
- const newLength = entryLastKey - end;
175
- this.entries.splice(isDirty ? i + 1 : i, isDirty ? 0 : 1, {
176
- start: newStart,
177
- length: newLength,
178
- value: entry.value,
179
- });
214
+ }
215
+ }
216
+ {
217
+ let entry = this.tree.nextHigherPair(start);
218
+ while (entry !== undefined) {
219
+ const key = entry[0];
220
+ if (this.gt(key, lastQueryKey)) {
221
+ break;
180
222
  }
223
+ const { length: entryLength, value } = entry[1];
224
+ const lastEntryKey = this.offsetKey(key, entryLength - 1);
225
+ entries.push({ start: key, length: entryLength, value });
226
+ entry = this.tree.nextHigherPair(lastEntryKey);
181
227
  }
182
228
  }
229
+ return entries;
230
+ }
231
+ gt(a, b) {
232
+ return this.subtractKeys(a, b) > 0;
233
+ }
234
+ ge(a, b) {
235
+ return this.subtractKeys(a, b) >= 0;
236
+ }
237
+ lt(a, b) {
238
+ return this.subtractKeys(a, b) < 0;
239
+ }
240
+ le(a, b) {
241
+ return this.subtractKeys(a, b) <= 0;
183
242
  }
184
243
  }
185
244
  exports.RangeMap = RangeMap;
245
+ function newIntegerRangeMap() {
246
+ return new RangeMap(offsetInteger, subtractIntegers);
247
+ }
248
+ exports.newIntegerRangeMap = newIntegerRangeMap;
249
+ function offsetInteger(key, offset) {
250
+ return key + offset;
251
+ }
252
+ function subtractIntegers(a, b) {
253
+ return a - b;
254
+ }
255
+ function defaultValueOffsetFn(value, offset) {
256
+ return value;
257
+ }
186
258
  //# sourceMappingURL=rangeMap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rangeMap.js","sourceRoot":"","sources":["../../src/util/rangeMap.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAA0D;AAE1D;;;GAGG;AACH,MAAa,QAAQ;IAGpB,YAAmB,cAAgC;QAClD,IAAI,CAAC,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1D,CAAC;IAED;;;OAGG;IACI,aAAa;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC;IACrB,CAAC;IAED;;;;;;;OAOG;IACI,GAAG,CAAC,KAAa,EAAE,MAAc;QACvC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC;gBACzB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;YAC5E,CAAC;YAED,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;gBAC3B,MAAM,aAAa,GAAG,YAAY,GAAG,KAAK,GAAG,CAAC,CAAC;gBAC/C,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC;YACxE,CAAC;QACF,CAAC;QAED,qGAAqG;QACrG,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACI,GAAG,CAAC,KAAa,EAAE,MAAc,EAAE,KAAoB;QAC7D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC3B,OAAO;QACR,CAAC;QAED,MAAM,GAAG,GAAG,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAEzD,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;QACjB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QACjC,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACjD,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,IAAI,YAAY,GAAG,KAAK,EAAE,CAAC;gBAC1B,OAAO,GAAG,CAAC,CAAC;YACb,CAAC;iBAAM,IAAI,KAAK,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC;gBAC9B,MAAM,GAAG,CAAC,CAAC;gBACX,MAAM;YACP,CAAC;QACF,CAAC;QAED,MAAM,qBAAqB,GAAG,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC;QACnD,IAAI,qBAAqB,KAAK,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YACzC,OAAO;QACR,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC;QAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAA,cAAG,GAAE,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAA,cAAG,GAAE,CAAC;QAC/C,MAAM,iBAAiB,GAAG,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC;QACnD,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5D,MAAM,eAAe,GAAG,YAAY,GAAG,GAAG,CAAC;QAE3C,IAAI,iBAAiB,GAAG,CAAC,IAAI,eAAe,GAAG,CAAC,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACtE,yDAAyD;YACzD,sCAAsC;YACtC,+CAA+C;YAC/C,gBAAgB;YAChB,8CAA8C;YAC9C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,QAAQ,EAAE;gBACtF,GAAG,SAAS;gBACZ,KAAK,EAAE,GAAG,GAAG,CAAC;gBACd,MAAM,EAAE,eAAe;aACvB,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;YACpE,kEAAkE;YAClE,OAAO,GAAG,MAAM,CAAC;QAClB,CAAC;QAED,IAAI,eAAe,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG;gBACrB,GAAG,SAAS;gBACZ,KAAK,EAAE,GAAG,GAAG,CAAC;gBACd,MAAM,EAAE,eAAe;aACvB,CAAC;YAEF,iEAAiE;YACjE,MAAM,GAAG,KAAK,CAAC;QAChB,CAAC;QAED,MAAM,mBAAmB,GAAG,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC;QACjD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IACjE,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACI,MAAM,CAAC,KAAa,EAAE,MAAc;QAC1C,MAAM,GAAG,GAAG,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC;QAE/B,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC;QACjB,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAEjC,KAAK,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACjD,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,IAAI,YAAY,GAAG,KAAK,EAAE,CAAC;gBAC1B,OAAO,GAAG,CAAC,CAAC;YACb,CAAC;iBAAM,IAAI,KAAK,CAAC,KAAK,GAAG,GAAG,EAAE,CAAC;gBAC9B,MAAM,GAAG,CAAC,CAAC;gBACX,MAAM;YACP,CAAC;QACF,CAAC;QAED,MAAM,qBAAqB,GAAG,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC;QAEnD,IAAI,qBAAqB,KAAK,CAAC,EAAE,CAAC;YACjC,2BAA2B;YAC3B,OAAO;QACR,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,GAAG,CAAC,CAAC;QAC3B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC;QAEzB,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAA,cAAG,GAAE,CAAC;YACvC,MAAM,YAAY,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,IAAI,OAAO,GAAG,KAAK,CAAC;YAEpB,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,IAAI,YAAY,IAAI,GAAG,EAAE,CAAC;gBACjD,8DAA8D;gBAC9D,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACP,6EAA6E;gBAC7E,IAAI,KAAK,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC;oBACzB,+EAA+E;oBAC/E,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;oBACzC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;oBACrD,OAAO,GAAG,IAAI,CAAC;gBAChB,CAAC;gBAED,IAAI,YAAY,GAAG,GAAG,EAAE,CAAC;oBACxB,gFAAgF;oBAChF,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,CAAC;oBACzB,MAAM,SAAS,GAAG,YAAY,GAAG,GAAG,CAAC;oBACrC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;wBACzD,KAAK,EAAE,QAAQ;wBACf,MAAM,EAAE,SAAS;wBACjB,KAAK,EAAE,KAAK,CAAC,KAAK;qBAClB,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;CACD;AAjMD,4BAiMC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { oob } from \"@fluidframework/core-utils/internal\";\n\n/**\n * RangeMap represents a mapping from integers to values of type T or undefined.\n * The values for a range of consecutive keys can be changed or queried in a single operation.\n */\nexport class RangeMap<T> {\n\tprivate readonly entries: RangeEntry<T>[];\n\n\tpublic constructor(initialEntries?: RangeEntry<T>[]) {\n\t\tthis.entries = initialEntries ? [...initialEntries] : [];\n\t}\n\n\t/**\n\t * Retrieves all entries from the rangeMap.\n\t * @returns An array of RangeEntryResult objects, each containing the start index, length, and value of a contiguous range.\n\t */\n\tpublic getAllEntries(): readonly RangeQueryResult<T>[] {\n\t\treturn this.entries;\n\t}\n\n\t/**\n\t * Retrieves the value for some prefix of the query range.\n\t *\n\t * @param start - The first key in the query range.\n\t * @param length - The length of the query range.\n\t * @returns A RangeQueryResult containing the value associated with `start`,\n\t * and the number of consecutive keys with that same value.\n\t */\n\tpublic get(start: number, length: number): RangeQueryResult<T> {\n\t\tfor (const entry of this.entries) {\n\t\t\tif (entry.start > start) {\n\t\t\t\treturn { value: undefined, length: Math.min(entry.start - start, length) };\n\t\t\t}\n\n\t\t\tconst lastRangeKey = entry.start + entry.length - 1;\n\t\t\tif (lastRangeKey >= start) {\n\t\t\t\tconst overlapLength = lastRangeKey - start + 1;\n\t\t\t\treturn { value: entry.value, length: Math.min(overlapLength, length) };\n\t\t\t}\n\t\t}\n\n\t\t// There were no entries intersecting the query range, so the entire query range has undefined value.\n\t\treturn { value: undefined, length };\n\t}\n\n\t/**\n\t * Sets the value for a specified range.\n\t *\n\t * @param start - The first key in the range being set.\n\t * @param length - The length of the range.\n\t * @param value - The value to associate with the range.\n\t */\n\tpublic set(start: number, length: number, value: T | undefined): void {\n\t\tif (value === undefined) {\n\t\t\tthis.delete(start, length);\n\t\t\treturn;\n\t\t}\n\n\t\tconst end = start + length - 1;\n\t\tconst newEntry: RangeEntry<T> = { start, length, value };\n\n\t\tlet iBefore = -1;\n\t\tlet iAfter = this.entries.length;\n\t\tfor (const [i, entry] of this.entries.entries()) {\n\t\t\tconst entryLastKey = entry.start + entry.length - 1;\n\t\t\tif (entryLastKey < start) {\n\t\t\t\tiBefore = i;\n\t\t\t} else if (entry.start > end) {\n\t\t\t\tiAfter = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst numOverlappingEntries = iAfter - iBefore - 1;\n\t\tif (numOverlappingEntries === 0) {\n\t\t\tthis.entries.splice(iAfter, 0, newEntry);\n\t\t\treturn;\n\t\t}\n\n\t\tconst iFirst = iBefore + 1;\n\t\tconst firstEntry = this.entries[iFirst] ?? oob();\n\t\tconst iLast = iAfter - 1;\n\t\tconst lastEntry = this.entries[iLast] ?? oob();\n\t\tconst lengthBeforeFirst = start - firstEntry.start;\n\t\tconst lastEntryKey = lastEntry.start + lastEntry.length - 1;\n\t\tconst lengthAfterLast = lastEntryKey - end;\n\n\t\tif (lengthBeforeFirst > 0 && lengthAfterLast > 0 && iFirst === iLast) {\n\t\t\t// The new entry fits in the middle of an existing entry.\n\t\t\t// We replace the existing entry with:\n\t\t\t// 1) the portion which comes before `newEntry`\n\t\t\t// 2) `newEntry`\n\t\t\t// 3) the portion which comes after `newEntry`\n\t\t\tthis.entries.splice(iFirst, 1, { ...firstEntry, length: lengthBeforeFirst }, newEntry, {\n\t\t\t\t...lastEntry,\n\t\t\t\tstart: end + 1,\n\t\t\t\tlength: lengthAfterLast,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (lengthBeforeFirst > 0) {\n\t\t\tthis.entries[iFirst] = { ...firstEntry, length: lengthBeforeFirst };\n\t\t\t// The entry at `iFirst` is no longer overlapping with `newEntry`.\n\t\t\tiBefore = iFirst;\n\t\t}\n\n\t\tif (lengthAfterLast > 0) {\n\t\t\tthis.entries[iLast] = {\n\t\t\t\t...lastEntry,\n\t\t\t\tstart: end + 1,\n\t\t\t\tlength: lengthAfterLast,\n\t\t\t};\n\n\t\t\t// The entry at `iLast` is no longer overlapping with `newEntry`.\n\t\t\tiAfter = iLast;\n\t\t}\n\n\t\tconst numContainedEntries = iAfter - iBefore - 1;\n\t\tthis.entries.splice(iBefore + 1, numContainedEntries, newEntry);\n\t}\n\n\t/**\n\t * Deletes values within a specified range, updating or removing existing entries.\n\t *\n\t * 1. If an entry is completely included in the deletion range, the whole entry will be deleted\n\t * e.g.: map = [[1, 2], [4, 6]], delete range: [3, 6]\n\t * map becomes [[1, 2]] after deletion\n\t * (Note: the notation [a, b] represents start = a, end = b for simpler visualization, instead of `b`\n\t * representing the length)\n\t *\n\t * 2. If an entry is partially overlapped with the deletion range, the start or end point will be shifted\n\t * e.g.: map = [[1, 2], [4, 6]], delete range: [2, 4]\n\t * map becomes [[1, 1], [5, 6]] after deletion\n\t *\n\t * 3. If an entry completely includes the deletion range, the original entry may be split into two.\n\t * e.g.: map = [[1, 6]], delete range: [2, 4]\n\t * map becomes [[1, 1], [5, 6]]\n\t *\n\t * @param start - The start of the range to delete (inclusive).\n\t * @param length - The length of the range to delete.\n\t */\n\tpublic delete(start: number, length: number): void {\n\t\tconst end = start + length - 1;\n\n\t\tlet iBefore = -1;\n\t\tlet iAfter = this.entries.length;\n\n\t\tfor (const [i, entry] of this.entries.entries()) {\n\t\t\tconst entryLastKey = entry.start + entry.length - 1;\n\t\t\tif (entryLastKey < start) {\n\t\t\t\tiBefore = i;\n\t\t\t} else if (entry.start > end) {\n\t\t\t\tiAfter = i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tconst numOverlappingEntries = iAfter - iBefore - 1;\n\n\t\tif (numOverlappingEntries === 0) {\n\t\t\t// No entry will be removed\n\t\t\treturn;\n\t\t}\n\n\t\tconst iFirst = iBefore + 1;\n\t\tconst iLast = iAfter - 1;\n\n\t\tfor (let i = iFirst; i <= iLast; ++i) {\n\t\t\tconst entry = this.entries[i] ?? oob();\n\t\t\tconst entryLastKey = entry.start + entry.length - 1;\n\t\t\tlet isDirty = false;\n\n\t\t\tif (entry.start >= start && entryLastKey <= end) {\n\t\t\t\t// If the entry lies within the range to be deleted, remove it\n\t\t\t\tthis.entries.splice(i, 1);\n\t\t\t} else {\n\t\t\t\t// If the entry partially or completely overlaps with the range to be deleted\n\t\t\t\tif (entry.start < start) {\n\t\t\t\t\t// Update the endpoint and length of the portion before the range to be deleted\n\t\t\t\t\tconst lengthBefore = start - entry.start;\n\t\t\t\t\tthis.entries[i] = { ...entry, length: lengthBefore };\n\t\t\t\t\tisDirty = true;\n\t\t\t\t}\n\n\t\t\t\tif (entryLastKey > end) {\n\t\t\t\t\t// Update the startpoint and length of the portion after the range to be deleted\n\t\t\t\t\tconst newStart = end + 1;\n\t\t\t\t\tconst newLength = entryLastKey - end;\n\t\t\t\t\tthis.entries.splice(isDirty ? i + 1 : i, isDirty ? 0 : 1, {\n\t\t\t\t\t\tstart: newStart,\n\t\t\t\t\t\tlength: newLength,\n\t\t\t\t\t\tvalue: entry.value,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Represents a contiguous range of values in the RangeMap.\n * This interface is used internally and should not be exposed to consumers.\n */\ninterface RangeEntry<T> {\n\t/**\n\t * The starting index of the range (inclusive).\n\t */\n\treadonly start: number;\n\n\t/**\n\t * The length of the range.\n\t */\n\treadonly length: number;\n\n\t/**\n\t * The value associated with this range.\n\t */\n\treadonly value: T;\n}\n\n/**\n * Describes the result of a range query, including the value and length of the matching prefix.\n */\nexport interface RangeQueryResult<T> {\n\t/**\n\t * The value of the first key in the query range.\n\t * If no matching range is found, this will be undefined.\n\t */\n\treadonly value: T | undefined;\n\n\t/**\n\t * The length of the prefix of the query range which has the same value.\n\t * For example, if a RangeMap has the same value for keys 5, 6, and 7,\n\t * a query about the range [5, 10] would give a result with length 3.\n\t */\n\treadonly length: number;\n}\n"]}
1
+ {"version":3,"file":"rangeMap.js","sourceRoot":"","sources":["../../src/util/rangeMap.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,kEAAkE;AAClE,gEAAkD;AAElD;;;;;;GAMG;AACH,MAAa,QAAQ;IAGpB;;;;;;;;;;;;;;;;OAgBG;IACH,YACkB,SAAwC,EACxC,YAAoC,EACrC,cAA+C,oBAAoB;QAFlE,cAAS,GAAT,SAAS,CAA+B;QACxC,iBAAY,GAAZ,YAAY,CAAwB;QACrC,gBAAW,GAAX,WAAW,CAAwD;QAEnF,IAAI,CAAC,IAAI,GAAG,IAAI,wBAAK,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACI,OAAO;QACb,MAAM,OAAO,GAA4B,EAAE,CAAC;QAC5C,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC;IAEM,KAAK;QACX,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,KAAQ,EAAE,MAAc;QACrC,MAAM,OAAO,GAAG,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,OAAO,CAAC;QAChB,CAAC;QAED,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,IAAA,cAAG,GAAE,CAAC;QACvC,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC;QAChE,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,CAAC,CAAC,GAAG;gBACZ,KAAK;gBACL,MAAM,EAAE,UAAU,CAAC,MAAM,GAAG,YAAY;gBACxC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,EAAE,YAAY,CAAC;aACvD,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAA,cAAG,GAAE,CAAC;QACvD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3E,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;QACvD,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAClE,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;QACxF,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC;IAED;;;;;;;OAOG;IACI,QAAQ,CAAC,KAAQ,EAAE,MAAc;QACvC,CAAC;YACA,wEAAwE;YACxE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC1B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBAEhD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;gBAC/D,MAAM,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAC7D,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;gBACvF,IAAI,iBAAiB,GAAG,CAAC,EAAE,CAAC;oBAC3B,OAAO;wBACN,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,iBAAiB,CAAC;wBACjD,KAAK;wBACL,MAAM,EAAE,iBAAiB;qBACzB,CAAC;gBACH,CAAC;YACF,CAAC;QACF,CAAC;QAED,CAAC;YACA,6CAA6C;YAC7C,8EAA8E;YAC9E,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACvB,MAAM,QAAQ,GAAG,GAAG,CAAC;gBAErB,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;gBACvD,IAAI,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,EAAE,CAAC;oBACrC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;gBAChF,CAAC;YACF,CAAC;YAED,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAC5C,CAAC;IACF,CAAC;IAED;;;;;;OAMG;IACI,GAAG,CAAC,KAAQ,EAAE,MAAc,EAAE,KAAoB;QACxD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACzC,CAAC;IACF,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACI,MAAM,CAAC,KAAQ,EAAE,MAAc;QACrC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;QACxD,KAAK,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,sBAAsB,CACnF,KAAK,EACL,MAAM,CACN,EAAE,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtB,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACnD,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;gBACtB,wFAAwF;gBACxF,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;YAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;YACnE,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBACrB,uFAAuF;gBACvF,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;gBAChD,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;gBAClD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;oBACrB,MAAM,EAAE,WAAW;oBACnB,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC;iBAC1C,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;IACF,CAAC;IAEM,KAAK;QACX,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAO,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACvF,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC;IACf,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,KAAK,CAAO,CAAiB,EAAE,CAAiB;QAC7D,IAAA,iBAAM,EACL,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,SAAS;YAC1B,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,YAAY;YACjC,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,WAAW,EAChC,KAAK,CAAC,wCAAwC,CAC9C,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;QAE9E,mEAAmE;QACnE,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAC7B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7C,8BAA8B;YAC9B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAEO,sBAAsB,CAAC,KAAQ,EAAE,MAAc;QACtD,MAAM,OAAO,GAA4B,EAAE,CAAC;QAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;QACvD,CAAC;YACA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAClD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACrB,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBAChD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;gBAC1D,IAAI,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;oBAClC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC1D,CAAC;YACF,CAAC;QACF,CAAC;QAED,CAAC;YACA,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YAC5C,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC5B,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACrB,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,CAAC;oBAChC,MAAM;gBACP,CAAC;gBAED,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBAChD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC;gBAE1D,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;gBACzD,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YAChD,CAAC;QACF,CAAC;QAED,OAAO,OAAO,CAAC;IAChB,CAAC;IAEO,EAAE,CAAC,CAAI,EAAE,CAAI;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAEO,EAAE,CAAC,CAAI,EAAE,CAAI;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;IAEO,EAAE,CAAC,CAAI,EAAE,CAAI;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAEO,EAAE,CAAC,CAAI,EAAE,CAAI;QACpB,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IACrC,CAAC;CACD;AAxQD,4BAwQC;AA4CD,SAAgB,kBAAkB;IACjC,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;AACtD,CAAC;AAFD,gDAEC;AAED,SAAS,aAAa,CAAC,GAAW,EAAE,MAAc;IACjD,OAAO,GAAG,GAAG,MAAM,CAAC;AACrB,CAAC;AAED,SAAS,gBAAgB,CAAC,CAAS,EAAE,CAAS;IAC7C,OAAO,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED,SAAS,oBAAoB,CAAI,KAAQ,EAAE,MAAc;IACxD,OAAO,KAAK,CAAC;AACd,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { assert, oob } from \"@fluidframework/core-utils/internal\";\nimport { BTree } from \"@tylerbu/sorted-btree-es6\";\n\n/**\n * RangeMap represents a mapping from keys of type K to values of type V or undefined.\n * The set of all possible keys is assumed to be fully ordered,\n * and for each key there should be a single next higher key.\n * The values for a range of consecutive keys can be changed or queried in a single operation.\n * The structure of the keys is described by the `offsetKey` and `subtractKeys` functions provided in the constructor.\n */\nexport class RangeMap<K, V> {\n\tprivate tree: BTree<K, RangeEntry<V>>;\n\n\t/**\n\t * @param offsetKey - Function which returns a new key which is `offset` keys after `key`.\n\t * When `offset` is negative, the returned key should come before `key`.\n\t *\n\t * @param subtractKeys - Function which returns the difference between `b` and `a`.\n\t * Offsetting `b` by this difference should return `a`.\n\t * The difference can be infinite if `a` cannot be reached from `b` by offsetting,\n\t * but the difference should still be positive if `a` is larger than `b` and negative if smaller.\n\t *\n\t * @param offsetValue - Function used to associate a range of values with a range of keys.\n\t * When writing to a range of keys starting with `start`, the value of the nth key is interpreted to be\n\t * `offsetValue(firstValue, n - 1)`.\n\t * The same logic should be used when interpreting the values for keys after the first in a\n\t * `RangeQueryResult` or `RangeQueryEntry`.\n\t *\n\t * If `offsetValue` is left unspecified, all keys in a block will be given the same value.\n\t */\n\tpublic constructor(\n\t\tprivate readonly offsetKey: (key: K, offset: number) => K,\n\t\tprivate readonly subtractKeys: (a: K, b: K) => number,\n\t\tpublic readonly offsetValue: (value: V, offset: number) => V = defaultValueOffsetFn,\n\t) {\n\t\tthis.tree = new BTree(undefined, subtractKeys);\n\t}\n\n\t/**\n\t * Retrieves all entries from the RangeMap.\n\t */\n\tpublic entries(): RangeQueryEntry<K, V>[] {\n\t\tconst entries: RangeQueryEntry<K, V>[] = [];\n\t\tfor (const [start, entry] of this.tree.entries()) {\n\t\t\tentries.push({ start, length: entry.length, value: entry.value });\n\t\t}\n\n\t\treturn entries;\n\t}\n\n\tpublic clear(): void {\n\t\tthis.tree.clear();\n\t}\n\n\t/**\n\t * Retrieves the values for all keys in the query range.\n\t *\n\t * @param start - The first key in the range being queried\n\t * @param length - The length of the query range\n\t * @returns A list of entries, each describing the value for some subrange of the query.\n\t * The entries are in the same order as the keys, and there is an entry for every key with a non `undefined` value.\n\t */\n\tpublic getAll(start: K, length: number): RangeQueryEntry<K, V>[] {\n\t\tconst entries = this.getIntersectingEntries(start, length);\n\t\tif (entries.length === 0) {\n\t\t\treturn entries;\n\t\t}\n\n\t\tconst firstEntry = entries[0] ?? oob();\n\t\tconst lengthBefore = this.subtractKeys(start, firstEntry.start);\n\t\tif (lengthBefore > 0) {\n\t\t\tentries[0] = {\n\t\t\t\tstart,\n\t\t\t\tlength: firstEntry.length - lengthBefore,\n\t\t\t\tvalue: this.offsetValue(firstEntry.value, lengthBefore),\n\t\t\t};\n\t\t}\n\n\t\tconst lastEntry = entries[entries.length - 1] ?? oob();\n\t\tconst lastEntryKey = this.offsetKey(lastEntry.start, lastEntry.length - 1);\n\t\tconst lastQueryKey = this.offsetKey(start, length - 1);\n\t\tconst lengthAfter = this.subtractKeys(lastEntryKey, lastQueryKey);\n\t\tif (lengthAfter > 0) {\n\t\t\tentries[entries.length - 1] = { ...lastEntry, length: lastEntry.length - lengthAfter };\n\t\t}\n\n\t\treturn entries;\n\t}\n\n\t/**\n\t * Retrieves the value for some prefix of the query range.\n\t *\n\t * @param start - The first key in the query range.\n\t * @param length - The length of the query range.\n\t * @returns A RangeQueryResult containing the value associated with `start`,\n\t * and the number of consecutive keys with that same value (at least 1, at most `length`).\n\t */\n\tpublic getFirst(start: K, length: number): RangeQueryResult<K, V> {\n\t\t{\n\t\t\t// We first check for an entry with a key less than or equal to `start`.\n\t\t\tconst entry = this.tree.getPairOrNextLower(start);\n\t\t\tif (entry !== undefined) {\n\t\t\t\tconst entryKey = entry[0];\n\t\t\t\tconst { value, length: entryLength } = entry[1];\n\n\t\t\t\tconst entryLastKey = this.offsetKey(entryKey, entryLength - 1);\n\t\t\t\tconst lengthBeforeQuery = this.subtractKeys(start, entryKey);\n\t\t\t\tconst overlappingLength = Math.min(this.subtractKeys(entryLastKey, start) + 1, length);\n\t\t\t\tif (overlappingLength > 0) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tvalue: this.offsetValue(value, lengthBeforeQuery),\n\t\t\t\t\t\tstart,\n\t\t\t\t\t\tlength: overlappingLength,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t{\n\t\t\t// There is no value associated with `start`.\n\t\t\t// Now we need to determine how many of the following keys are also undefined.\n\t\t\tconst key = this.tree.nextHigherKey(start);\n\t\t\tif (key !== undefined) {\n\t\t\t\tconst entryKey = key;\n\n\t\t\t\tconst lastQueryKey = this.offsetKey(start, length - 1);\n\t\t\t\tif (this.le(entryKey, lastQueryKey)) {\n\t\t\t\t\treturn { value: undefined, start, length: this.subtractKeys(entryKey, start) };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { value: undefined, start, length };\n\t\t}\n\t}\n\n\t/**\n\t * Sets the value for a specified range.\n\t *\n\t * @param start - The first key in the range being set.\n\t * @param length - The length of the range.\n\t * @param value - The value to associate with the range.\n\t */\n\tpublic set(start: K, length: number, value: V | undefined): void {\n\t\tthis.delete(start, length);\n\t\tif (value !== undefined) {\n\t\t\tthis.tree.set(start, { value, length });\n\t\t}\n\t}\n\n\t/**\n\t * Deletes values within a specified range, updating or removing existing entries.\n\t *\n\t * 1. If an entry is completely included in the deletion range, the whole entry will be deleted\n\t * e.g.: map = [[1, 2], [4, 6]], delete range: [3, 6]\n\t * map becomes [[1, 2]] after deletion\n\t * (Note: the notation [a, b] represents start = a, end = b for simpler visualization, instead of `b`\n\t * representing the length)\n\t *\n\t * 2. If an entry is partially overlapped with the deletion range, the start or end point will be shifted\n\t * e.g.: map = [[1, 2], [4, 6]], delete range: [2, 4]\n\t * map becomes [[1, 1], [5, 6]] after deletion\n\t *\n\t * 3. If an entry completely includes the deletion range, the original entry may be split into two.\n\t * e.g.: map = [[1, 6]], delete range: [2, 4]\n\t * map becomes [[1, 1], [5, 6]]\n\t *\n\t * @param start - The start of the range to delete (inclusive).\n\t * @param length - The length of the range to delete.\n\t */\n\tpublic delete(start: K, length: number): void {\n\t\tconst lastDeleteKey = this.offsetKey(start, length - 1);\n\t\tfor (const { start: key, length: entryLength, value } of this.getIntersectingEntries(\n\t\t\tstart,\n\t\t\tlength,\n\t\t)) {\n\t\t\tthis.tree.delete(key);\n\t\t\tconst lengthBefore = this.subtractKeys(start, key);\n\t\t\tif (lengthBefore > 0) {\n\t\t\t\t// A portion of this entry comes before the deletion range, so we reinsert that portion.\n\t\t\t\tthis.tree.set(key, { length: lengthBefore, value });\n\t\t\t}\n\n\t\t\tconst lastEntryKey = this.offsetKey(key, entryLength - 1);\n\t\t\tconst lengthAfter = this.subtractKeys(lastEntryKey, lastDeleteKey);\n\t\t\tif (lengthAfter > 0) {\n\t\t\t\t// A portion of this entry comes after the deletion range, so we reinsert that portion.\n\t\t\t\tconst newKey = this.offsetKey(lastDeleteKey, 1);\n\t\t\t\tconst difference = this.subtractKeys(newKey, key);\n\t\t\t\tthis.tree.set(newKey, {\n\t\t\t\t\tlength: lengthAfter,\n\t\t\t\t\tvalue: this.offsetValue(value, difference),\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic clone(): RangeMap<K, V> {\n\t\tconst cloned = new RangeMap<K, V>(this.offsetKey, this.subtractKeys, this.offsetValue);\n\t\tcloned.tree = this.tree.clone();\n\t\treturn cloned;\n\t}\n\n\t/**\n\t * Returns a new map which contains the entries from both input maps.\n\t */\n\tpublic static union<K, V>(a: RangeMap<K, V>, b: RangeMap<K, V>): RangeMap<K, V> {\n\t\tassert(\n\t\t\ta.offsetKey === b.offsetKey &&\n\t\t\t\ta.subtractKeys === b.subtractKeys &&\n\t\t\t\ta.offsetValue === b.offsetValue,\n\t\t\t0xaae /* Maps should have the same behavior */,\n\t\t);\n\n\t\tconst merged = new RangeMap<K, V>(a.offsetKey, a.subtractKeys, a.offsetValue);\n\n\t\t// TODO: Is there a good pattern that lets us make `tree` readonly?\n\t\tmerged.tree = a.tree.clone();\n\t\tfor (const [key, value] of b.tree.entries()) {\n\t\t\t// TODO: Handle key collisions\n\t\t\tmerged.tree.set(key, value);\n\t\t}\n\n\t\treturn merged;\n\t}\n\n\tprivate getIntersectingEntries(start: K, length: number): RangeQueryEntry<K, V>[] {\n\t\tconst entries: RangeQueryEntry<K, V>[] = [];\n\t\tconst lastQueryKey = this.offsetKey(start, length - 1);\n\t\t{\n\t\t\tconst entry = this.tree.getPairOrNextLower(start);\n\t\t\tif (entry !== undefined) {\n\t\t\t\tconst key = entry[0];\n\t\t\t\tconst { length: entryLength, value } = entry[1];\n\t\t\t\tconst lastEntryKey = this.offsetKey(key, entryLength - 1);\n\t\t\t\tif (this.ge(lastEntryKey, start)) {\n\t\t\t\t\tentries.push({ start: key, length: entryLength, value });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t{\n\t\t\tlet entry = this.tree.nextHigherPair(start);\n\t\t\twhile (entry !== undefined) {\n\t\t\t\tconst key = entry[0];\n\t\t\t\tif (this.gt(key, lastQueryKey)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst { length: entryLength, value } = entry[1];\n\t\t\t\tconst lastEntryKey = this.offsetKey(key, entryLength - 1);\n\n\t\t\t\tentries.push({ start: key, length: entryLength, value });\n\t\t\t\tentry = this.tree.nextHigherPair(lastEntryKey);\n\t\t\t}\n\t\t}\n\n\t\treturn entries;\n\t}\n\n\tprivate gt(a: K, b: K): boolean {\n\t\treturn this.subtractKeys(a, b) > 0;\n\t}\n\n\tprivate ge(a: K, b: K): boolean {\n\t\treturn this.subtractKeys(a, b) >= 0;\n\t}\n\n\tprivate lt(a: K, b: K): boolean {\n\t\treturn this.subtractKeys(a, b) < 0;\n\t}\n\n\tprivate le(a: K, b: K): boolean {\n\t\treturn this.subtractKeys(a, b) <= 0;\n\t}\n}\n\n/**\n * Represents a contiguous range of values in the RangeMap.\n */\ninterface RangeEntry<V> {\n\t/**\n\t * The length of the range.\n\t */\n\treadonly length: number;\n\n\t/**\n\t * The value associated with this range.\n\t */\n\treadonly value: V;\n}\n\n/**\n * Describes the result of a range query, including the value and length of the matching prefix.\n */\nexport interface RangeQueryResult<K, V> {\n\t/**\n\t * The key for the first element in the range.\n\t */\n\treadonly start: K;\n\n\t/**\n\t * The value of the first key in the query range.\n\t * If no matching range is found, this will be undefined.\n\t */\n\treadonly value: V | undefined;\n\n\t/**\n\t * The length of the prefix of the query range which has the same value.\n\t * For example, if a RangeMap has the same value for keys 5, 6, and 7,\n\t * a query about the range [5, 10] would give a result with length 3.\n\t */\n\treadonly length: number;\n}\n\nexport interface RangeQueryEntry<K, V> extends RangeQueryResult<K, V> {\n\treadonly value: V;\n}\n\nexport function newIntegerRangeMap<V>(): RangeMap<number, V> {\n\treturn new RangeMap(offsetInteger, subtractIntegers);\n}\n\nfunction offsetInteger(key: number, offset: number): number {\n\treturn key + offset;\n}\n\nfunction subtractIntegers(a: number, b: number): number {\n\treturn a - b;\n}\n\nfunction defaultValueOffsetFn<T>(value: T, offset: number): T {\n\treturn value;\n}\n"]}