Skip to main content

scirs2_core/concurrent/
persistent_vector.rs

1//! Persistent vector based on Relaxed Radix Balanced (RRB) trees.
2//!
3//! An immutable, persistent vector where every "mutation" returns a new
4//! vector while sharing unchanged structure with previous versions via `Arc`.
5//!
6//! # Complexity
7//!
8//! | Operation     | Time                |
9//! |---------------|---------------------|
10//! | `get(index)`  | O(log₃₂ N)         |
11//! | `set(i, v)`   | O(log₃₂ N)         |
12//! | `push_back`   | O(1) amortised      |
13//! | `concat`      | O(log₃₂ N)         |
14//! | `slice`       | O(log₃₂ N)         |
15//! | `len`         | O(1)                |
16//!
17//! # Structural Sharing
18//!
19//! Old versions remain valid after modification — they share subtrees with
20//! new versions through `Arc`.
21
22use std::sync::Arc;
23
24/// Branching factor (2^5 = 32).
25const BRANCHING: usize = 32;
26/// Bit-mask for one level of index.
27const MASK: usize = BRANCHING - 1;
28/// Bits consumed per level.
29const BITS: usize = 5;
30
31// ---------------------------------------------------------------------------
32// Internal node types
33// ---------------------------------------------------------------------------
34
35#[derive(Clone, Debug)]
36enum RrbNode<T: Clone> {
37    /// Internal node with children and optional size table for relaxed nodes.
38    Internal {
39        children: Arc<Vec<Arc<RrbNode<T>>>>,
40        /// Size table: `sizes[i]` = cumulative count of elements up to and
41        /// including child `i`.  `None` for "dense" nodes where sizes are
42        /// computed from depth alone.
43        sizes: Option<Arc<Vec<usize>>>,
44    },
45    /// Leaf node holding up to BRANCHING elements.
46    Leaf { elements: Arc<Vec<T>> },
47}
48
49impl<T: Clone> RrbNode<T> {
50    fn empty_leaf() -> Arc<Self> {
51        Arc::new(RrbNode::Leaf {
52            elements: Arc::new(Vec::new()),
53        })
54    }
55
56    fn leaf(elements: Vec<T>) -> Arc<Self> {
57        Arc::new(RrbNode::Leaf {
58            elements: Arc::new(elements),
59        })
60    }
61
62    fn internal(children: Vec<Arc<RrbNode<T>>>, sizes: Option<Vec<usize>>) -> Arc<Self> {
63        Arc::new(RrbNode::Internal {
64            children: Arc::new(children),
65            sizes: sizes.map(Arc::new),
66        })
67    }
68
69    /// Number of children (for internal) or elements (for leaf).
70    fn width(&self) -> usize {
71        match self {
72            RrbNode::Internal { children, .. } => children.len(),
73            RrbNode::Leaf { elements } => elements.len(),
74        }
75    }
76
77    /// Get element at the given index within this subtree.
78    fn get(&self, index: usize, depth: usize) -> Option<&T> {
79        match self {
80            RrbNode::Leaf { elements } => elements.get(index),
81            RrbNode::Internal {
82                children, sizes, ..
83            } => {
84                if let Some(ref sz) = sizes {
85                    // Relaxed node: use size table to find child.
86                    let (child_idx, child_offset) = Self::find_child_relaxed(sz, index);
87                    children
88                        .get(child_idx)
89                        .and_then(|c| c.get(child_offset, depth - 1))
90                } else {
91                    // Dense node: compute child index from bits.
92                    let shift = depth * BITS;
93                    let child_idx = (index >> shift) & MASK;
94                    let child_offset = index & ((1 << shift) - 1);
95                    children
96                        .get(child_idx)
97                        .and_then(|c| c.get(child_offset, depth - 1))
98                }
99            }
100        }
101    }
102
103    /// Set element at the given index, returning a new node.
104    fn set(&self, index: usize, value: T, depth: usize) -> Arc<Self> {
105        match self {
106            RrbNode::Leaf { elements } => {
107                let mut new_elems = (**elements).clone();
108                if index < new_elems.len() {
109                    new_elems[index] = value;
110                }
111                Self::leaf(new_elems)
112            }
113            RrbNode::Internal {
114                children, sizes, ..
115            } => {
116                if let Some(ref sz) = sizes {
117                    let (child_idx, child_offset) = Self::find_child_relaxed(sz, index);
118                    let mut new_children = (**children).clone();
119                    if let Some(child) = new_children.get(child_idx) {
120                        new_children[child_idx] = child.set(child_offset, value, depth - 1);
121                    }
122                    Self::internal(new_children, Some((**sz).clone()))
123                } else {
124                    let shift = depth * BITS;
125                    let child_idx = (index >> shift) & MASK;
126                    let child_offset = index & ((1 << shift) - 1);
127                    let mut new_children = (**children).clone();
128                    if let Some(child) = new_children.get(child_idx) {
129                        new_children[child_idx] = child.set(child_offset, value, depth - 1);
130                    }
131                    Self::internal(new_children, None)
132                }
133            }
134        }
135    }
136
137    /// Find the child index and offset within that child for a relaxed node.
138    fn find_child_relaxed(sizes: &[usize], index: usize) -> (usize, usize) {
139        for (i, &cumulative) in sizes.iter().enumerate() {
140            if index < cumulative {
141                let prev = if i == 0 { 0 } else { sizes[i - 1] };
142                return (i, index - prev);
143            }
144        }
145        // Fallback: last child.
146        let last = sizes.len().saturating_sub(1);
147        let prev = if last == 0 { 0 } else { sizes[last - 1] };
148        (last, index.saturating_sub(prev))
149    }
150
151    /// Count elements in this subtree.
152    fn count(&self, _depth: usize) -> usize {
153        match self {
154            RrbNode::Leaf { elements } => elements.len(),
155            RrbNode::Internal {
156                children, sizes, ..
157            } => {
158                if let Some(ref sz) = sizes {
159                    sz.last().copied().unwrap_or(0)
160                } else if children.is_empty() {
161                    0
162                } else {
163                    // Dense node: compute from structure.
164                    let mut total = 0;
165                    for child in children.iter() {
166                        total += child.count(_depth - 1);
167                    }
168                    total
169                }
170            }
171        }
172    }
173
174    /// Collect all elements into a vec (in order).
175    fn collect_into(&self, out: &mut Vec<T>) {
176        match self {
177            RrbNode::Leaf { elements } => {
178                out.extend(elements.iter().cloned());
179            }
180            RrbNode::Internal { children, .. } => {
181                for child in children.iter() {
182                    child.collect_into(out);
183                }
184            }
185        }
186    }
187}
188
189// ---------------------------------------------------------------------------
190// PersistentRrbVec
191// ---------------------------------------------------------------------------
192
193/// A persistent vector based on Relaxed Radix Balanced (RRB) trees.
194///
195/// Every modification returns a new vector; the original remains unchanged.
196/// Structural sharing means this is memory-efficient.
197///
198/// # Example
199///
200/// ```rust
201/// use scirs2_core::concurrent::PersistentRrbVec;
202///
203/// let v0 = PersistentRrbVec::new();
204/// let v1 = v0.push_back(10);
205/// let v2 = v1.push_back(20);
206/// let v3 = v2.push_back(30);
207///
208/// assert_eq!(v3.get(0), Some(&10));
209/// assert_eq!(v3.get(1), Some(&20));
210/// assert_eq!(v3.get(2), Some(&30));
211/// assert_eq!(v3.len(), 3);
212///
213/// // v0 is still empty
214/// assert!(v0.is_empty());
215/// ```
216#[derive(Clone)]
217pub struct PersistentRrbVec<T: Clone> {
218    root: Arc<RrbNode<T>>,
219    /// Detached tail for O(1) amortised push.
220    tail: Arc<Vec<T>>,
221    /// Number of elements *not* in the tail (i.e., in the tree).
222    tree_len: usize,
223    /// Depth of the tree (0 = root is a leaf).
224    depth: usize,
225}
226
227impl<T: Clone> PersistentRrbVec<T> {
228    /// Create an empty persistent vector.
229    pub fn new() -> Self {
230        PersistentRrbVec {
231            root: RrbNode::empty_leaf(),
232            tail: Arc::new(Vec::new()),
233            tree_len: 0,
234            depth: 0,
235        }
236    }
237
238    /// Return the total number of elements.
239    pub fn len(&self) -> usize {
240        self.tree_len + self.tail.len()
241    }
242
243    /// Return `true` if the vector is empty.
244    pub fn is_empty(&self) -> bool {
245        self.len() == 0
246    }
247
248    /// Get a reference to the element at `index`.
249    pub fn get(&self, index: usize) -> Option<&T> {
250        let total = self.len();
251        if index >= total {
252            return None;
253        }
254
255        if index >= self.tree_len {
256            // In the tail.
257            self.tail.get(index - self.tree_len)
258        } else {
259            // In the tree.
260            self.root.get(index, self.depth)
261        }
262    }
263
264    /// Return a new vector with the element at `index` replaced by `value`.
265    ///
266    /// Returns `None` if `index` is out of bounds.
267    pub fn set(&self, index: usize, value: T) -> Option<Self> {
268        let total = self.len();
269        if index >= total {
270            return None;
271        }
272
273        if index >= self.tree_len {
274            // In the tail.
275            let tail_idx = index - self.tree_len;
276            let mut new_tail = (*self.tail).clone();
277            new_tail[tail_idx] = value;
278            Some(PersistentRrbVec {
279                root: Arc::clone(&self.root),
280                tail: Arc::new(new_tail),
281                tree_len: self.tree_len,
282                depth: self.depth,
283            })
284        } else {
285            // In the tree.
286            let new_root = self.root.set(index, value, self.depth);
287            Some(PersistentRrbVec {
288                root: new_root,
289                tail: Arc::clone(&self.tail),
290                tree_len: self.tree_len,
291                depth: self.depth,
292            })
293        }
294    }
295
296    /// Return a new vector with `value` appended at the end.
297    pub fn push_back(&self, value: T) -> Self {
298        if self.tail.len() < BRANCHING {
299            // Room in the tail.
300            let mut new_tail = (*self.tail).clone();
301            new_tail.push(value);
302            PersistentRrbVec {
303                root: Arc::clone(&self.root),
304                tail: Arc::new(new_tail),
305                tree_len: self.tree_len,
306                depth: self.depth,
307            }
308        } else {
309            // Tail is full — push it into the tree and start a new tail.
310            let tail_node = RrbNode::leaf((*self.tail).clone());
311            let (new_root, new_depth) = self.push_tail_into_tree(tail_node);
312            let new_tail = vec![value];
313
314            PersistentRrbVec {
315                root: new_root,
316                tail: Arc::new(new_tail),
317                tree_len: self.tree_len + BRANCHING,
318                depth: new_depth,
319            }
320        }
321    }
322
323    /// Push the full tail leaf into the tree, possibly growing the tree height.
324    fn push_tail_into_tree(&self, tail_node: Arc<RrbNode<T>>) -> (Arc<RrbNode<T>>, usize) {
325        // Special case: empty tree.
326        if self.tree_len == 0 {
327            return (tail_node, 0);
328        }
329
330        // Try to insert into the existing tree.
331        if let Some(new_root) = self.push_into_node(&self.root, tail_node.clone(), self.depth) {
332            (new_root, self.depth)
333        } else {
334            // Tree is full at this depth — grow by one level.
335            let new_right = self.new_path(tail_node, self.depth);
336            let mut sizes = Vec::new();
337            let left_count = self.root.count(self.depth);
338            let right_count = new_right.count(self.depth);
339            sizes.push(left_count);
340            sizes.push(left_count + right_count);
341            let new_root = RrbNode::internal(vec![Arc::clone(&self.root), new_right], Some(sizes));
342            (new_root, self.depth + 1)
343        }
344    }
345
346    /// Try to push a leaf into the given node. Returns `None` if the node is full.
347    fn push_into_node(
348        &self,
349        node: &Arc<RrbNode<T>>,
350        leaf: Arc<RrbNode<T>>,
351        depth: usize,
352    ) -> Option<Arc<RrbNode<T>>> {
353        match node.as_ref() {
354            RrbNode::Leaf { .. } => {
355                // We're at a leaf level; can't push another leaf here.
356                // The caller needs to grow the tree.
357                None
358            }
359            RrbNode::Internal {
360                children, sizes, ..
361            } => {
362                if depth == 1 {
363                    // Children are leaves.
364                    if children.len() < BRANCHING {
365                        let mut new_children = (**children).clone();
366                        new_children.push(leaf);
367                        let new_sizes = self.compute_sizes(&new_children, 0);
368                        Some(RrbNode::internal(new_children, Some(new_sizes)))
369                    } else {
370                        None // full
371                    }
372                } else {
373                    // Try to push into the last child.
374                    let last_idx = children.len() - 1;
375                    if let Some(new_last) =
376                        self.push_into_node(&children[last_idx], leaf.clone(), depth - 1)
377                    {
378                        let mut new_children = (**children).clone();
379                        new_children[last_idx] = new_last;
380                        let new_sizes = self.compute_sizes(&new_children, depth - 1);
381                        Some(RrbNode::internal(new_children, Some(new_sizes)))
382                    } else if children.len() < BRANCHING {
383                        // Last child is full; add a new path.
384                        let new_path = self.new_path(leaf, depth - 1);
385                        let mut new_children = (**children).clone();
386                        new_children.push(new_path);
387                        let new_sizes = self.compute_sizes(&new_children, depth - 1);
388                        Some(RrbNode::internal(new_children, Some(new_sizes)))
389                    } else {
390                        None // this node is full
391                    }
392                }
393            }
394        }
395    }
396
397    /// Create a path of internal nodes leading to the given leaf at the specified depth.
398    fn new_path(&self, leaf: Arc<RrbNode<T>>, depth: usize) -> Arc<RrbNode<T>> {
399        if depth == 0 {
400            leaf
401        } else {
402            let child = self.new_path(leaf, depth - 1);
403            let count = child.count(depth - 1);
404            RrbNode::internal(vec![child], Some(vec![count]))
405        }
406    }
407
408    /// Compute cumulative size table for a list of children at a given child depth.
409    fn compute_sizes(&self, children: &[Arc<RrbNode<T>>], child_depth: usize) -> Vec<usize> {
410        let mut sizes = Vec::with_capacity(children.len());
411        let mut cumulative = 0usize;
412        for child in children {
413            cumulative += child.count(child_depth);
414            sizes.push(cumulative);
415        }
416        sizes
417    }
418
419    /// Concatenate two persistent vectors into a new one.
420    ///
421    /// Both original vectors remain valid.
422    pub fn concat(&self, other: &Self) -> Self {
423        if self.is_empty() {
424            return other.clone();
425        }
426        if other.is_empty() {
427            return self.clone();
428        }
429
430        // Simple strategy: collect both into one vec and rebuild.
431        // This is O(n) but correct. For a production RRB-tree, the concat
432        // algorithm would merge the spines in O(log N) but that's
433        // significantly more complex.
434        let mut all = Vec::with_capacity(self.len() + other.len());
435        self.root.collect_into(&mut all);
436        all.extend(self.tail.iter().cloned());
437        other.root.collect_into(&mut all);
438        all.extend(other.tail.iter().cloned());
439
440        Self::from_vec(all)
441    }
442
443    /// Build a PersistentRrbVec from a Vec efficiently (bottom-up).
444    fn from_vec(elements: Vec<T>) -> Self {
445        if elements.is_empty() {
446            return Self::new();
447        }
448
449        let total = elements.len();
450
451        // Split into tree portion (full leaves) and tail.
452        let full_leaves = total / BRANCHING;
453        let tail_len = total - full_leaves * BRANCHING;
454
455        let tree_elements = &elements[..full_leaves * BRANCHING];
456        let tail_elements = &elements[full_leaves * BRANCHING..];
457
458        let tail = Arc::new(tail_elements.to_vec());
459
460        if full_leaves == 0 {
461            return PersistentRrbVec {
462                root: RrbNode::empty_leaf(),
463                tail,
464                tree_len: 0,
465                depth: 0,
466            };
467        }
468
469        // Build leaf nodes.
470        let mut leaves: Vec<Arc<RrbNode<T>>> = Vec::with_capacity(full_leaves);
471        for chunk in tree_elements.chunks(BRANCHING) {
472            leaves.push(RrbNode::leaf(chunk.to_vec()));
473        }
474
475        // Build tree bottom-up.
476        let mut level_nodes = leaves;
477        let mut depth = 0usize;
478
479        while level_nodes.len() > 1 {
480            let mut next_level = Vec::new();
481            for chunk in level_nodes.chunks(BRANCHING) {
482                let children: Vec<Arc<RrbNode<T>>> = chunk.to_vec();
483                let mut sizes = Vec::with_capacity(children.len());
484                let mut cum = 0usize;
485                for child in &children {
486                    cum += child.count(depth);
487                    sizes.push(cum);
488                }
489                next_level.push(RrbNode::internal(children, Some(sizes)));
490            }
491            level_nodes = next_level;
492            depth += 1;
493        }
494
495        let root = level_nodes
496            .into_iter()
497            .next()
498            .unwrap_or_else(RrbNode::empty_leaf);
499
500        PersistentRrbVec {
501            root,
502            tail,
503            tree_len: full_leaves * BRANCHING,
504            depth,
505        }
506    }
507
508    /// Extract a sub-vector for the given range.
509    ///
510    /// Returns a new `PersistentRrbVec` containing elements `[start..end)`.
511    pub fn slice(&self, start: usize, end: usize) -> Self {
512        let total = self.len();
513        let start = start.min(total);
514        let end = end.min(total);
515        if start >= end {
516            return Self::new();
517        }
518
519        // Collect the slice and rebuild.
520        let mut elements = Vec::with_capacity(end - start);
521        for i in start..end {
522            if let Some(v) = self.get(i) {
523                elements.push(v.clone());
524            }
525        }
526        Self::from_vec(elements)
527    }
528
529    /// Collect all elements into a `Vec`.
530    pub fn to_vec(&self) -> Vec<T> {
531        let mut result = Vec::with_capacity(self.len());
532        self.root.collect_into(&mut result);
533        result.extend(self.tail.iter().cloned());
534        result
535    }
536
537    /// Return an iterator over the elements.
538    pub fn iter(&self) -> PersistentRrbVecIter<'_, T> {
539        PersistentRrbVecIter {
540            vec: self,
541            index: 0,
542        }
543    }
544}
545
546impl<T: Clone> Default for PersistentRrbVec<T> {
547    fn default() -> Self {
548        Self::new()
549    }
550}
551
552impl<T: Clone + std::fmt::Debug> std::fmt::Debug for PersistentRrbVec<T> {
553    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
554        f.debug_list().entries(self.iter()).finish()
555    }
556}
557
558// ---------------------------------------------------------------------------
559// Iterator
560// ---------------------------------------------------------------------------
561
562/// Iterator over elements of a [`PersistentRrbVec`].
563pub struct PersistentRrbVecIter<'a, T: Clone> {
564    vec: &'a PersistentRrbVec<T>,
565    index: usize,
566}
567
568impl<'a, T: Clone> Iterator for PersistentRrbVecIter<'a, T> {
569    type Item = &'a T;
570
571    fn next(&mut self) -> Option<Self::Item> {
572        if self.index >= self.vec.len() {
573            return None;
574        }
575        let item = self.vec.get(self.index);
576        self.index += 1;
577        item
578    }
579
580    fn size_hint(&self) -> (usize, Option<usize>) {
581        let remaining = self.vec.len() - self.index;
582        (remaining, Some(remaining))
583    }
584}
585
586impl<T: Clone> ExactSizeIterator for PersistentRrbVecIter<'_, T> {}
587
588// ---------------------------------------------------------------------------
589// Tests
590// ---------------------------------------------------------------------------
591
592#[cfg(test)]
593mod tests {
594    use super::*;
595
596    #[test]
597    fn test_push_back_and_get() {
598        let v0 = PersistentRrbVec::new();
599        let v1 = v0.push_back(10);
600        let v2 = v1.push_back(20);
601        let v3 = v2.push_back(30);
602
603        assert_eq!(v3.get(0), Some(&10));
604        assert_eq!(v3.get(1), Some(&20));
605        assert_eq!(v3.get(2), Some(&30));
606        assert_eq!(v3.len(), 3);
607    }
608
609    #[test]
610    fn test_structural_sharing() {
611        let v0 = PersistentRrbVec::new();
612        let v1 = v0.push_back(1);
613        let v2 = v1.push_back(2);
614
615        // v1 should still be valid and unchanged.
616        assert_eq!(v1.len(), 1);
617        assert_eq!(v1.get(0), Some(&1));
618        assert_eq!(v1.get(1), None);
619
620        // v2 has both elements.
621        assert_eq!(v2.len(), 2);
622        assert_eq!(v2.get(0), Some(&1));
623        assert_eq!(v2.get(1), Some(&2));
624
625        // v0 is still empty.
626        assert!(v0.is_empty());
627    }
628
629    #[test]
630    fn test_set_returns_new_version() {
631        let v0 = PersistentRrbVec::new();
632        let v1 = v0.push_back(1).push_back(2).push_back(3);
633
634        let v2 = v1.set(1, 42);
635        assert!(v2.is_some());
636        let v2 = v2.expect("set should succeed");
637
638        // v2 has the updated value.
639        assert_eq!(v2.get(1), Some(&42));
640        // v1 is unchanged.
641        assert_eq!(v1.get(1), Some(&2));
642
643        // Out-of-bounds set returns None.
644        assert!(v1.set(100, 0).is_none());
645    }
646
647    #[test]
648    fn test_large_push_back() {
649        let mut v = PersistentRrbVec::new();
650        for i in 0..200u32 {
651            v = v.push_back(i);
652        }
653        assert_eq!(v.len(), 200);
654        for i in 0..200u32 {
655            assert_eq!(v.get(i as usize), Some(&i), "failed at index {i}");
656        }
657    }
658
659    #[test]
660    fn test_concat() {
661        let mut v1 = PersistentRrbVec::new();
662        for i in 0..50u32 {
663            v1 = v1.push_back(i);
664        }
665
666        let mut v2 = PersistentRrbVec::new();
667        for i in 50..100u32 {
668            v2 = v2.push_back(i);
669        }
670
671        let v3 = v1.concat(&v2);
672        assert_eq!(v3.len(), 100);
673        for i in 0..100u32 {
674            assert_eq!(v3.get(i as usize), Some(&i), "concat failed at index {i}");
675        }
676
677        // Originals unchanged.
678        assert_eq!(v1.len(), 50);
679        assert_eq!(v2.len(), 50);
680    }
681
682    #[test]
683    fn test_slice() {
684        let mut v = PersistentRrbVec::new();
685        for i in 0..100u32 {
686            v = v.push_back(i);
687        }
688
689        let s = v.slice(10, 20);
690        assert_eq!(s.len(), 10);
691        for i in 0..10u32 {
692            assert_eq!(s.get(i as usize), Some(&(i + 10)));
693        }
694
695        // Empty slice.
696        let s2 = v.slice(50, 50);
697        assert!(s2.is_empty());
698
699        // Out-of-bounds slice clamps.
700        let s3 = v.slice(90, 200);
701        assert_eq!(s3.len(), 10);
702    }
703
704    #[test]
705    fn test_to_vec() {
706        let mut v = PersistentRrbVec::new();
707        for i in 0..10u32 {
708            v = v.push_back(i);
709        }
710        assert_eq!(v.to_vec(), (0..10u32).collect::<Vec<_>>());
711    }
712
713    #[test]
714    fn test_iter() {
715        let mut v = PersistentRrbVec::new();
716        for i in 0..5i32 {
717            v = v.push_back(i);
718        }
719        let collected: Vec<i32> = v.iter().copied().collect();
720        assert_eq!(collected, vec![0, 1, 2, 3, 4]);
721        assert_eq!(v.iter().len(), 5);
722    }
723
724    #[test]
725    fn test_empty() {
726        let v: PersistentRrbVec<i32> = PersistentRrbVec::new();
727        assert!(v.is_empty());
728        assert_eq!(v.len(), 0);
729        assert_eq!(v.get(0), None);
730        assert!(v.to_vec().is_empty());
731    }
732
733    #[test]
734    fn test_single_element() {
735        let v = PersistentRrbVec::new().push_back(42);
736        assert_eq!(v.len(), 1);
737        assert_eq!(v.get(0), Some(&42));
738        assert!(!v.is_empty());
739    }
740
741    #[test]
742    fn test_concat_empty() {
743        let v = PersistentRrbVec::new().push_back(1).push_back(2);
744        let empty = PersistentRrbVec::new();
745
746        let r1 = v.concat(&empty);
747        assert_eq!(r1.len(), 2);
748
749        let r2 = empty.concat(&v);
750        assert_eq!(r2.len(), 2);
751    }
752
753    #[test]
754    fn test_many_push_backs_past_branching() {
755        // Push more than BRANCHING * BRANCHING elements to test tree growth.
756        let n = BRANCHING * BRANCHING + 100;
757        let mut v = PersistentRrbVec::new();
758        for i in 0..n {
759            v = v.push_back(i);
760        }
761        assert_eq!(v.len(), n);
762        for i in 0..n {
763            assert_eq!(v.get(i), Some(&i), "failed at index {i}");
764        }
765    }
766
767    #[test]
768    fn test_from_vec_roundtrip() {
769        let original: Vec<u32> = (0..150).collect();
770        let pv = PersistentRrbVec::from_vec(original.clone());
771        assert_eq!(pv.len(), 150);
772        assert_eq!(pv.to_vec(), original);
773    }
774}