@procedures/collections 0.46.0 → 0.47.1

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,29 @@
1
1
  # @procedures/collections
2
2
 
3
+ ## 0.47.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [f845c6d]
8
+ - @procedures/client@0.47.1
9
+
10
+ ## 0.47.0
11
+
12
+ ### Patch Changes
13
+
14
+ - 397dd4b: Add `SummaryTree<Leaf, Summary>` and `summaryTree(spec, leaves)`: a persistent sequence of leaves with a monoid summary in each node. `concat`, `splitAt`, `split` (a monotone predicate over the prefix summary), `search`, `slice`, `splice`, `insert`, `remove`, `set` and `at` are O(log n). The tree is an AVL tree with the join algorithms.
15
+ - e1ce6f4: `SummaryTree` gets `locate(key, target)`, which finds the leaf and the offset of a position of an additive key and calls no `combine`. The new optional `spec.merge(left, right)` joins two neighbor leaves at each seam of `concat`, `append`, `prepend`, `splice`, `insert` and `remove`. `set` and a `splice` of 8 leaves or fewer copy only the paths to their leaves. A rope edit of 100k characters in leaves of 256 calls `combine` and `measure` 21 times at most, and 135 times before. Each node keeps the summary of its left subtree and its leaf, so a copy that changes only the right subtree calls `combine` once. The new type `SummaryLocation` is the result of `locate`.
16
+ - Updated dependencies [c9125a8]
17
+ - Updated dependencies [335728b]
18
+ - Updated dependencies [d987202]
19
+ - Updated dependencies [45a737f]
20
+ - Updated dependencies [d77e9e8]
21
+ - Updated dependencies [e913014]
22
+ - Updated dependencies [2f0c7b0]
23
+ - Updated dependencies [ad70c38]
24
+ - Updated dependencies [47819c6]
25
+ - @procedures/client@0.47.0
26
+
3
27
  ## 0.46.0
4
28
 
5
29
  ### Patch Changes
package/README.md CHANGED
@@ -408,6 +408,34 @@ const pq = new PriorityQueue<Task>((a, b) => a.priority - b.priority);
408
408
  const deque = new ArrayDeque<Message>(); // Double-ended queue
409
409
  ```
410
410
 
411
+ ### Sequences with a summary: `SummaryTree`
412
+
413
+ `SummaryTree<Leaf, Summary>` is a persistent sequence of leaves. Each node keeps the summary of its part of the sequence. A summary is a value of a monoid that you give as data: `empty` and an associative `combine`.
414
+
415
+ - `concat`, `splitAt`, `split`, `slice`, `splice`, `insert`, `remove`, `set` and `at` are O(log n).
416
+ - `split(predicate)` splits before the first leaf whose prefix summary satisfies a monotone predicate. `search(predicate)` finds that leaf and changes nothing.
417
+ - `locate(key, target)` finds the leaf that holds a position of an additive key, and the offset in that leaf. It calls no `combine`, so it costs nothing when `combine` is slow.
418
+ - `set` and a `splice` of 8 leaves or fewer copy only the paths to their leaves. Each level of each path calls `combine` 1 or 2 times. A leaf that becomes two leaves costs one descent.
419
+ - The optional `spec.merge(left, right)` joins two neighbor leaves into one at each seam that an edit makes. A rope uses it to keep its chunks large.
420
+ - Each edit returns a new tree. The old tree does not change, and the two trees share the nodes that did not change.
421
+ - The tree is an AVL tree, so its height is at most 1.45 log2(n + 2).
422
+
423
+ ```typescript
424
+ import { summaryTree } from "@procedures/collections";
425
+
426
+ const spec = {
427
+ monoid: { empty: 0, combine: (a: number, b: number) => a + b },
428
+ measure: (line: string) => line.length,
429
+ };
430
+ const lines = summaryTree(spec, ["first line", "second", "third"]);
431
+ lines.summary; // 21
432
+ const hit = lines.search((length) => length > 12); // { index: 1, leaf: "second", before: 10, through: 16 }
433
+ const edited = lines.splice(1, 1, ["2nd"]); // lines does not change
434
+ const at = lines.locate((length) => length, 12); // { index: 1, leaf: "second", offset: 2 }
435
+ ```
436
+
437
+ Use the same `spec` object for each tree that `concat` or `splice` joins. A tree of a different spec causes a `TypeError`.
438
+
411
439
  ## Behavior Decorators
412
440
 
413
441
  ### Bounded Collections