Skip to main content

nickel_lang_vector/
vector.rs

1//! [`Vector`] is a persistent vector (also known as a "bitmapped vector trie").
2//!
3//! Most of the operations on `Vector` have similar asymptotic (but
4//! with a slower constant-factor) run-time to the same operations on the
5//! standard-library `Vec`. For example, you can quickly push an element to
6//! the back, or pop one from the back; random-access indexing is also fast.
7//! On the other hand, pushing/popping from the front or insertion/deletion in
8//! the middle are both slow. (Actually, we haven't even implemented these slow
9//! operations because we don't need them.)
10//!
11//! The main advantage that [`Vector`] has over [`std::vec::Vec`] is *persistence*:
12//! you can cheaply clone a `Vector` and then modify the clone. The clone and the
13//! original will share most of their storage.
14//!
15//! There's a good explanation of the data structure
16//! [here](https://hypirion.com/musings/understanding-persistent-vector-pt-1).
17//! Very briefly, a vector is stored as a tree with a fixed branching factor, where
18//! all leaves are the same distance from the root.
19//! Unlike most tree data-structures, it isn't balanced. Instead, it's "packed left"
20//! as much as possible.
21//!
22//! Persistence is achieved by cloning the path leading down
23//! to the node you want to modify: say you want to push a new element, and the're
24//! room for it in the right-most leaf. Then you clone the right-most leaf and
25//! add your new element. Then you clone the leaf's parent and populate it with
26//! pointers to the leaf's (unmodified) siblings, plus the leaf's new clone. Then
27//! you clone the leaf's grandparent and populate it with pointers to the leaf's
28//! (unmodified) uncles, plus the leaf's parent's new clone. You continue up the
29//! tree like this, and you end up with a tree where the path from the leaf to
30//! the root is new but everything else is shared with the previous version of
31//! the vector.
32//!
33//! In this implementation, the pointers in the tree are `Rc` pointers, and we
34//! use `Rc::make_mut` to clone-on-write: when a tree node is only present in
35//! the tree that we're modifying, the clones in the description above
36//! are replaced by direct modification.
37//!
38//! ## Branching factor `N`.
39//!
40//! `Vector` stores its data in a tree, and you get to choose the branching factor
41//! `N`. It must be a power of 2 between 2 and 128 (inclusive), and something like
42//! 32 seems to be reasonable. There is a trade-off involved, of course. Large
43//! values of `N` make traditional array operations -- like random access, pushing,
44//! and popping -- fast because the tree becomes very flat. On the other hand, the
45//! copy-on-write operations suffer when `N` is large because blocks of size `N`
46//! are the smallest units of shareable data.
47//!
48//! For example, if `N` is 128 and you have a vector of less than 128 entries,
49//! it will be stored in a single flat array of capacity 128. If you then clone
50//! the `Vector` and modify the clone, the whole length-128 array will be
51//! cloned. If the vector is stored as a taller tree, only the blocks on the
52//! path from the root to the modified entry will be duplicated. That is, modifying
53//! an entry in a `Vector` of length `n` and branching factor `N` has
54//! cost `O(N * log_N n)`.
55//!
56//! ## Comparison to `rpds`
57//!
58//! The same structure is implemented in [rpds](https://crates.io/crates/rpds),
59//! but our implementation is faster for Nickel's use-cases:
60//! - rpds's internal nodes are implemented with `Vec`, meaning that there's a
61//!   double pointer indirection. We store our internal nodes inline.
62//! - rpds wraps its leaves in `Rc` pointers, but we are mainly interested in
63//!   storing things that are already reference-counted under the hood. We store
64//!   our leaves inline, and require that they be `Clone`.
65//! - we have optimized implementations of `Extend`, and support fast iteration
66//!   over subslices.
67//! - we have better support for "consuming" operations, such as an
68//!   implementation of `into_iter` that avoids cloning the data unless
69//!   necessary for persistence.
70
71use std::{iter::Peekable, ops::Index, rc::Rc};
72
73use imbl_sized_chunks::Chunk;
74
75use crate::{Const, ValidBranchingConstant};
76
77// In principle we could decouple the size of the interior nodes from the size of the leaves.
78// This might make sense when `T` is large, because the interior nodes are always pointer-sized.
79type Interior<T, const N: usize> = Chunk<Rc<Node<T, N>>, N>;
80type ChunkIter<T, const N: usize> = imbl_sized_chunks::sized_chunk::Iter<T, N>;
81type InteriorChunkIter<T, const N: usize> = ChunkIter<Rc<Node<T, N>>, N>;
82
83// Can we improve the memory layout? We like N to be a power of 2 for
84// performance (because it allows adjusting the indices using just bitwise
85// operations), but it would also be cool if the total size of the node were a
86// nice round number (so it would exactly fit in a small integer number of cache
87// lines). The discriminant makes it hard to have both of these at once.
88// Since we always know (based on the tree height) which type we *expect* a node
89// to have, we could use a `union` instead of an `enum` (at the cost of lots of
90// unsafe code).
91//
92// `N` must be a power of 2; this is important for efficiency because it allows
93// the use of bitwise operations for a lot of things. I tried allowing `N` to
94// be arbitrary, hoping that the compiler would be smart enough to do the fast
95// thing when `N` is a power of 2. It wasn't.
96//
97// It would be nice to encode the power-of-2 restriction more efficiently (for
98// example, by parametrizing with `B` and setting `N = 1 << B`). This sort of
99// needs the `generic_const_exprs` feature to work, though.
100#[derive(Debug, Clone, PartialEq, Eq, Hash)]
101enum Node<T, const N: usize> {
102    Leaf { data: Chunk<T, N> },
103    Interior { children: Interior<T, N> },
104}
105
106/// `idx` is the global index into the root node, and we are some
107/// possibly-intermediate node at height `height` (where the leaf is at height
108/// zero). Which of our children does the global index belong to?
109fn extract_index<const N: usize>(idx: usize, height: u8) -> usize {
110    let shifted: usize = idx >> (N.ilog2() * u32::from(height));
111    shifted & (N - 1)
112}
113
114impl<T: Clone, const N: usize> Node<T, N>
115where
116    Const<N>: ValidBranchingConstant,
117{
118    /// An inefficient but correct (and simple) method for computing the length
119    /// of this subtree. We cache the length in the top-level vector, so this is
120    /// only used for sanity-checks.
121    fn len(&self) -> usize {
122        match self {
123            Node::Leaf { data } => data.len(),
124            Node::Interior { children } => {
125                // This could be faster if we used the tree height to compute
126                // the size of the packed part of the tree. But this function is
127                // only used for checking invariants, so speed isn't important.
128                children.iter().map(|c| c.len()).sum()
129            }
130        }
131    }
132
133    /// If this node is at height `height`, try to get the element at the given
134    /// index.
135    fn get(&self, height: u8, idx: usize) -> Option<&T> {
136        match self {
137            Node::Leaf { data } => {
138                debug_assert_eq!(height, 0);
139                data.get(idx & (N - 1))
140            }
141            Node::Interior { children } => {
142                let bucket_idx = extract_index::<N>(idx, height);
143                children
144                    .get(bucket_idx)
145                    .and_then(|child| child.get(height - 1, idx))
146            }
147        }
148    }
149
150    /// Set the element at the given index.
151    ///
152    /// The index is allowed to point to the uninitialized slot just past the
153    /// end of the initialized part, but it must point to a valid index within
154    /// this node (i.e. if this node is full then it can't point past the end).
155    ///
156    /// Panics if the index is invalid.
157    fn set(&mut self, height: u8, idx: usize, elt: T) {
158        match self {
159            Node::Leaf { data } => {
160                let idx = idx & (N - 1);
161                debug_assert_eq!(height, 0);
162                debug_assert!(idx <= data.len());
163                if idx < data.len() {
164                    data.set(idx, elt);
165                } else {
166                    data.push_back(elt);
167                }
168            }
169            Node::Interior { children } => {
170                let bucket_idx = extract_index::<N>(idx, height);
171                assert!(height >= 1);
172                assert!(bucket_idx <= children.len());
173                if bucket_idx < children.len() {
174                    Rc::make_mut(&mut children[bucket_idx]).set(height - 1, idx, elt);
175                } else {
176                    let mut leaf = Chunk::new();
177                    leaf.push_back(elt);
178
179                    let mut child = Node::Leaf { data: leaf };
180                    for _ in 1..height {
181                        let mut children = Chunk::new();
182                        children.push_back(Rc::new(child));
183                        child = Node::Interior { children };
184                    }
185                    children.push_back(Rc::new(child));
186                }
187            }
188        }
189    }
190
191    /// Deletes and returns the last element of this subtree (which is assumed to be non-empty).
192    ///
193    /// Returns true if popping made this subtree empty.
194    fn pop(&mut self) -> (T, bool) {
195        match self {
196            Node::Leaf { data } => {
197                debug_assert!(!data.is_empty());
198                let ret = data.pop_back();
199                (ret, data.is_empty())
200            }
201            Node::Interior { children } => {
202                let (ret, child_empty) =
203                    Rc::make_mut(children.last_mut().expect("empty interior node")).pop();
204                if child_empty {
205                    children.pop_back();
206                }
207                (ret, children.is_empty())
208            }
209        }
210    }
211
212    /// Shrinks the length of this subtree to `len`.
213    ///
214    /// Assumes that the length is less than this node's current length.
215    fn truncate(&mut self, height: u8, len: usize) {
216        match self {
217            Node::Leaf { data } => {
218                debug_assert!(height == 0);
219                data.drop_right(len);
220            }
221            Node::Interior { children } => {
222                // If `len` is small enough, we may just want to drop some children
223                // and their entire subtrees.
224                let max_child_len = N.pow(u32::from(height));
225                let num_full_children = len / max_child_len;
226                let extra = len % max_child_len;
227                if extra > 0 {
228                    children.drop_right(num_full_children + 1);
229                    Rc::make_mut(&mut children[num_full_children]).truncate(height - 1, extra);
230                } else {
231                    children.drop_right(num_full_children);
232                }
233            }
234        }
235    }
236}
237
238/// A persistent vector.
239#[derive(Clone, Debug, PartialEq, Eq, Hash)]
240pub struct Vector<T, const N: usize>
241where
242    Const<N>: ValidBranchingConstant,
243{
244    root: Option<Rc<Node<T, N>>>,
245    length: usize,
246    // TODO: could save some space by taking 8 bits out of length
247    height: u8,
248}
249
250/// A borrowed iterator over a [`Vector`].
251#[derive(Debug, Clone)]
252pub struct Iter<'a, T, const N: usize>
253where
254    Const<N>: ValidBranchingConstant,
255{
256    stack: Vec<std::slice::Iter<'a, Rc<Node<T, N>>>>,
257    leaf: std::slice::Iter<'a, T>,
258}
259
260impl<'a, T, const N: usize> Iterator for Iter<'a, T, N>
261where
262    Const<N>: ValidBranchingConstant,
263{
264    type Item = &'a T;
265
266    fn next(&mut self) -> Option<Self::Item> {
267        if let Some(ret) = self.leaf.next() {
268            Some(ret)
269        } else {
270            let height = self.stack.len();
271            let mut next = loop {
272                match self.stack.last_mut() {
273                    Some(iter) => {
274                        if let Some(next) = iter.next() {
275                            break next;
276                        } else {
277                            self.stack.pop();
278                        }
279                    }
280                    None => {
281                        return None;
282                    }
283                }
284            };
285
286            let cur_len = self.stack.len();
287            for _ in cur_len..height {
288                let Node::Interior { children } = next.as_ref() else {
289                    unreachable!();
290                };
291                let mut children_iter = children.iter();
292                next = children_iter.next().expect("empty interior node");
293                self.stack.push(children_iter);
294            }
295
296            let Node::Leaf { data } = next.as_ref() else {
297                unreachable!();
298            };
299            debug_assert!(!data.is_empty());
300            self.leaf = data.iter();
301            self.leaf.next()
302        }
303    }
304}
305
306/// A mutable iterator over a [`Vector`].
307#[derive(Debug)]
308pub struct IterMut<'a, T, const N: usize>
309where
310    Const<N>: ValidBranchingConstant,
311{
312    stack: Vec<std::slice::IterMut<'a, Rc<Node<T, N>>>>,
313    leaf: std::slice::IterMut<'a, T>,
314}
315
316impl<'a, T, const N: usize> Iterator for IterMut<'a, T, N>
317where
318    Const<N>: ValidBranchingConstant,
319    T: Clone,
320{
321    type Item = &'a mut T;
322
323    fn next(&mut self) -> Option<Self::Item> {
324        if let Some(ret) = self.leaf.next() {
325            Some(ret)
326        } else {
327            let height = self.stack.len();
328            let mut next = loop {
329                match self.stack.last_mut() {
330                    Some(iter) => {
331                        if let Some(next) = iter.next() {
332                            break next;
333                        } else {
334                            self.stack.pop();
335                        }
336                    }
337                    None => {
338                        return None;
339                    }
340                }
341            };
342
343            let cur_len = self.stack.len();
344            for _ in cur_len..height {
345                let Node::Interior { children } = Rc::make_mut(next) else {
346                    unreachable!();
347                };
348                let mut children_iter = children.iter_mut();
349                next = children_iter.next().expect("empty interior node");
350                self.stack.push(children_iter);
351            }
352
353            let Node::Leaf { data } = Rc::make_mut(next) else {
354                unreachable!();
355            };
356            debug_assert!(!data.is_empty());
357            self.leaf = data.iter_mut();
358            self.leaf.next()
359        }
360    }
361}
362
363/// An owned iterator over a [`Vector`].
364//
365// `IntoIter` and `Iter` share a bunch of almost-identical code, and if we
366// ever want an `IterMut` then it will also be similar. I tried to make a
367// common implementation by defining something like
368//
369// ```rust
370// struct GenericIter<InteriorIter, LeafIter>
371// where InteriorIter: Iterator<Item = Either<InteriorIter, LeafIter>>,
372// {
373//     stack: Vec<InteriorIter>,
374//     leaf: LeafIter,
375// }
376// ```
377//
378// but it came with a massive 500% performance penalty. I didn't look carefully
379// into why.
380pub struct IntoIter<T, const N: usize> {
381    stack: Vec<InteriorChunkIter<T, N>>,
382    leaf: ChunkIter<T, N>,
383}
384
385impl<T: Clone, const N: usize> Iterator for IntoIter<T, N> {
386    type Item = T;
387
388    fn next(&mut self) -> Option<Self::Item> {
389        if let Some(ret) = self.leaf.next() {
390            Some(ret)
391        } else {
392            let height = self.stack.len();
393            let mut next = loop {
394                match self.stack.last_mut() {
395                    Some(iter) => {
396                        if let Some(next) = iter.next() {
397                            break next;
398                        } else {
399                            self.stack.pop();
400                        }
401                    }
402                    None => {
403                        return None;
404                    }
405                }
406            };
407
408            let cur_len = self.stack.len();
409            for _ in cur_len..height {
410                let Node::Interior { children } = Rc::unwrap_or_clone(next) else {
411                    unreachable!();
412                };
413                let mut children_iter = children.into_iter();
414                next = children_iter.next().expect("empty interior node");
415                self.stack.push(children_iter);
416            }
417
418            let Node::Leaf { data } = Rc::unwrap_or_clone(next) else {
419                unreachable!();
420            };
421            debug_assert!(!data.is_empty());
422            self.leaf = data.into_iter();
423            self.leaf.next()
424        }
425    }
426}
427
428impl<T: Clone, const N: usize> Extend<T> for Vector<T, N>
429where
430    Const<N>: ValidBranchingConstant,
431{
432    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
433        // Make the iterator peekable, because we need to check if there's an
434        // element remaining before we mutate the tree to make room for it.
435        let mut iter = iter.into_iter().peekable();
436
437        // Extends a node from an iterator, but does not increase the height of
438        // the node. If the node fills up, the iterator may not be fully consumed.
439        //
440        // Returns the number of elements consumed from the iterator.
441        fn extend_rec<T: Clone, I: Iterator<Item = T>, const N: usize>(
442            iter: &mut Peekable<I>,
443            node: &mut Interior<T, N>,
444            height: u8,
445        ) -> usize {
446            debug_assert!(height >= 1);
447            let mut consumed = 0;
448
449            if height == 1 {
450                // If there's a leaf that isn't filled, fill it.
451                if let Some(last_child) = node.last_mut() {
452                    // Usually, we assert that there's a last child because the
453                    // interior nodes are guaranteed to be non-empty. But within
454                    // this function we sometimes create empty interior nodes to
455                    // be filled later.
456                    // TODO: can avoid the clone if it's already full
457                    let Node::Leaf { data } = Rc::make_mut(last_child) else {
458                        unreachable!();
459                    };
460                    let old_len = data.len();
461                    data.extend(iter.take(N - data.len()));
462                    consumed += data.len() - old_len;
463                }
464
465                while !node.is_full() && iter.peek().is_some() {
466                    let data: Chunk<T, N> = iter.take(N).collect();
467                    consumed += data.len();
468                    node.push_back(Rc::new(Node::Leaf { data }));
469                }
470            } else {
471                if let Some(child) = node.last_mut() {
472                    let Node::Interior { children } = Rc::make_mut(child) else {
473                        unreachable!();
474                    };
475
476                    consumed += extend_rec(iter, children, height - 1);
477                }
478
479                while !node.is_full() && iter.peek().is_some() {
480                    let mut new_child: Interior<T, N> = Chunk::new();
481                    consumed += extend_rec(iter, &mut new_child, height - 1);
482                    node.push_back(Rc::new(Node::Interior {
483                        children: new_child,
484                    }));
485                }
486            }
487
488            consumed
489        }
490
491        if iter.peek().is_some() && self.root.is_none() {
492            self.root = Some(Rc::new(Node::Leaf {
493                data: Chunk::default(),
494            }));
495        }
496        while iter.peek().is_some() {
497            // Unwrap: we ensured that if the iterator has anything, the root is present.
498            let consumed = match Rc::make_mut(self.root.as_mut().unwrap()) {
499                Node::Leaf { data } => {
500                    let old_len = data.len();
501                    data.extend((&mut iter).take(N - data.len()));
502                    data.len() - old_len
503                }
504                Node::Interior { children } => extend_rec(&mut iter, children, self.height),
505            };
506            self.length += consumed;
507
508            // Check if there's more left in the iterator, and add a level if there is.
509            if iter.peek().is_some() {
510                self.add_level();
511            }
512        }
513    }
514}
515
516fn height_for_length<const N: usize>(length: usize) -> u8 {
517    // Length zero through N has height zero, length N + 1 through N^2 has height 1, etc.
518    // The unwrap is fine unless someone has a usize that's more than 256 bits.
519    length.saturating_sub(1).max(1).ilog(N).try_into().unwrap()
520}
521
522impl<T, const N: usize> Vector<T, N>
523where
524    Const<N>: ValidBranchingConstant,
525{
526    /// Create a new, empty, vector.
527    pub fn new() -> Self {
528        Self {
529            root: None,
530            length: 0,
531            height: 0,
532        }
533    }
534
535    /// The number of elements in this vector.
536    pub fn len(&self) -> usize {
537        self.length
538    }
539
540    /// Returns `true` if the length is zero.
541    pub fn is_empty(&self) -> bool {
542        self.length == 0
543    }
544}
545
546impl<T: Clone, const N: usize> Vector<T, N>
547where
548    Const<N>: ValidBranchingConstant,
549{
550    // Vectors must always be "packed to the left": every child that isn't the
551    // right-most child of its parent must have a complete subtree.
552    //
553    // This function checks that invariant. It's only used in tests.
554    fn is_packed(&self) -> bool {
555        fn is_packed_rec<T: Clone, const N: usize>(n: &Node<T, N>, right_most: bool) -> bool {
556            match n {
557                Node::Leaf { data } => data.is_full() || right_most,
558                Node::Interior { children } => {
559                    if let Some((tail, others)) = children.split_last() {
560                        others.iter().all(|n| is_packed_rec(n, false)) && is_packed_rec(tail, true)
561                    } else {
562                        debug_assert!(false, "empty node");
563                        false
564                    }
565                }
566            }
567        }
568
569        match &self.root {
570            None => true,
571            Some(root) => is_packed_rec(root, true),
572        }
573    }
574
575    /// Checks our internal invariants.
576    ///
577    /// It's public so that it can be used in out-of-crate tests.
578    #[doc(hidden)]
579    pub fn check_invariants(&self) {
580        assert!(self.is_packed());
581        assert_eq!(self.length, self.root.as_ref().map_or(0, |root| root.len()));
582        if let Some(root) = self.root.as_ref()
583            && let Node::Interior { children } = root.as_ref()
584        {
585            assert!(children.len() > 1);
586        }
587        assert_eq!(self.height, height_for_length::<N>(self.len()));
588    }
589
590    // Is this vector as full as it can be without increasing the height?
591    fn is_full(&self) -> bool {
592        self.root.is_none() || self.length == N.pow(u32::from(self.height) + 1)
593    }
594
595    /// Gets an element at a given index, or `None` if `idx` is out-of-bounds.
596    pub fn get(&self, idx: usize) -> Option<&T> {
597        self.root.as_ref().and_then(|r| r.get(self.height, idx))
598    }
599
600    /// Sets an element at a given index.
601    ///
602    /// Panics if the index is out of bounds.
603    pub fn set(&mut self, idx: usize, elt: T) {
604        if idx >= self.length {
605            panic!("index {idx} out of bounds, length is {}", self.length);
606        }
607
608        if let Some(root) = self.root.as_mut() {
609            Rc::make_mut(root).set(self.height, idx, elt);
610        }
611    }
612
613    // Increases the height of the tree by one, temporarily breaking the invariant that
614    // the root must have at least two children.
615    fn add_level(&mut self) {
616        match &mut self.root {
617            None => {
618                // We don't increment height in this case: height zero is used for both
619                // the empty vector and a vector with just one leaf.
620                // (Maybe we should use height 1 in the latter case?)
621                self.root = Some(Rc::new(Node::Leaf { data: Chunk::new() }));
622            }
623            Some(root) => {
624                let old_root = std::mem::replace(
625                    root,
626                    Rc::new(Node::Interior {
627                        children: Chunk::new(),
628                    }),
629                );
630
631                // TODO: maybe we can avoid the make_mut and the fallible destructuring?
632                // It seems a little tricky to do so without increasing some ref-counts.
633                let Node::Interior { children } = Rc::make_mut(root) else {
634                    unreachable!();
635                };
636                children.push_back(old_root);
637                self.height += 1;
638            }
639        }
640    }
641
642    /// Adds an element to the end of this array.
643    ///
644    /// Runs in time complexity `O(log n)` where `n` is the array length.
645    pub fn push(&mut self, elt: T) {
646        if self.is_full() {
647            self.add_level();
648        }
649        let idx = self.len();
650        // unwrap: self.add_level ensures that the root is non-empty
651        Rc::make_mut(self.root.as_mut().unwrap()).set(self.height, idx, elt);
652        self.length += 1;
653    }
654
655    /// Removes and returns the element at the end of this array, or
656    /// `None` if we're empty.
657    ///
658    /// Runs in time complexity `O(log self.len())`.
659    pub fn pop(&mut self) -> Option<T> {
660        if self.is_empty() {
661            None
662        } else {
663            // Unwrap: if we aren't empty, we have a root.
664            let root_mut = Rc::make_mut(self.root.as_mut().unwrap());
665            let (ret, _empty) = root_mut.pop();
666            self.length -= 1;
667
668            // If we've shrunk the root down to a single child, reduce the tree height by 1.
669            if let Node::Interior { children } = root_mut
670                && children.len() == 1
671            {
672                self.root = Some(children.pop_back());
673                self.height -= 1;
674            }
675            Some(ret)
676        }
677    }
678
679    /// If `len` is less than our length, shortens this vector to length `len`.
680    ///
681    /// If `len` is greater than or equal to our length, does nothing.
682    ///
683    /// The running time is `O(log self.len() + (len - self.len()))`. That
684    /// is, it is linear in the number of elements to be discarded. Even if
685    /// the elements to be discarded have trivial destructors, we still need
686    /// to destroy (and potentially de-allocate) a linear number of internal
687    /// nodes. However, the constant factor in this linear term should be quite
688    /// small; you can expect that `truncate` is much faster than multiple calls
689    /// to `pop`.
690    pub fn truncate(&mut self, len: usize) {
691        if len >= self.length {
692            return;
693        }
694
695        let new_height = height_for_length::<N>(len);
696        if new_height < self.height {
697            // unwrap: if we were empty, we would have returned at the `len >= self.length` check.
698            let mut new_root = self.root.as_ref().unwrap();
699            for _ in new_height..self.height {
700                let Node::Interior { children } = new_root.as_ref() else {
701                    unreachable!();
702                };
703                new_root = children.first().expect("empty interior node");
704            }
705            self.root = Some(Rc::clone(new_root));
706            self.height = new_height;
707        }
708
709        // unwrap: if we were empty, we would have returned at the `len >= self.length` check.
710        Rc::make_mut(self.root.as_mut().unwrap()).truncate(self.height, len);
711
712        self.length = len;
713    }
714
715    /// Returns an iterator over all elements in this vector.
716    ///
717    /// Iterator construction runs in `O(log self.len())` time. Each step
718    /// of the iteration runs in amortized constant time, worst-case `O(log
719    /// self.len())` time.
720    pub fn iter(&self) -> Iter<'_, T, N> {
721        self.into_iter()
722    }
723
724    /// Returns a mutable iterator over all elements in this vector.
725    ///
726    /// Iterator construction runs in `O(log self.len())` time. Each step
727    /// of the iteration runs in amortized constant time, worst-case `O(log
728    /// self.len())` time.
729    pub fn iter_mut(&mut self) -> IterMut<'_, T, N> {
730        self.into_iter()
731    }
732
733    /// Returns an iterator over borrowed elements in this vector, starting at a
734    /// specific index.
735    ///
736    /// Iterator construction runs in `O(log self.len())` time. Each step
737    /// of the iteration runs in amortized constant time, worst-case
738    /// `O(log self.len())` time. In particular, if `idx` is large then this is
739    /// much more efficient than calling `iter` and then advancing past `idx`
740    /// elements.
741    pub fn iter_starting_at(&self, idx: usize) -> Iter<'_, T, N> {
742        if idx == self.len() {
743            return Iter {
744                stack: Vec::new(),
745                leaf: [].iter(),
746            };
747        }
748        if idx > self.len() {
749            panic!("out of bounds");
750        }
751
752        let mut stack = Vec::with_capacity(self.height.into());
753        // unwrap: if we got past the initial tests on `idx`, we must be non-empty
754        // and so we have a root
755        let mut node = self.root.as_ref().unwrap().as_ref();
756        let mut height = self.height;
757
758        while let Node::Interior { children } = node {
759            let bucket_idx = extract_index::<N>(idx, height);
760            let mut node_iter = children[bucket_idx..].iter();
761
762            // expect: we've checked that `idx` is strictly less than the length,
763            // so this interior iterator should be non-empty also.
764            node = node_iter.next().expect("empty interior node");
765            stack.push(node_iter);
766
767            height = height.checked_sub(1).expect("invalid height");
768        }
769
770        let Node::Leaf { data } = node else {
771            unreachable!();
772        };
773        Iter {
774            stack,
775            leaf: data[(idx & (N - 1))..].iter(),
776        }
777    }
778
779    /// Returns an iterator over mutable elements in this vector, starting at a
780    /// specific index.
781    ///
782    /// Iterator construction runs in `O(log self.len())` time. Each step
783    /// of the iteration runs in amortized constant time, worst-case
784    /// `O(log self.len())` time. In particular, if `idx` is large then this is
785    /// much more efficient than calling `iter` and then advancing past `idx`
786    /// elements.
787    pub fn iter_mut_starting_at(&mut self, idx: usize) -> IterMut<'_, T, N> {
788        if idx == self.len() {
789            return IterMut {
790                stack: Vec::new(),
791                leaf: [].iter_mut(),
792            };
793        }
794        if idx > self.len() {
795            panic!("out of bounds");
796        }
797
798        let mut stack = Vec::with_capacity(self.height.into());
799        // unwrap: if we got past the initial tests on `idx`, we must be non-empty
800        // and so we have a root
801        let mut node = self.root.as_mut().unwrap();
802        let mut height = self.height;
803
804        while let Node::Interior { .. } = node.as_ref() {
805            let Node::Interior { children } = Rc::make_mut(node) else {
806                unreachable!("but we just checked it");
807            };
808
809            let bucket_idx = extract_index::<N>(idx, height);
810            let mut node_iter = children[bucket_idx..].iter_mut();
811
812            // expect: we've checked that `idx` is strictly less than the length,
813            // so this interior iterator should be non-empty also.
814            node = node_iter.next().expect("empty interior node");
815            stack.push(node_iter);
816
817            height = height.checked_sub(1).expect("invalid height");
818        }
819
820        let Node::Leaf { data } = Rc::make_mut(node) else {
821            unreachable!();
822        };
823        IterMut {
824            stack,
825            leaf: data[(idx & (N - 1))..].iter_mut(),
826        }
827    }
828
829    /// Returns an iterator over borrowed elements in this vector, starting at a
830    /// specific index.
831    ///
832    /// Iterator construction runs in `O(log self.len() + idx)` time. Each step
833    /// of the iteration runs in amortized constant time, worst-case
834    /// `O(log self.len())` time. Unlike the borrowed `iter_starting_at`, this is
835    /// not asymptotically faster than calling `into_iter` and then advancing
836    /// past `idx` elements, because we need to destruct and then potentially
837    /// de-allocate a linear (in `idx`) number of things. However, this method
838    /// should be faster in practice than iterating over `idx` elements.
839    pub fn into_iter_starting_at(self, mut idx: usize) -> IntoIter<T, N> {
840        if idx == self.len() {
841            return IntoIter {
842                stack: Vec::new(),
843                leaf: Chunk::new().into_iter(),
844            };
845        }
846        if idx > self.len() {
847            panic!("out of bounds");
848        }
849
850        let mut stack = Vec::with_capacity(self.height.into());
851        // unwrap: if we got past the initial tests on `idx`, we must be non-empty
852        // and so we have a root
853        let mut node = Rc::unwrap_or_clone(self.root.unwrap());
854        let mut height = self.height;
855
856        while let Node::Interior { mut children } = node {
857            let bucket_idx = extract_index::<N>(idx, height);
858            children.drop_left(bucket_idx);
859            let mut node_iter = children.into_iter();
860            node = Rc::unwrap_or_clone(node_iter.next().expect("empty interior node"));
861            stack.push(node_iter);
862
863            height = height.checked_sub(1).expect("invalid height");
864        }
865
866        let Node::Leaf { mut data } = node else {
867            unreachable!();
868        };
869        idx &= N - 1;
870        data.drop_left(idx);
871        IntoIter {
872            stack,
873            leaf: data.into_iter(),
874        }
875    }
876}
877
878impl<'a, T, const N: usize> IntoIterator for &'a Vector<T, N>
879where
880    Const<N>: ValidBranchingConstant,
881{
882    type Item = &'a T;
883    type IntoIter = Iter<'a, T, N>;
884
885    fn into_iter(self) -> Self::IntoIter {
886        let mut stack = Vec::with_capacity(self.height.into());
887        let Some(root) = &self.root else {
888            return Iter {
889                stack,
890                leaf: [].iter(),
891            };
892        };
893
894        let mut node = root.as_ref();
895        while let Node::Interior { children } = node {
896            let mut node_iter = children.iter();
897            node = node_iter.next().expect("empty interior node");
898            stack.push(node_iter);
899        }
900
901        let Node::Leaf { data } = node else {
902            unreachable!();
903        };
904        Iter {
905            stack,
906            leaf: data.iter(),
907        }
908    }
909}
910
911impl<'a, T, const N: usize> IntoIterator for &'a mut Vector<T, N>
912where
913    Const<N>: ValidBranchingConstant,
914    T: Clone,
915{
916    type Item = &'a mut T;
917    type IntoIter = IterMut<'a, T, N>;
918
919    fn into_iter(self) -> Self::IntoIter {
920        let mut stack = Vec::with_capacity(self.height.into());
921        let Some(root) = &mut self.root else {
922            return IterMut {
923                stack,
924                leaf: [].iter_mut(),
925            };
926        };
927
928        let mut node = root;
929        while let Node::Interior { .. } = node.as_ref() {
930            let Node::Interior { children } = Rc::make_mut(node) else {
931                unreachable!("but we just checked it");
932            };
933            let mut node_iter = children.iter_mut();
934            node = node_iter.next().expect("empty interior node");
935            stack.push(node_iter);
936        }
937
938        let Node::Leaf { data } = Rc::make_mut(node) else {
939            unreachable!();
940        };
941        IterMut {
942            stack,
943            leaf: data.iter_mut(),
944        }
945    }
946}
947
948impl<T: Clone, const N: usize> IntoIterator for Vector<T, N>
949where
950    Const<N>: ValidBranchingConstant,
951{
952    type Item = T;
953    type IntoIter = IntoIter<T, N>;
954
955    fn into_iter(self) -> Self::IntoIter {
956        let mut stack = Vec::with_capacity(self.height.into());
957        let Some(root) = self.root else {
958            return IntoIter {
959                stack,
960                leaf: Chunk::new().into_iter(),
961            };
962        };
963
964        let mut node = Rc::unwrap_or_clone(root);
965        while let Node::Interior { children } = node {
966            let mut node_iter = children.into_iter();
967            node = Rc::unwrap_or_clone(node_iter.next().expect("empty interior node"));
968            stack.push(node_iter);
969        }
970
971        let Node::Leaf { data } = node else {
972            unreachable!();
973        };
974        IntoIter {
975            stack,
976            leaf: data.into_iter(),
977        }
978    }
979}
980
981impl<T, const N: usize> Default for Vector<T, N>
982where
983    Const<N>: ValidBranchingConstant,
984{
985    fn default() -> Self {
986        Self::new()
987    }
988}
989
990impl<T: Clone, const N: usize> FromIterator<T> for Vector<T, N>
991where
992    Const<N>: ValidBranchingConstant,
993{
994    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
995        let mut ret = Vector::default();
996        ret.extend(iter);
997        ret
998    }
999}
1000
1001impl<T: Clone, const N: usize> Index<usize> for Vector<T, N>
1002where
1003    Const<N>: ValidBranchingConstant,
1004{
1005    type Output = T;
1006
1007    fn index(&self, index: usize) -> &Self::Output {
1008        self.get(index).expect("index out of range")
1009    }
1010}
1011
1012#[cfg(test)]
1013mod tests {
1014    use super::*;
1015
1016    #[test]
1017    fn basic() {
1018        let mut vec = Vector::<u32, 2>::new();
1019        vec.check_invariants();
1020        vec.push(1);
1021        assert_eq!(vec.get(0), Some(&1));
1022        assert_eq!(vec.get(1), None);
1023        vec.check_invariants();
1024
1025        vec.push(2);
1026        vec.check_invariants();
1027        vec.push(3);
1028        vec.check_invariants();
1029        assert_eq!(vec.get(0), Some(&1));
1030        assert_eq!(vec.get(1), Some(&2));
1031        assert_eq!(vec.get(2), Some(&3));
1032        assert_eq!(vec.get(3), None);
1033
1034        let mut iter = vec.iter();
1035        assert_eq!(iter.next(), Some(&1));
1036        assert_eq!(iter.next(), Some(&2));
1037        assert_eq!(iter.next(), Some(&3));
1038        assert_eq!(iter.next(), None);
1039
1040        assert_eq!(vec.iter().copied().collect::<Vec<_>>(), vec![1, 2, 3]);
1041
1042        assert_eq!(vec.pop(), Some(3));
1043        vec.check_invariants();
1044        vec.push(3);
1045        vec.check_invariants();
1046
1047        vec.extend([1, 2, 3]);
1048        vec.check_invariants();
1049        let mut iter = vec.iter();
1050        assert_eq!(iter.next(), Some(&1));
1051        assert_eq!(iter.next(), Some(&2));
1052        assert_eq!(iter.next(), Some(&3));
1053        assert_eq!(iter.next(), Some(&1));
1054        assert_eq!(iter.next(), Some(&2));
1055        assert_eq!(iter.next(), Some(&3));
1056        assert_eq!(iter.next(), None);
1057
1058        assert_eq!(6, vec.len());
1059        assert_eq!(
1060            vec.iter().copied().collect::<Vec<_>>(),
1061            vec![1, 2, 3, 1, 2, 3]
1062        );
1063        assert_eq!(vec.into_iter().collect::<Vec<_>>(), vec![1, 2, 3, 1, 2, 3]);
1064    }
1065}