* Scans and potentially modifies values for a subsequence of keys. * Note: the callback `onFound` should ideally be a pure function. * Specfically, it must not insert items, call clone(), or change * the collection except via return value; out-of-band editing may * cause an excepti
(
low: K,
high: K,
includeHigh: boolean,
onFound: (k: K, v: V, counter: number) => EditRangeResult<V, R> | void,
initialCounter?: number,
)
| 375 | * where n is proportional to the amount of shared data scanned. |
| 376 | */ |
| 377 | editRange<R = V>( |
| 378 | low: K, |
| 379 | high: K, |
| 380 | includeHigh: boolean, |
| 381 | onFound: (k: K, v: V, counter: number) => EditRangeResult<V, R> | void, |
| 382 | initialCounter?: number, |
| 383 | ): R | number { |
| 384 | let root = this._root |
| 385 | if (root.isShared) this._root = root = root.clone() |
| 386 | try { |
| 387 | const r = root.forRange( |
| 388 | low, |
| 389 | high, |
| 390 | includeHigh, |
| 391 | true, |
| 392 | this, |
| 393 | initialCounter || 0, |
| 394 | onFound, |
| 395 | ) |
| 396 | return typeof r === `number` ? r : r.break! |
| 397 | } finally { |
| 398 | let isShared |
| 399 | while (root.keys.length <= 1 && !root.isLeaf) { |
| 400 | isShared ||= root.isShared |
| 401 | this._root = root = |
| 402 | root.keys.length === 0 |
| 403 | ? EmptyLeaf |
| 404 | : (root as any as BNodeInternal<K, V>).children[0]! |
| 405 | } |
| 406 | // If any ancestor of the new root was shared, the new root must also be shared |
| 407 | if (isShared) { |
| 408 | root.isShared = true |
| 409 | } |
| 410 | } |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | /** Leaf node / base class. **************************************************/ |