tiered_vector/
lib.rs

1//
2// Copyright (c) 2025 Nathan Fiedler
3//
4
5//! An implementation of tiered vectors as described in the paper **Tiered
6//! Vectors** by Goodrich and Kloss II, published in 1999.
7//!
8//! * DOI:10.1007/3-540-48447-7_21
9//!
10//! This implementation is based on the algorithms described in the 1998 version
11//! of the paper titled **Tiered Vector** by the same authors. In short, the
12//! structure consists of a dope vector that references one or more circular
13//! buffers in which all buffers are full, with the exception of the last buffer
14//! which may be partially filled.
15//!
16//! # Memory Usage
17//!
18//! An empty resizable vector is approximately 72 bytes in size, and while
19//! holding elements it will have a space overhead on the order of O(√N) as
20//! described in the paper. As elements are added the vector will grow by
21//! allocating additional data blocks. Likewise, as elements are removed from
22//! the vector, data blocks will be deallocated as they become empty.
23//!
24//! # Performance
25//!
26//! The performance and memory layout is as described in the paper: O(√N) space
27//! overhead, O(1) get and update operations, and O(√n) insert and remove.
28//!
29//! # Safety
30//!
31//! Because this data structure is allocating memory, copying bytes using raw
32//! pointers, and de-allocating memory as needed, there are many `unsafe` blocks
33//! throughout the code.
34
35use std::alloc::{Layout, alloc, dealloc, handle_alloc_error};
36use std::fmt;
37use std::ops::{Index, IndexMut};
38
39/// Tiered vector which maintains a collection of circular deques in order to
40/// efficiently support insert and remove from any location within the vector.
41pub struct Vector<T> {
42    /// each deque is of size l = 2^k
43    k: usize,
44    /// bit-mask to get the index into a circular deque
45    k_mask: usize,
46    /// the 'l' value (2^k) cached for performance
47    l: usize,
48    /// when count increases to this size, expand the vector
49    upper_limit: usize,
50    /// when count decreases to this size, compress the vector
51    lower_limit: usize,
52    /// number of elements in the vector
53    count: usize,
54    /// dope vector
55    index: Vec<CyclicArray<T>>,
56}
57
58impl<T> Vector<T> {
59    /// Return an empty vector with zero capacity.
60    pub fn new() -> Self {
61        // default l value of 4 like std::vec::Vec does for its initial
62        // allocation (its initial capacity is zero then becomes 4 then doubles
63        // with each expansion)
64        Self {
65            k: 2,
66            k_mask: 3,
67            l: 4,
68            upper_limit: 16,
69            lower_limit: 0,
70            count: 0,
71            index: vec![],
72        }
73    }
74
75    /// Double the capacity of this vector by combining its deques into new
76    /// deques of double the capacity.
77    fn expand(&mut self) {
78        let l_prime = 1 << (self.k + 1);
79        let old_index: Vec<CyclicArray<T>> = std::mem::take(&mut self.index);
80        let mut iter = old_index.into_iter();
81        while let Some(a) = iter.next() {
82            if let Some(b) = iter.next() {
83                self.index.push(CyclicArray::combine(a, b));
84            } else {
85                self.index.push(CyclicArray::from(l_prime, a));
86            }
87        }
88        self.k += 1;
89        self.k_mask = (1 << self.k) - 1;
90        self.l = 1 << self.k;
91        self.upper_limit = self.l * self.l;
92        self.lower_limit = self.upper_limit / 8;
93    }
94
95    /// Inserts an element at position `index` within the array, shifting some
96    /// elements to the right as needed.
97    pub fn insert(&mut self, index: usize, value: T) {
98        let len = self.count;
99        if index > len {
100            panic!("insertion index (is {index}) should be <= len (is {len})");
101        }
102        if len >= self.upper_limit {
103            self.expand();
104        }
105        if len >= self.capacity() {
106            self.index.push(CyclicArray::<T>::new(self.l));
107        }
108        let sub = index >> self.k;
109        let end = len >> self.k;
110        let r_prime = index & self.k_mask;
111        if sub < end {
112            // push-pop phase
113            let mut head = self.index[sub].pop_back().unwrap();
114            for i in (sub + 1)..end {
115                let tail = self.index[i].pop_back().unwrap();
116                self.index[i].push_front(head);
117                head = tail;
118            }
119            self.index[end].push_front(head);
120        }
121        // shift phase
122        self.index[sub].insert(r_prime, value);
123        self.count += 1;
124    }
125
126    /// Appends an element to the back of a collection.
127    ///
128    /// # Panics
129    ///
130    /// Panics if a new block is allocated that would exceed `isize::MAX` _bytes_.
131    ///
132    /// # Time complexity
133    ///
134    /// O(√N) in the worst case.
135    pub fn push(&mut self, value: T) {
136        self.insert(self.count, value);
137    }
138
139    /// Appends an element if there is sufficient spare capacity, otherwise an
140    /// error is returned with the element.
141    ///
142    /// # Time complexity
143    ///
144    /// O(√N) in the worst case.
145    pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
146        if self.capacity() <= self.count {
147            Err(value)
148        } else {
149            self.push(value);
150            Ok(())
151        }
152    }
153
154    /// Retrieve a reference to the element at the given offset.
155    ///
156    /// # Time complexity
157    ///
158    /// Constant time.
159    pub fn get(&self, index: usize) -> Option<&T> {
160        if index >= self.count {
161            None
162        } else {
163            let sub = index >> self.k;
164            let r_prime = index & self.k_mask;
165            self.index[sub].get(r_prime)
166        }
167    }
168
169    /// Returns a mutable reference to an element.
170    ///
171    /// # Time complexity
172    ///
173    /// Constant time.
174    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
175        if index >= self.count {
176            None
177        } else {
178            let sub = index >> self.k;
179            let r_prime = index & self.k_mask;
180            self.index[sub].get_mut(r_prime)
181        }
182    }
183
184    /// Shrink the capacity of this vector by splitting its deques into new
185    /// deques of half the capacity.
186    fn compress(&mut self) {
187        let old_index: Vec<CyclicArray<T>> = std::mem::take(&mut self.index);
188        for old_deque in old_index.into_iter() {
189            let (a, b) = old_deque.split();
190            self.index.push(a);
191            self.index.push(b);
192        }
193        self.k -= 1;
194        self.k_mask = (1 << self.k) - 1;
195        self.l = 1 << self.k;
196        self.upper_limit = self.l * self.l;
197        self.lower_limit = self.upper_limit / 8;
198    }
199
200    /// Removes an element from position `index` within the array, shifting some
201    /// elements to the left as needed to close the gap.
202    ///
203    /// # Time complexity
204    ///
205    /// O(√N) in the worst case.
206    pub fn remove(&mut self, index: usize) -> T {
207        let len = self.count;
208        if index > len {
209            panic!("removal index (is {index}) should be <= len (is {len})");
210        }
211        // avoid compressing to deques smaller than 4
212        if len < self.lower_limit && self.k > 2 {
213            self.compress();
214        }
215        let sub = index >> self.k;
216        let end = (len - 1) >> self.k;
217        let r_prime = index & self.k_mask;
218        // shift phase
219        let ret = self.index[sub].remove(r_prime);
220        if sub < end {
221            // push-pop phase
222            let mut tail = self.index[end].pop_front().unwrap();
223            for i in (sub + 1..end).rev() {
224                let head = self.index[i].pop_front().unwrap();
225                self.index[i].push_back(tail);
226                tail = head;
227            }
228            self.index[sub].push_back(tail);
229        }
230        if self.index[end].is_empty() {
231            // prune circular arrays as they become empty
232            self.index.pop();
233        }
234        self.count -= 1;
235        ret
236    }
237
238    /// Removes the last element from the vector and returns it, or `None` if the
239    /// vector is empty.
240    ///
241    /// # Time complexity
242    ///
243    /// O(√N) in the worst case.
244    pub fn pop(&mut self) -> Option<T> {
245        if self.count > 0 {
246            Some(self.remove(self.count - 1))
247        } else {
248            None
249        }
250    }
251
252    /// Removes and returns the last element from a vector if the predicate
253    /// returns true, or `None`` if the predicate returns `false`` or the vector
254    /// is empty (the predicate will not be called in that case).
255    ///
256    /// # Time complexity
257    ///
258    /// O(√N) in the worst case.
259    pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
260        if self.count == 0 {
261            None
262        } else if let Some(last) = self.get_mut(self.count - 1) {
263            if predicate(last) { self.pop() } else { None }
264        } else {
265            None
266        }
267    }
268
269    // Returns an iterator over the vector.
270    //
271    // The iterator yields all items from start to end.
272    pub fn iter(&self) -> VectorIter<'_, T> {
273        VectorIter {
274            array: self,
275            index: 0,
276        }
277    }
278
279    /// Return the number of elements in the vector.
280    ///
281    /// # Time complexity
282    ///
283    /// Constant time.
284    pub fn len(&self) -> usize {
285        self.count
286    }
287
288    /// Returns the total number of elements the vector can hold without
289    /// reallocating.
290    ///
291    /// # Time complexity
292    ///
293    /// Constant time.
294    pub fn capacity(&self) -> usize {
295        (1 << self.k) * self.index.len()
296    }
297
298    /// Returns true if the array has a length of 0.
299    ///
300    /// # Time complexity
301    ///
302    /// Constant time.
303    pub fn is_empty(&self) -> bool {
304        self.count == 0
305    }
306
307    /// Clears the vector, removing all values and deallocating all blocks.
308    ///
309    /// # Time complexity
310    ///
311    /// O(n) if elements are droppable, otherwise O(√N)
312    pub fn clear(&mut self) {
313        self.index.clear();
314        self.count = 0;
315        self.k = 2;
316        self.k_mask = 3;
317        self.l = 1 << self.k;
318        self.upper_limit = self.l * self.l;
319        self.lower_limit = self.upper_limit / 8;
320    }
321}
322
323impl<T> Default for Vector<T> {
324    fn default() -> Self {
325        Self::new()
326    }
327}
328
329impl<T> fmt::Display for Vector<T> {
330    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331        write!(
332            f,
333            "Vector(k: {}, count: {}, dope: {})",
334            self.k,
335            self.count,
336            self.index.len(),
337        )
338    }
339}
340
341impl<T> Index<usize> for Vector<T> {
342    type Output = T;
343
344    fn index(&self, index: usize) -> &Self::Output {
345        let Some(item) = self.get(index) else {
346            panic!("index out of bounds: {}", index);
347        };
348        item
349    }
350}
351
352impl<T> IndexMut<usize> for Vector<T> {
353    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
354        let Some(item) = self.get_mut(index) else {
355            panic!("index out of bounds: {}", index);
356        };
357        item
358    }
359}
360
361impl<A> FromIterator<A> for Vector<A> {
362    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
363        let mut arr: Vector<A> = Vector::new();
364        for value in iter {
365            arr.push(value)
366        }
367        arr
368    }
369}
370
371/// Immutable array iterator.
372pub struct VectorIter<'a, T> {
373    array: &'a Vector<T>,
374    index: usize,
375}
376
377impl<'a, T> Iterator for VectorIter<'a, T> {
378    type Item = &'a T;
379
380    fn next(&mut self) -> Option<Self::Item> {
381        let value = self.array.get(self.index);
382        self.index += 1;
383        value
384    }
385}
386
387impl<T> IntoIterator for Vector<T> {
388    type Item = T;
389    type IntoIter = VectorIntoIter<Self::Item>;
390
391    fn into_iter(self) -> Self::IntoIter {
392        let mut me = std::mem::ManuallyDrop::new(self);
393        let index = std::mem::take(&mut me.index);
394        VectorIntoIter {
395            count: me.count,
396            index,
397        }
398    }
399}
400
401/// An iterator that moves out of a tiered vector.
402pub struct VectorIntoIter<T> {
403    /// number of remaining elements
404    count: usize,
405    /// index of circular deques
406    index: Vec<CyclicArray<T>>,
407}
408
409impl<T> Iterator for VectorIntoIter<T> {
410    type Item = T;
411
412    fn next(&mut self) -> Option<Self::Item> {
413        if self.count > 0 {
414            let ret = self.index[0].pop_front();
415            self.count -= 1;
416            if self.index[0].is_empty() {
417                self.index.remove(0);
418            }
419            ret
420        } else {
421            None
422        }
423    }
424}
425
426/// Basic circular buffer, or what Goodrich and Kloss call a circular deque.
427///
428/// This implementation allows push and pop from both ends of the buffer and
429/// supports insert and remove from arbitrary offsets.
430///
431/// Unlike the `VecDeque` in the standard library, this array has a fixed size
432/// and will panic if a push is performed while the array is already full.
433pub struct CyclicArray<T> {
434    /// allocated buffer of size `capacity`
435    buffer: *mut T,
436    /// number of slots allocated in the buffer
437    capacity: usize,
438    /// offset of the first entry
439    head: usize,
440    /// number of elements
441    count: usize,
442}
443
444impl<T> CyclicArray<T> {
445    /// Construct a new cyclic array with the given capacity.
446    pub fn new(capacity: usize) -> Self {
447        let buffer = if capacity == 0 {
448            std::ptr::null_mut::<T>()
449        } else {
450            let layout = Layout::array::<T>(capacity).expect("unexpected overflow");
451            unsafe {
452                let ptr = alloc(layout).cast::<T>();
453                if ptr.is_null() {
454                    handle_alloc_error(layout);
455                }
456                ptr
457            }
458        };
459        Self {
460            buffer,
461            capacity,
462            head: 0,
463            count: 0,
464        }
465    }
466
467    /// Free the buffer for this cyclic array without dropping the elements.
468    fn dealloc(&mut self) {
469        // apparently this has no effect if capacity is zero
470        let layout = Layout::array::<T>(self.capacity).expect("unexpected overflow");
471        unsafe {
472            dealloc(self.buffer as *mut u8, layout);
473        }
474    }
475
476    /// Take the elements from the two other cyclic arrays into a new cyclic
477    /// array with the combined capacity.
478    pub fn combine(a: CyclicArray<T>, b: CyclicArray<T>) -> Self {
479        let mut this: CyclicArray<T> = CyclicArray::new(a.capacity + b.capacity);
480        let mut this_pos = 0;
481        let their_a = std::mem::ManuallyDrop::new(a);
482        let their_b = std::mem::ManuallyDrop::new(b);
483        for mut other in [their_a, their_b] {
484            if other.head + other.count > other.capacity {
485                // data wraps around, copy as two blocks
486                let src = unsafe { other.buffer.add(other.head) };
487                let dst = unsafe { this.buffer.add(this_pos) };
488                let count_1 = other.capacity - other.head;
489                unsafe { std::ptr::copy(src, dst, count_1) }
490                this_pos += count_1;
491                let dst = unsafe { this.buffer.add(this_pos) };
492                let count_2 = other.count - count_1;
493                unsafe { std::ptr::copy(other.buffer, dst, count_2) }
494                this_pos += count_2;
495            } else {
496                // data is contiguous, copy as one block
497                let src = unsafe { other.buffer.add(other.head) };
498                let dst = unsafe { this.buffer.add(this_pos) };
499                unsafe { std::ptr::copy(src, dst, other.count) }
500                this_pos += other.count;
501            }
502            other.dealloc();
503            this.count += other.count;
504        }
505        this
506    }
507
508    /// Take the elements from the other cyclic array into a new cyclic array
509    /// with the given capacity.
510    pub fn from(capacity: usize, other: CyclicArray<T>) -> Self {
511        assert!(capacity > other.count, "capacity cannot be less than count");
512        let layout = Layout::array::<T>(capacity).expect("unexpected overflow");
513        let buffer = unsafe {
514            let ptr = alloc(layout).cast::<T>();
515            if ptr.is_null() {
516                handle_alloc_error(layout);
517            }
518            ptr
519        };
520        let mut them = std::mem::ManuallyDrop::new(other);
521        if them.head + them.count > them.capacity {
522            // data wraps around, copy as two blocks
523            let src = unsafe { them.buffer.add(them.head) };
524            let count_1 = them.capacity - them.head;
525            unsafe { std::ptr::copy(src, buffer, count_1) }
526            let dst = unsafe { buffer.add(count_1) };
527            let count_2 = them.count - count_1;
528            unsafe { std::ptr::copy(them.buffer, dst, count_2) }
529        } else {
530            // data is contiguous, copy as one block
531            let src = unsafe { them.buffer.add(them.head) };
532            unsafe { std::ptr::copy(src, buffer, them.count) }
533        }
534        them.dealloc();
535        Self {
536            buffer,
537            capacity,
538            head: 0,
539            count: them.count,
540        }
541    }
542
543    /// Split this cyclic buffer into two equal sized buffers.
544    ///
545    /// The second buffer may be empty if all elements fit within the first
546    /// buffer.
547    pub fn split(self) -> (CyclicArray<T>, CyclicArray<T>) {
548        assert!(
549            self.capacity.is_multiple_of(2),
550            "capacity must be an even number"
551        );
552        let half = self.capacity / 2;
553        let mut me = std::mem::ManuallyDrop::new(self);
554        let mut a: CyclicArray<T> = CyclicArray::new(half);
555        let mut b: CyclicArray<T> = CyclicArray::new(half);
556        let mut remaining = me.count;
557        for other in [&mut a, &mut b] {
558            let mut other_pos = 0;
559            while remaining > 0 && !other.is_full() {
560                let want_to_copy = if me.head + remaining > me.capacity {
561                    me.capacity - me.head
562                } else {
563                    remaining
564                };
565                let can_fit = other.capacity - other.count;
566                let to_copy = if want_to_copy > can_fit {
567                    can_fit
568                } else {
569                    want_to_copy
570                };
571                let src = unsafe { me.buffer.add(me.head) };
572                let dst = unsafe { other.buffer.add(other_pos) };
573                unsafe { std::ptr::copy(src, dst, to_copy) };
574                other_pos += to_copy;
575                other.count += to_copy;
576                me.head = me.physical_add(to_copy);
577                remaining -= to_copy;
578            }
579        }
580        me.dealloc();
581        (a, b)
582    }
583
584    /// Appends an element to the back of the cyclic array.
585    ///
586    /// # Panic
587    ///
588    /// Panics if the buffer is already full.
589    pub fn push_back(&mut self, value: T) {
590        if self.count == self.capacity {
591            panic!("cyclic array is full")
592        }
593        let off = self.physical_add(self.count);
594        unsafe { std::ptr::write(self.buffer.add(off), value) }
595        self.count += 1;
596    }
597
598    /// Prepends an element to the front of the cyclic array.
599    ///
600    /// # Panic
601    ///
602    /// Panics if the buffer is already full.
603    pub fn push_front(&mut self, value: T) {
604        if self.count == self.capacity {
605            panic!("cyclic array is full")
606        }
607        self.head = self.physical_sub(1);
608        unsafe { std::ptr::write(self.buffer.add(self.head), value) }
609        self.count += 1;
610    }
611
612    /// Removes the last element and returns it, or `None` if the cyclic array
613    /// is empty.
614    pub fn pop_back(&mut self) -> Option<T> {
615        if self.count == 0 {
616            None
617        } else {
618            self.count -= 1;
619            let off = self.physical_add(self.count);
620            unsafe { Some(std::ptr::read(self.buffer.add(off))) }
621        }
622    }
623
624    /// Removes the first element and returns it, or `None` if the cyclic array
625    /// is empty.
626    pub fn pop_front(&mut self) -> Option<T> {
627        if self.count == 0 {
628            None
629        } else {
630            let old_head = self.head;
631            self.head = self.physical_add(1);
632            self.count -= 1;
633            unsafe { Some(std::ptr::read(self.buffer.add(old_head))) }
634        }
635    }
636
637    /// Inserts an element at position `index` within the array, possibly
638    /// shifting some elements to the left or the right as needed.
639    pub fn insert(&mut self, index: usize, value: T) {
640        let len = self.count;
641        if index > len {
642            panic!("insertion index (is {index}) should be <= len (is {len})");
643        }
644        if len == self.capacity {
645            panic!("cyclic array is full")
646        }
647        //
648        // Some free space exists in the array, either on the left, the right,
649        // the middle, at both ends, or the entire array is empty. Regardless,
650        // there are two cases, shift some elements to the left or to the right.
651        //
652        let mut r_prime = self.physical_add(index);
653        if len > 0 && index < len {
654            // need to make space for the new element
655            if self.head == 0 || r_prime < self.head {
656                // Slide all elements in S,sub of rank greater than or equal to
657                // r’ and less than (|S,sub| — r’) mod l to the right by one
658                let src = unsafe { self.buffer.add(r_prime) };
659                let dst = unsafe { self.buffer.add(r_prime + 1) };
660                let count = self.count - index;
661                unsafe { std::ptr::copy(src, dst, count) }
662            } else {
663                // Slide all elements in S,sub of rank less than r’ and greater
664                // than or equal to h,sub to the left by one
665                let src = unsafe { self.buffer.add(self.head) };
666                let count = r_prime - self.head;
667                self.head = self.physical_sub(1);
668                let dst = unsafe { self.buffer.add(self.head) };
669                unsafe { std::ptr::copy(src, dst, count) }
670                r_prime -= 1;
671            }
672        }
673        unsafe { std::ptr::write(self.buffer.add(r_prime), value) }
674        self.count += 1;
675    }
676
677    /// Removes and returns the element at position `index` within the array,
678    /// shifting some elements to the left or to the right.
679    pub fn remove(&mut self, index: usize) -> T {
680        let len = self.count;
681        if index >= len {
682            panic!("removal index (is {index}) should be < len (is {len})");
683        }
684        let r_prime = self.physical_add(index);
685        let ret = unsafe { std::ptr::read(self.buffer.add(r_prime)) };
686        if index < (len - 1) {
687            // need to slide elements to fill the new gap
688            if self.head == 0 || r_prime < self.head {
689                // Slide all elements in S,sub of rank r'+1 to h,sub + |S,sub| to
690                // the left by one
691                let src = unsafe { self.buffer.add(r_prime + 1) };
692                let dst = unsafe { self.buffer.add(r_prime) };
693                let count = self.count - index;
694                unsafe { std::ptr::copy(src, dst, count) }
695            } else {
696                // Slide all elements in S,sub of rank greater than or equal to
697                // h,sub and less than r' to the right by one
698                let src = unsafe { self.buffer.add(self.head) };
699                let count = r_prime - self.head;
700                self.head = self.physical_add(1);
701                let dst = unsafe { self.buffer.add(self.head) };
702                unsafe { std::ptr::copy(src, dst, count) }
703            }
704        }
705        self.count -= 1;
706        ret
707    }
708
709    /// Provides a reference to the element at the given index.
710    pub fn get(&self, index: usize) -> Option<&T> {
711        if index < self.count {
712            let idx = self.physical_add(index);
713            unsafe { Some(&*self.buffer.add(idx)) }
714        } else {
715            None
716        }
717    }
718
719    /// Returns a mutable reference to an element.
720    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
721        if index < self.count {
722            let idx = self.physical_add(index);
723            unsafe { (self.buffer.add(idx)).as_mut() }
724        } else {
725            None
726        }
727    }
728
729    /// Clears the cyclic array, removing and dropping all values.
730    pub fn clear(&mut self) {
731        use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
732
733        if self.count > 0 && std::mem::needs_drop::<T>() {
734            let first_slot = self.physical_add(0);
735            let last_slot = self.physical_add(self.count);
736            if first_slot < last_slot {
737                // elements are in one contiguous block
738                unsafe {
739                    drop_in_place(slice_from_raw_parts_mut(
740                        self.buffer.add(first_slot),
741                        last_slot - first_slot,
742                    ));
743                }
744            } else {
745                // elements wrap around the end of the buffer
746                unsafe {
747                    drop_in_place(slice_from_raw_parts_mut(
748                        self.buffer.add(first_slot),
749                        self.capacity - first_slot,
750                    ));
751                    // check if first and last are at the start of the array
752                    if first_slot != last_slot || first_slot != 0 {
753                        drop_in_place(slice_from_raw_parts_mut(self.buffer, last_slot));
754                    }
755                }
756            }
757        }
758        self.head = 0;
759        self.count = 0;
760    }
761
762    /// Return the number of elements in the array.
763    pub fn len(&self) -> usize {
764        self.count
765    }
766
767    /// Returns the total number of elements the cyclic array can hold.
768    pub fn capacity(&self) -> usize {
769        self.capacity
770    }
771
772    /// Returns true if the array has a length of 0.
773    pub fn is_empty(&self) -> bool {
774        self.count == 0
775    }
776
777    /// Returns true if the array has a length equal to its capacity.
778    pub fn is_full(&self) -> bool {
779        self.count == self.capacity
780    }
781
782    /// Perform a wrapping addition relative to the head of the array and
783    /// convert the logical offset to the physical offset within the array.
784    fn physical_add(&self, addend: usize) -> usize {
785        let logical_index = self.head.wrapping_add(addend);
786        if logical_index >= self.capacity {
787            logical_index - self.capacity
788        } else {
789            logical_index
790        }
791    }
792
793    /// Perform a wrapping subtraction relative to the head of the array and
794    /// convert the logical offset to the physical offset within the array.
795    fn physical_sub(&self, subtrahend: usize) -> usize {
796        let logical_index = self
797            .head
798            .wrapping_sub(subtrahend)
799            .wrapping_add(self.capacity);
800        if logical_index >= self.capacity {
801            logical_index - self.capacity
802        } else {
803            logical_index
804        }
805    }
806}
807
808impl<T> Default for CyclicArray<T> {
809    fn default() -> Self {
810        Self::new(0)
811    }
812}
813
814impl<T> fmt::Display for CyclicArray<T> {
815    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
816        write!(
817            f,
818            "CyclicArray(capacity: {}, head: {}, count: {})",
819            self.capacity, self.head, self.count,
820        )
821    }
822}
823
824impl<T> Index<usize> for CyclicArray<T> {
825    type Output = T;
826
827    fn index(&self, index: usize) -> &Self::Output {
828        let Some(item) = self.get(index) else {
829            panic!("index out of bounds: {}", index);
830        };
831        item
832    }
833}
834
835impl<T> IndexMut<usize> for CyclicArray<T> {
836    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
837        let Some(item) = self.get_mut(index) else {
838            panic!("index out of bounds: {}", index);
839        };
840        item
841    }
842}
843
844impl<T> Drop for CyclicArray<T> {
845    fn drop(&mut self) {
846        self.clear();
847        self.dealloc();
848    }
849}
850
851#[cfg(test)]
852mod tests {
853    use super::*;
854
855    #[test]
856    fn test_vector_insert_head() {
857        let mut sut = Vector::<usize>::new();
858        assert!(sut.is_empty());
859        for value in (1..=16).rev() {
860            sut.insert(0, value);
861        }
862        assert!(!sut.is_empty());
863        for (index, value) in (1..=16).enumerate() {
864            assert_eq!(sut[index], value);
865        }
866    }
867
868    #[test]
869    fn test_vector_push_and_clear() {
870        let mut sut = Vector::<usize>::new();
871        assert!(sut.is_empty());
872        for value in 0..64 {
873            sut.push(value);
874        }
875        assert!(!sut.is_empty());
876        assert_eq!(sut.len(), 64);
877        assert_eq!(sut.capacity(), 64);
878        for value in 0..64 {
879            assert_eq!(sut[value], value);
880        }
881        sut.clear();
882        assert!(sut.is_empty());
883        assert_eq!(sut.len(), 0);
884        assert_eq!(sut.capacity(), 0);
885    }
886
887    #[test]
888    fn test_vector_get_mut() {
889        let mut sut = Vector::<usize>::new();
890        for value in 0..4 {
891            sut.push(value);
892        }
893        if let Some(value) = sut.get_mut(1) {
894            *value = 11;
895        } else {
896            panic!("get_mut() returned None")
897        }
898        sut[2] = 12;
899        assert_eq!(sut.len(), 4);
900        assert_eq!(sut[0], 0);
901        assert_eq!(sut[1], 11);
902        assert_eq!(sut[2], 12);
903        assert_eq!(sut[3], 3);
904    }
905
906    #[test]
907    fn test_vector_insert_expand() {
908        let mut sut = Vector::<usize>::new();
909        assert!(sut.is_empty());
910        for value in (1..=130).rev() {
911            sut.insert(0, value);
912        }
913        assert!(!sut.is_empty());
914        assert_eq!(sut.len(), 130);
915        assert_eq!(sut.capacity(), 144);
916        for value in 0..130 {
917            assert_eq!(sut[value], value + 1);
918        }
919    }
920
921    #[test]
922    fn test_vector_push_many() {
923        let mut sut = Vector::<usize>::new();
924        assert!(sut.is_empty());
925        for value in 0..100_000 {
926            sut.push(value);
927        }
928        assert!(!sut.is_empty());
929        assert_eq!(sut.len(), 100_000);
930        assert_eq!(sut.capacity(), 100352);
931        for value in 0..100_000 {
932            assert_eq!(sut[value], value);
933        }
934    }
935
936    #[test]
937    fn test_vector_push_within_capacity() {
938        // empty array has no allocated space
939        let mut sut = Vector::<u32>::new();
940        assert_eq!(sut.push_within_capacity(101), Err(101));
941        sut.push(1);
942        sut.push(2);
943        assert_eq!(sut.push_within_capacity(3), Ok(()));
944        assert_eq!(sut.push_within_capacity(4), Ok(()));
945        assert_eq!(sut.push_within_capacity(5), Err(5));
946    }
947
948    #[test]
949    fn test_vector_remove_small() {
950        let mut sut = Vector::<usize>::new();
951        assert!(sut.is_empty());
952        assert_eq!(sut.len(), 0);
953        for value in 0..15 {
954            sut.push(value);
955        }
956        assert!(!sut.is_empty());
957        assert_eq!(sut.len(), 15);
958        for value in 0..15 {
959            assert_eq!(sut.remove(0), value);
960        }
961        assert!(sut.is_empty());
962        assert_eq!(sut.len(), 0);
963        assert_eq!(sut.capacity(), 0);
964    }
965
966    #[test]
967    fn test_vector_remove_medium() {
968        let mut sut = Vector::<usize>::new();
969        assert!(sut.is_empty());
970        assert_eq!(sut.len(), 0);
971        assert_eq!(sut.capacity(), 0);
972        for value in 0..2048 {
973            sut.push(value);
974        }
975        assert!(!sut.is_empty());
976        assert_eq!(sut.len(), 2048);
977        assert_eq!(sut.capacity(), 2048);
978        for value in 0..2048 {
979            assert_eq!(sut.remove(0), value);
980        }
981        assert!(sut.is_empty());
982        assert_eq!(sut.len(), 0);
983        assert_eq!(sut.capacity(), 0);
984    }
985
986    #[test]
987    fn test_vector_pop_small() {
988        let mut sut = Vector::<usize>::new();
989        assert!(sut.is_empty());
990        assert_eq!(sut.len(), 0);
991        for value in 0..15 {
992            sut.push(value);
993        }
994        assert!(!sut.is_empty());
995        assert_eq!(sut.len(), 15);
996        for value in (0..15).rev() {
997            assert_eq!(sut.pop(), Some(value));
998        }
999        assert!(sut.is_empty());
1000        assert_eq!(sut.len(), 0);
1001        assert_eq!(sut.capacity(), 0);
1002    }
1003
1004    #[test]
1005    fn test_vector_pop_if() {
1006        let mut sut = Vector::<u32>::new();
1007        assert!(sut.pop_if(|_| panic!("should not be called")).is_none());
1008        for value in 0..10 {
1009            sut.push(value);
1010        }
1011        assert!(sut.pop_if(|_| false).is_none());
1012        let maybe = sut.pop_if(|v| *v == 9);
1013        assert_eq!(maybe.unwrap(), 9);
1014        assert!(sut.pop_if(|v| *v == 9).is_none());
1015    }
1016
1017    #[test]
1018    fn test_vector_iter() {
1019        let mut sut = Vector::<usize>::new();
1020        for value in 0..1000 {
1021            sut.push(value);
1022        }
1023        assert_eq!(sut.len(), 1000);
1024        for (index, value) in sut.iter().enumerate() {
1025            assert_eq!(sut[index], *value);
1026        }
1027    }
1028
1029    #[test]
1030    fn test_vector_from_iterator() {
1031        let mut inputs: Vec<i32> = Vec::new();
1032        for value in 0..10_000 {
1033            inputs.push(value);
1034        }
1035        let sut: Vector<i32> = inputs.into_iter().collect();
1036        assert_eq!(sut.len(), 10_000);
1037        for idx in 0..10_000i32 {
1038            let maybe = sut.get(idx as usize);
1039            assert!(maybe.is_some(), "{idx} is none");
1040            let actual = maybe.unwrap();
1041            assert_eq!(idx, *actual);
1042        }
1043    }
1044
1045    #[test]
1046    fn test_vector_into_iterator_ints_done() {
1047        let mut sut = Vector::<usize>::new();
1048        for value in 0..1024 {
1049            sut.push(value);
1050        }
1051        for (idx, elem) in sut.into_iter().enumerate() {
1052            assert_eq!(idx, elem);
1053        }
1054        // sut.len(); // error: ownership of sut was moved
1055    }
1056
1057    #[test]
1058    fn test_vector_remove_insert_basic() {
1059        let mut sut = Vector::<usize>::new();
1060        for value in 1..=16 {
1061            sut.push(value);
1062        }
1063        let value = sut.remove(3);
1064        sut.insert(7, value);
1065        let mut sorted: Vec<usize> = sut.into_iter().collect();
1066        sorted.sort();
1067        for (index, value) in (1..=16).enumerate() {
1068            assert_eq!(sorted[index], value);
1069        }
1070    }
1071
1072    #[test]
1073    fn test_vector_random_insert_remove() {
1074        // trade-off of exhaustive randomized testing and running time
1075        let mut sut = Vector::<usize>::new();
1076        let size = 100_000;
1077        for value in 1..=size {
1078            sut.push(value);
1079        }
1080        for _ in 0..200_000 {
1081            let from = rand::random_range(0..size);
1082            let to = rand::random_range(0..size - 1);
1083            let value = sut.remove(from);
1084            sut.insert(to, value);
1085        }
1086        let mut sorted: Vec<usize> = sut.into_iter().collect();
1087        sorted.sort();
1088        for (idx, value) in (1..=size).enumerate() {
1089            assert_eq!(sorted[idx], value);
1090        }
1091    }
1092
1093    #[test]
1094    fn test_vector_push_pop_strings() {
1095        let mut array: Vector<String> = Vector::new();
1096        for _ in 0..1024 {
1097            let value = ulid::Ulid::new().to_string();
1098            array.push(value);
1099        }
1100        assert_eq!(array.len(), 1024);
1101        while let Some(s) = array.pop() {
1102            assert!(!s.is_empty());
1103        }
1104    }
1105
1106    #[test]
1107    fn test_cyclic_array_zero_capacity() {
1108        let sut = CyclicArray::<usize>::new(0);
1109        assert_eq!(sut.len(), 0);
1110        assert_eq!(sut.capacity(), 0);
1111        assert!(sut.is_empty());
1112        assert!(sut.is_full());
1113    }
1114
1115    #[test]
1116    #[should_panic(expected = "cyclic array is full")]
1117    fn test_cyclic_array_zero_push_panics() {
1118        let mut sut = CyclicArray::<usize>::new(0);
1119        sut.push_back(101);
1120    }
1121
1122    #[test]
1123    fn test_cyclic_array_forward() {
1124        let mut sut = CyclicArray::<usize>::new(10);
1125        assert_eq!(sut.len(), 0);
1126        assert_eq!(sut.capacity(), 10);
1127        assert!(sut.is_empty());
1128        assert!(!sut.is_full());
1129
1130        // add until full
1131        for value in 0..sut.capacity() {
1132            sut.push_back(value);
1133        }
1134        assert_eq!(sut.len(), 10);
1135        assert_eq!(sut.capacity(), 10);
1136        assert!(!sut.is_empty());
1137        assert!(sut.is_full());
1138
1139        assert_eq!(sut.get(1), Some(&1));
1140        assert_eq!(sut[1], 1);
1141        assert_eq!(sut.get(3), Some(&3));
1142        assert_eq!(sut[3], 3);
1143        assert_eq!(sut.get(6), Some(&6));
1144        assert_eq!(sut[6], 6);
1145        assert_eq!(sut.get(9), Some(&9));
1146        assert_eq!(sut[9], 9);
1147        assert_eq!(sut.get(10), None);
1148
1149        // remove until empty
1150        for index in 0..10 {
1151            let maybe = sut.pop_front();
1152            assert!(maybe.is_some());
1153            let value = maybe.unwrap();
1154            assert_eq!(value, index);
1155        }
1156        assert_eq!(sut.len(), 0);
1157        assert_eq!(sut.capacity(), 10);
1158        assert!(sut.is_empty());
1159        assert!(!sut.is_full());
1160    }
1161
1162    #[test]
1163    fn test_cyclic_array_backward() {
1164        let mut sut = CyclicArray::<usize>::new(10);
1165        assert_eq!(sut.len(), 0);
1166        assert_eq!(sut.capacity(), 10);
1167        assert!(sut.is_empty());
1168        assert!(!sut.is_full());
1169
1170        // add until full
1171        for value in 0..sut.capacity() {
1172            sut.push_front(value);
1173        }
1174        assert_eq!(sut.len(), 10);
1175        assert_eq!(sut.capacity(), 10);
1176        assert!(!sut.is_empty());
1177        assert!(sut.is_full());
1178
1179        // everything is backwards
1180        assert_eq!(sut.get(1), Some(&8));
1181        assert_eq!(sut[1], 8);
1182        assert_eq!(sut.get(3), Some(&6));
1183        assert_eq!(sut[3], 6);
1184        assert_eq!(sut.get(6), Some(&3));
1185        assert_eq!(sut[6], 3);
1186        assert_eq!(sut.get(9), Some(&0));
1187        assert_eq!(sut[9], 0);
1188        assert_eq!(sut.get(10), None);
1189
1190        // remove until empty
1191        for index in 0..10 {
1192            let maybe = sut.pop_back();
1193            assert!(maybe.is_some());
1194            let value = maybe.unwrap();
1195            assert_eq!(value, index);
1196        }
1197        assert_eq!(sut.len(), 0);
1198        assert_eq!(sut.capacity(), 10);
1199        assert!(sut.is_empty());
1200        assert!(!sut.is_full());
1201    }
1202
1203    #[test]
1204    #[should_panic(expected = "index out of bounds:")]
1205    fn test_cyclic_array_index_out_of_bounds() {
1206        let mut sut = CyclicArray::<usize>::new(10);
1207        sut.push_back(10);
1208        sut.push_back(20);
1209        let _ = sut[2];
1210    }
1211
1212    #[test]
1213    fn test_cyclic_array_clear_and_reuse() {
1214        let mut sut = CyclicArray::<String>::new(10);
1215        for _ in 0..7 {
1216            let value = ulid::Ulid::new().to_string();
1217            sut.push_back(value);
1218        }
1219        sut.clear();
1220        for _ in 0..7 {
1221            let value = ulid::Ulid::new().to_string();
1222            sut.push_back(value);
1223        }
1224        sut.clear();
1225        for _ in 0..7 {
1226            let value = ulid::Ulid::new().to_string();
1227            sut.push_back(value);
1228        }
1229        sut.clear();
1230    }
1231
1232    #[test]
1233    fn test_cyclic_array_drop_partial() {
1234        let mut sut = CyclicArray::<String>::new(10);
1235        for _ in 0..7 {
1236            let value = ulid::Ulid::new().to_string();
1237            sut.push_back(value);
1238        }
1239        drop(sut);
1240    }
1241
1242    #[test]
1243    fn test_cyclic_array_drop_full() {
1244        let mut sut = CyclicArray::<String>::new(10);
1245        for _ in 0..sut.capacity() {
1246            let value = ulid::Ulid::new().to_string();
1247            sut.push_back(value);
1248        }
1249        drop(sut);
1250    }
1251
1252    #[test]
1253    fn test_cyclic_array_drop_wrapped() {
1254        let mut sut = CyclicArray::<String>::new(10);
1255        // push enough to almost fill the buffer
1256        for _ in 0..7 {
1257            let value = ulid::Ulid::new().to_string();
1258            sut.push_back(value);
1259        }
1260        // empty the buffer
1261        while !sut.is_empty() {
1262            sut.pop_front();
1263        }
1264        // push enough to wrap around to the start of the physical buffer
1265        for _ in 0..7 {
1266            let value = ulid::Ulid::new().to_string();
1267            sut.push_back(value);
1268        }
1269        drop(sut);
1270    }
1271
1272    #[test]
1273    #[should_panic(expected = "cyclic array is full")]
1274    fn test_cyclic_array_full_panic() {
1275        let mut sut = CyclicArray::<usize>::new(1);
1276        sut.push_back(10);
1277        sut.push_back(20);
1278    }
1279
1280    #[test]
1281    fn test_cyclic_array_wrapping() {
1282        let mut sut = CyclicArray::<usize>::new(10);
1283        // push enough to almost fill the buffer
1284        for value in 0..7 {
1285            sut.push_back(value);
1286        }
1287        // empty the buffer
1288        while !sut.is_empty() {
1289            sut.pop_front();
1290        }
1291        // push enough to wrap around to the start of the physical buffer
1292        for value in 0..7 {
1293            sut.push_back(value);
1294        }
1295
1296        assert_eq!(sut.get(1), Some(&1));
1297        assert_eq!(sut[1], 1);
1298        assert_eq!(sut.get(3), Some(&3));
1299        assert_eq!(sut[3], 3);
1300        assert_eq!(sut.get(6), Some(&6));
1301        assert_eq!(sut[6], 6);
1302        assert_eq!(sut.get(8), None);
1303
1304        // ensure values are removed correctly
1305        for value in 0..7 {
1306            assert_eq!(sut.pop_front(), Some(value));
1307        }
1308        assert_eq!(sut.len(), 0);
1309        assert_eq!(sut.capacity(), 10);
1310        assert!(sut.is_empty());
1311        assert!(!sut.is_full());
1312    }
1313
1314    #[test]
1315    fn test_cyclic_array_random_insert_remove() {
1316        let size = 1024;
1317        let mut sut = CyclicArray::<usize>::new(size);
1318        for value in 1..=size {
1319            sut.push_back(value);
1320        }
1321        for _ in 0..4096 {
1322            let from = rand::random_range(0..size);
1323            let to = rand::random_range(0..size - 1);
1324            let value = sut.remove(from);
1325            sut.insert(to, value);
1326        }
1327        let mut sorted: Vec<usize> = vec![];
1328        while let Some(value) = sut.pop_front() {
1329            sorted.push(value);
1330        }
1331        sorted.sort();
1332        for (idx, value) in (1..=size).enumerate() {
1333            assert_eq!(sorted[idx], value);
1334        }
1335    }
1336
1337    #[test]
1338    fn test_cyclic_array_insert_head() {
1339        let mut sut = CyclicArray::<usize>::new(4);
1340        sut.insert(0, 4);
1341        sut.insert(0, 3);
1342        sut.insert(0, 2);
1343        sut.insert(0, 1);
1344        assert_eq!(sut.len(), 4);
1345        assert_eq!(sut[0], 1);
1346        assert_eq!(sut[1], 2);
1347        assert_eq!(sut[2], 3);
1348        assert_eq!(sut[3], 4);
1349    }
1350
1351    #[test]
1352    fn test_cyclic_array_insert_empty() {
1353        let mut sut = CyclicArray::<usize>::new(4);
1354        // start with:
1355        // ```
1356        // +---+---+---+---+
1357        // |   |   |   |   |
1358        // +---+---+---+---+
1359        // ```
1360        // becomes:
1361        // ```
1362        // +---+---+---+---+
1363        // | 1 |   |   |   |
1364        // +---+---+---+---+
1365        // ```
1366        sut.insert(0, 1);
1367        assert_eq!(sut[0], 1);
1368        assert_eq!(sut.len(), 1);
1369    }
1370
1371    #[test]
1372    fn test_cyclic_array_insert_empty_head_not_zero() {
1373        let mut sut = CyclicArray::<usize>::new(4);
1374        sut.push_back(1);
1375        sut.push_back(2);
1376        sut.pop_front();
1377        sut.pop_front();
1378        sut.insert(0, 1);
1379        assert_eq!(sut[0], 1);
1380        assert_eq!(sut.len(), 1);
1381    }
1382
1383    #[test]
1384    fn test_cyclic_array_insert_loop() {
1385        let mut sut = CyclicArray::<usize>::new(4);
1386        for value in 0..100 {
1387            sut.insert(0, value);
1388            sut.insert(0, value);
1389            sut.insert(0, value);
1390            sut.pop_front();
1391            sut.pop_front();
1392            sut.pop_front();
1393        }
1394        assert_eq!(sut.len(), 0);
1395        sut.push_back(1);
1396        sut.push_back(2);
1397        sut.push_back(3);
1398        sut.push_back(4);
1399        assert_eq!(sut.len(), 4);
1400        assert_eq!(sut[0], 1);
1401        assert_eq!(sut[1], 2);
1402        assert_eq!(sut[2], 3);
1403        assert_eq!(sut[3], 4);
1404    }
1405
1406    #[test]
1407    fn test_cyclic_array_insert_1() {
1408        let mut sut = CyclicArray::<usize>::new(4);
1409        // start with:
1410        // ```
1411        // +---+---+---+---+
1412        // | 1 | 2 |   |   |
1413        // +---+---+---+---+
1414        // ```
1415        // becomes:
1416        // ```
1417        // +---+---+---+---+
1418        // | 1 | 3 | 2 |   |
1419        // +---+---+---+---+
1420        // ```
1421        sut.push_back(1);
1422        sut.push_back(2);
1423        sut.insert(1, 3);
1424        assert_eq!(sut.len(), 3);
1425        assert_eq!(sut[0], 1);
1426        assert_eq!(sut[1], 3);
1427        assert_eq!(sut[2], 2);
1428    }
1429
1430    #[test]
1431    fn test_cyclic_array_insert_2() {
1432        let mut sut = CyclicArray::<usize>::new(4);
1433        // start with:
1434        // ```
1435        // +---+---+---+---+
1436        // | 2 |   |   | 1 |
1437        // +---+---+---+---+
1438        // ```
1439        // becomes:
1440        // ```
1441        // +---+---+---+---+
1442        // | 3 | 2 |   | 1 |
1443        // +---+---+---+---+
1444        // ```
1445        sut.push_back(1);
1446        sut.push_back(1);
1447        sut.push_back(1);
1448        sut.push_back(1);
1449        sut.pop_front();
1450        sut.pop_front();
1451        sut.pop_front();
1452        sut.push_back(2);
1453        sut.insert(1, 3);
1454        assert_eq!(sut.len(), 3);
1455        assert_eq!(sut[0], 1);
1456        assert_eq!(sut[1], 3);
1457        assert_eq!(sut[2], 2);
1458    }
1459
1460    #[test]
1461    fn test_cyclic_array_insert_3() {
1462        let mut sut = CyclicArray::<usize>::new(4);
1463        // start with:
1464        // ```
1465        // +---+---+---+---+
1466        // |   |   | 1 | 2 |
1467        // +---+---+---+---+
1468        // ```
1469        // becomes:
1470        // ```
1471        // +---+---+---+---+
1472        // |   | 1 | 3 | 2 |
1473        // +---+---+---+---+
1474        // ```
1475        sut.push_back(1);
1476        sut.push_back(1);
1477        sut.push_back(1);
1478        sut.push_back(2);
1479        sut.pop_front();
1480        sut.pop_front();
1481        sut.insert(1, 3);
1482        assert_eq!(sut.len(), 3);
1483        assert_eq!(sut[0], 1);
1484        assert_eq!(sut[1], 3);
1485        assert_eq!(sut[2], 2);
1486    }
1487
1488    #[test]
1489    fn test_cyclic_array_insert_4() {
1490        let mut sut = CyclicArray::<usize>::new(4);
1491        // start with:
1492        // ```
1493        // +---+---+---+---+
1494        // | 2 |   |   | 1 |
1495        // +---+---+---+---+
1496        // ```
1497        // becomes:
1498        // ```
1499        // +---+---+---+---+
1500        // | 2 |   | 3 | 1 |
1501        // +---+---+---+---+
1502        // ```
1503        sut.push_back(1);
1504        sut.push_back(1);
1505        sut.push_back(1);
1506        sut.push_back(1);
1507        sut.pop_front();
1508        sut.pop_front();
1509        sut.pop_front();
1510        sut.push_back(2);
1511        sut.insert(0, 3);
1512        assert_eq!(sut.len(), 3);
1513        assert_eq!(sut[0], 3);
1514        assert_eq!(sut[1], 1);
1515        assert_eq!(sut[2], 2);
1516    }
1517
1518    #[test]
1519    fn test_cyclic_array_insert_start() {
1520        let mut sut = CyclicArray::<usize>::new(4);
1521        // start with:
1522        // ```
1523        // +---+---+---+---+
1524        // | 1 | 2 |   |   |
1525        // +---+---+---+---+
1526        // ```
1527        // becomes:
1528        // ```
1529        // +---+---+---+---+
1530        // | 3 | 1 | 2 |   |
1531        // +---+---+---+---+
1532        // ```
1533        sut.push_back(1);
1534        sut.push_back(2);
1535        sut.insert(0, 3);
1536        assert_eq!(sut.len(), 3);
1537        assert_eq!(sut[0], 3);
1538        assert_eq!(sut[1], 1);
1539        assert_eq!(sut[2], 2);
1540    }
1541
1542    #[test]
1543    fn test_cyclic_array_insert_end() {
1544        let mut sut = CyclicArray::<usize>::new(4);
1545        // start with:
1546        // ```
1547        // +---+---+---+---+
1548        // | 1 | 2 |   |   |
1549        // +---+---+---+---+
1550        // ```
1551        // becomes:
1552        // ```
1553        // +---+---+---+---+
1554        // | 1 | 2 | 3 |   |
1555        // +---+---+---+---+
1556        // ```
1557        sut.push_back(1);
1558        sut.push_back(2);
1559        sut.insert(2, 3);
1560        assert_eq!(sut.len(), 3);
1561        assert_eq!(sut[0], 1);
1562        assert_eq!(sut[1], 2);
1563        assert_eq!(sut[2], 3);
1564    }
1565
1566    #[test]
1567    fn test_cyclic_array_insert_end_wrap() {
1568        let mut sut = CyclicArray::<usize>::new(4);
1569        // start with:
1570        // ```
1571        // +---+-V-+---+---+
1572        // |   | 2 | 3 | 4 |
1573        // +---+---+---+---+
1574        // ```
1575        // becomes:
1576        // ```
1577        // +---+-V-+---+---+
1578        // | 1 | 2 | 3 | 4 |
1579        // +---+---+---+---+
1580        // ```
1581        sut.push_back(1);
1582        sut.push_back(2);
1583        sut.push_back(3);
1584        sut.push_back(4);
1585        sut.pop_front();
1586        sut.insert(3, 1);
1587        assert_eq!(sut.len(), 4);
1588        assert_eq!(sut[0], 2);
1589        assert_eq!(sut[1], 3);
1590        assert_eq!(sut[2], 4);
1591        assert_eq!(sut[3], 1);
1592    }
1593
1594    #[test]
1595    #[should_panic(expected = "cyclic array is full")]
1596    fn test_cyclic_array_insert_full_panic() {
1597        let mut sut = CyclicArray::<usize>::new(1);
1598        sut.push_back(10);
1599        sut.insert(0, 20);
1600    }
1601
1602    #[test]
1603    #[should_panic(expected = "insertion index (is 2) should be <= len (is 0)")]
1604    fn test_cyclic_array_insert_bounds_panic() {
1605        let mut sut = CyclicArray::<usize>::new(1);
1606        sut.insert(2, 20);
1607    }
1608
1609    #[test]
1610    fn test_cyclic_array_remove_start() {
1611        let mut sut = CyclicArray::<usize>::new(4);
1612        // start with:
1613        // ```
1614        // +---+---+---+---+
1615        // | 1 | 2 | 3 |   |
1616        // +---+---+---+---+
1617        // ```
1618        // becomes:
1619        // ```
1620        // +---+---+---+---+
1621        // | 2 | 3 |   |   |
1622        // +---+---+---+---+
1623        // ```
1624        sut.push_back(1);
1625        sut.push_back(2);
1626        sut.push_back(3);
1627        sut.remove(0);
1628        assert_eq!(sut.len(), 2);
1629        assert_eq!(sut[0], 2);
1630        assert_eq!(sut[1], 3);
1631    }
1632
1633    #[test]
1634    fn test_cyclic_array_remove_1() {
1635        let mut sut = CyclicArray::<usize>::new(4);
1636        // start with:
1637        // ```
1638        // +---+---+---+---+
1639        // |   | 1 | 2 | 3 |
1640        // +---+---+---+---+
1641        // ```
1642        // becomes:
1643        // ```
1644        // +---+---+---+---+
1645        // |   |   | 1 | 3 |
1646        // +---+---+---+---+
1647        // ```
1648        sut.push_back(1);
1649        sut.push_back(1);
1650        sut.push_back(2);
1651        sut.push_back(3);
1652        sut.pop_front();
1653        sut.remove(1);
1654        assert_eq!(sut.len(), 2);
1655        assert_eq!(sut[0], 1);
1656        assert_eq!(sut[1], 3);
1657    }
1658
1659    #[test]
1660    fn test_cyclic_array_remove_2() {
1661        let mut sut = CyclicArray::<usize>::new(4);
1662        // start with:
1663        // ```
1664        // +---+---+---+---+
1665        // |   | 1 | 2 | 3 |
1666        // +---+---+---+---+
1667        // ```
1668        // becomes:
1669        // ```
1670        // +---+---+---+---+
1671        // |   |   | 2 | 3 |
1672        // +---+---+---+---+
1673        // ```
1674        sut.push_back(1);
1675        sut.push_back(1);
1676        sut.push_back(2);
1677        sut.push_back(3);
1678        sut.pop_front();
1679        sut.remove(0);
1680        assert_eq!(sut.len(), 2);
1681        assert_eq!(sut[0], 2);
1682        assert_eq!(sut[1], 3);
1683    }
1684
1685    #[test]
1686    fn test_cyclic_array_remove_3() {
1687        let mut sut = CyclicArray::<usize>::new(4);
1688        // start with:
1689        // ```
1690        // +---+---+---+---+
1691        // | 2 | 3 |   | 1 |
1692        // +---+---+---+---+
1693        // ```
1694        // becomes:
1695        // ```
1696        // +---+---+---+---+
1697        // | 3 |   |   | 1 |
1698        // +---+---+---+---+
1699        // ```
1700        sut.push_back(1);
1701        sut.push_back(1);
1702        sut.push_back(1);
1703        sut.push_back(1);
1704        sut.pop_front();
1705        sut.pop_front();
1706        sut.pop_front();
1707        sut.push_back(2);
1708        sut.push_back(3);
1709        sut.remove(1);
1710        assert_eq!(sut.len(), 2);
1711        assert_eq!(sut[0], 1);
1712        assert_eq!(sut[1], 3);
1713    }
1714
1715    #[test]
1716    fn test_cyclic_array_remove_end() {
1717        let mut sut = CyclicArray::<usize>::new(4);
1718        // start with:
1719        // ```
1720        // +---+---+---+---+
1721        // | 1 | 2 | 3 |   |
1722        // +---+---+---+---+
1723        // ```
1724        // becomes:
1725        // ```
1726        // +---+---+---+---+
1727        // | 1 | 2 |   |   |
1728        // +---+---+---+---+
1729        // ```
1730        sut.push_back(1);
1731        sut.push_back(2);
1732        sut.push_back(3);
1733        sut.remove(2);
1734        assert_eq!(sut.len(), 2);
1735        assert_eq!(sut[0], 1);
1736        assert_eq!(sut[1], 2);
1737    }
1738
1739    #[test]
1740    fn test_cyclic_array_remove_end_wrap() {
1741        let mut sut = CyclicArray::<usize>::new(4);
1742        // start with:
1743        // ```
1744        // +---+-V-+---+---+
1745        // | 5 | 2 | 3 | 4 |
1746        // +---+---+---+---+
1747        // ```
1748        // becomes:
1749        // ```
1750        // +---+-V-+---+---+
1751        // |   | 2 | 3 | 4 |
1752        // +---+---+---+---+
1753        // ```
1754        sut.push_back(1);
1755        sut.push_back(2);
1756        sut.push_back(3);
1757        sut.push_back(4);
1758        sut.pop_front();
1759        sut.push_back(5);
1760        assert_eq!(sut.len(), 4);
1761        assert_eq!(sut[0], 2);
1762        assert_eq!(sut[1], 3);
1763        assert_eq!(sut[2], 4);
1764        assert_eq!(sut[3], 5);
1765        sut.remove(3);
1766        assert_eq!(sut.len(), 3);
1767        assert_eq!(sut[0], 2);
1768        assert_eq!(sut[1], 3);
1769        assert_eq!(sut[2], 4);
1770    }
1771
1772    #[test]
1773    fn test_cyclic_array_push_pop_remove() {
1774        let mut sut = CyclicArray::<usize>::new(4);
1775        sut.push_back(7);
1776        sut.push_back(7);
1777        sut.push_back(7);
1778        sut.push_back(8);
1779        sut.pop_front();
1780        sut.pop_front();
1781        sut.push_back(10);
1782        sut.push_back(11);
1783        sut.remove(2);
1784        assert_eq!(sut.len(), 3);
1785        assert_eq!(sut[0], 7);
1786        assert_eq!(sut[1], 8);
1787        assert_eq!(sut[2], 11);
1788    }
1789
1790    #[test]
1791    fn test_cyclic_array_push_pop_insert() {
1792        let mut sut = CyclicArray::<usize>::new(4);
1793        sut.push_back(11);
1794        sut.push_back(11);
1795        sut.push_back(11);
1796        sut.push_back(12);
1797        sut.pop_front();
1798        sut.pop_front();
1799        sut.push_back(4);
1800        sut.insert(2, 3);
1801        assert_eq!(sut.len(), 4);
1802        assert_eq!(sut[0], 11);
1803        assert_eq!(sut[1], 12);
1804        assert_eq!(sut[2], 3);
1805        assert_eq!(sut[3], 4);
1806    }
1807
1808    #[test]
1809    #[should_panic(expected = "removal index (is 2) should be < len (is 0)")]
1810    fn test_cyclic_array_remove_bounds_panic() {
1811        let mut sut = CyclicArray::<usize>::new(1);
1812        sut.remove(2);
1813    }
1814
1815    #[test]
1816    fn test_cyclic_array_from_string() {
1817        let mut sut = CyclicArray::<String>::new(4);
1818        sut.push_back(ulid::Ulid::new().to_string());
1819        sut.push_back(ulid::Ulid::new().to_string());
1820        sut.push_back(ulid::Ulid::new().to_string());
1821        let copy = CyclicArray::<String>::from(8, sut);
1822        assert_eq!(copy.len(), 3);
1823        assert_eq!(copy.capacity(), 8);
1824        assert!(!copy[0].is_empty());
1825        assert!(!copy[1].is_empty());
1826        assert!(!copy[2].is_empty());
1827    }
1828
1829    #[test]
1830    fn test_cyclic_array_from_smaller_1() {
1831        let mut sut = CyclicArray::<usize>::new(4);
1832        sut.push_back(1);
1833        sut.push_back(2);
1834        sut.push_back(3);
1835        let copy = CyclicArray::<usize>::from(8, sut);
1836        assert_eq!(copy.len(), 3);
1837        assert_eq!(copy.capacity(), 8);
1838        assert_eq!(copy[0], 1);
1839        assert_eq!(copy[1], 2);
1840        assert_eq!(copy[2], 3);
1841    }
1842
1843    #[test]
1844    fn test_cyclic_array_from_smaller_2() {
1845        let mut sut = CyclicArray::<usize>::new(4);
1846        sut.push_back(1);
1847        sut.push_back(1);
1848        sut.push_back(1);
1849        sut.push_back(2);
1850        sut.pop_front();
1851        sut.pop_front();
1852        sut.push_back(3);
1853        sut.push_back(4);
1854        let copy = CyclicArray::<usize>::from(8, sut);
1855        assert_eq!(copy.len(), 4);
1856        assert_eq!(copy.capacity(), 8);
1857        assert_eq!(copy[0], 1);
1858        assert_eq!(copy[1], 2);
1859        assert_eq!(copy[2], 3);
1860        assert_eq!(copy[3], 4);
1861    }
1862
1863    #[test]
1864    fn test_cyclic_array_from_larger_1() {
1865        let mut sut = CyclicArray::<usize>::new(8);
1866        sut.push_back(1);
1867        sut.push_back(2);
1868        sut.push_back(3);
1869        let copy = CyclicArray::<usize>::from(4, sut);
1870        assert_eq!(copy.len(), 3);
1871        assert_eq!(copy.capacity(), 4);
1872        assert_eq!(copy[0], 1);
1873        assert_eq!(copy[1], 2);
1874        assert_eq!(copy[2], 3);
1875    }
1876
1877    #[test]
1878    fn test_cyclic_array_from_larger_2() {
1879        let mut sut = CyclicArray::<usize>::new(8);
1880        for _ in 0..7 {
1881            sut.push_back(1);
1882        }
1883        sut.push_back(2);
1884        for _ in 0..6 {
1885            sut.pop_front();
1886        }
1887        sut.push_back(3);
1888        let copy = CyclicArray::<usize>::from(4, sut);
1889        assert_eq!(copy.len(), 3);
1890        assert_eq!(copy.capacity(), 4);
1891        assert_eq!(copy[0], 1);
1892        assert_eq!(copy[1], 2);
1893        assert_eq!(copy[2], 3);
1894    }
1895
1896    #[test]
1897    fn test_cyclic_array_combine_string() {
1898        let mut a = CyclicArray::<String>::new(4);
1899        a.push_back(ulid::Ulid::new().to_string());
1900        a.push_back(ulid::Ulid::new().to_string());
1901        a.push_back(ulid::Ulid::new().to_string());
1902        let mut b = CyclicArray::<String>::new(4);
1903        b.push_back(ulid::Ulid::new().to_string());
1904        b.push_back(ulid::Ulid::new().to_string());
1905        b.push_back(ulid::Ulid::new().to_string());
1906        let sut = CyclicArray::combine(a, b);
1907        assert_eq!(sut.len(), 6);
1908        assert_eq!(sut.capacity(), 8);
1909        for i in 0..6 {
1910            assert!(!sut[i].is_empty());
1911        }
1912    }
1913
1914    #[test]
1915    fn test_cyclic_array_combine_1_1() {
1916        let mut a = CyclicArray::<usize>::new(4);
1917        a.push_back(1);
1918        a.push_back(2);
1919        a.push_back(3);
1920        let mut b = CyclicArray::<usize>::new(4);
1921        b.push_back(4);
1922        b.push_back(5);
1923        b.push_back(6);
1924        let sut = CyclicArray::combine(a, b);
1925        assert_eq!(sut.len(), 6);
1926        assert_eq!(sut.capacity(), 8);
1927        for i in 0..6 {
1928            assert_eq!(sut[i], i + 1);
1929        }
1930    }
1931
1932    #[test]
1933    fn test_cyclic_array_combine_1_2() {
1934        let mut a = CyclicArray::<usize>::new(4);
1935        a.push_back(1);
1936        a.push_back(2);
1937        a.push_back(3);
1938        let mut b = CyclicArray::<usize>::new(4);
1939        b.push_back(4);
1940        b.push_back(4);
1941        b.push_back(4);
1942        b.push_back(5);
1943        b.pop_front();
1944        b.pop_front();
1945        b.push_back(6);
1946        let sut = CyclicArray::combine(a, b);
1947        assert_eq!(sut.len(), 6);
1948        assert_eq!(sut.capacity(), 8);
1949        for i in 0..6 {
1950            assert_eq!(sut[i], i + 1);
1951        }
1952    }
1953
1954    #[test]
1955    fn test_cyclic_array_combine_2_1() {
1956        let mut a = CyclicArray::<usize>::new(4);
1957        a.push_back(1);
1958        a.push_back(1);
1959        a.push_back(1);
1960        a.push_back(2);
1961        a.pop_front();
1962        a.pop_front();
1963        a.push_back(3);
1964        let mut b = CyclicArray::<usize>::new(4);
1965        b.push_back(4);
1966        b.push_back(5);
1967        b.push_back(6);
1968        let sut = CyclicArray::combine(a, b);
1969        assert_eq!(sut.len(), 6);
1970        assert_eq!(sut.capacity(), 8);
1971        for i in 0..6 {
1972            assert_eq!(sut[i], i + 1);
1973        }
1974    }
1975
1976    #[test]
1977    fn test_cyclic_array_combine_2_2() {
1978        let mut a = CyclicArray::<usize>::new(4);
1979        a.push_back(1);
1980        a.push_back(1);
1981        a.push_back(1);
1982        a.push_back(2);
1983        a.pop_front();
1984        a.pop_front();
1985        a.push_back(3);
1986        let mut b = CyclicArray::<usize>::new(4);
1987        b.push_back(4);
1988        b.push_back(4);
1989        b.push_back(4);
1990        b.push_back(5);
1991        b.pop_front();
1992        b.pop_front();
1993        b.push_back(6);
1994        let sut = CyclicArray::combine(a, b);
1995        assert_eq!(sut.len(), 6);
1996        assert_eq!(sut.capacity(), 8);
1997        for i in 0..6 {
1998            assert_eq!(sut[i], i + 1);
1999        }
2000    }
2001
2002    #[test]
2003    fn test_cyclic_array_split_empty() {
2004        let big = CyclicArray::<usize>::new(8);
2005        let (a, b) = big.split();
2006        assert_eq!(a.len(), 0);
2007        assert_eq!(a.capacity(), 4);
2008        assert_eq!(b.len(), 0);
2009        assert_eq!(b.capacity(), 4);
2010    }
2011
2012    #[test]
2013    fn test_cyclic_array_split_string() {
2014        let mut big = CyclicArray::<String>::new(8);
2015        for _ in 0..8 {
2016            big.push_back(ulid::Ulid::new().to_string());
2017        }
2018        let (a, b) = big.split();
2019        assert_eq!(a.len(), 4);
2020        assert_eq!(a.capacity(), 4);
2021        assert!(!a[0].is_empty());
2022        assert!(!a[1].is_empty());
2023        assert!(!a[2].is_empty());
2024        assert!(!a[3].is_empty());
2025        assert_eq!(b.len(), 4);
2026        assert_eq!(b.capacity(), 4);
2027        assert!(!b[0].is_empty());
2028        assert!(!b[1].is_empty());
2029        assert!(!b[2].is_empty());
2030        assert!(!b[3].is_empty());
2031    }
2032
2033    #[test]
2034    fn test_cyclic_array_split_full() {
2035        let mut big = CyclicArray::<usize>::new(8);
2036        for value in 1..=8 {
2037            big.push_back(value);
2038        }
2039        let (a, b) = big.split();
2040        assert_eq!(a.len(), 4);
2041        assert_eq!(a.capacity(), 4);
2042        assert_eq!(a[0], 1);
2043        assert_eq!(a[1], 2);
2044        assert_eq!(a[2], 3);
2045        assert_eq!(a[3], 4);
2046        assert_eq!(b.len(), 4);
2047        assert_eq!(b.capacity(), 4);
2048        assert_eq!(b[0], 5);
2049        assert_eq!(b[1], 6);
2050        assert_eq!(b[2], 7);
2051        assert_eq!(b[3], 8);
2052    }
2053
2054    #[test]
2055    fn test_cyclic_array_split_partial_whole() {
2056        let mut big = CyclicArray::<usize>::new(8);
2057        for value in 1..=6 {
2058            big.push_back(value);
2059        }
2060        let (a, b) = big.split();
2061        assert_eq!(a.len(), 4);
2062        assert_eq!(a.capacity(), 4);
2063        assert_eq!(a[0], 1);
2064        assert_eq!(a[1], 2);
2065        assert_eq!(a[2], 3);
2066        assert_eq!(a[3], 4);
2067        assert_eq!(b.len(), 2);
2068        assert_eq!(b.capacity(), 4);
2069        assert_eq!(b[0], 5);
2070        assert_eq!(b[1], 6);
2071    }
2072
2073    #[test]
2074    fn test_cyclic_array_split_partial_split() {
2075        let mut big = CyclicArray::<usize>::new(8);
2076        for value in 1..=6 {
2077            big.push_back(value);
2078        }
2079        big.pop_front();
2080        big.pop_front();
2081        big.pop_front();
2082        big.push_back(7);
2083        big.push_back(8);
2084        big.push_back(9);
2085        let (a, b) = big.split();
2086        assert_eq!(a.len(), 4);
2087        assert_eq!(a.capacity(), 4);
2088        assert_eq!(a[0], 4);
2089        assert_eq!(a[1], 5);
2090        assert_eq!(a[2], 6);
2091        assert_eq!(a[3], 7);
2092        assert_eq!(b.len(), 2);
2093        assert_eq!(b.capacity(), 4);
2094        assert_eq!(b[0], 8);
2095        assert_eq!(b[1], 9);
2096    }
2097
2098    #[test]
2099    fn test_cyclic_array_get_mut() {
2100        let mut sut = CyclicArray::<usize>::new(4);
2101        sut.push_back(1);
2102        sut.push_back(2);
2103        sut.push_back(3);
2104        sut.push_back(4);
2105        if let Some(value) = sut.get_mut(1) {
2106            *value = 12;
2107        } else {
2108            panic!("get_mut() returned None")
2109        }
2110        sut[2] = 13;
2111        assert_eq!(sut[0], 1);
2112        assert_eq!(sut[1], 12);
2113        assert_eq!(sut[2], 13);
2114        assert_eq!(sut[3], 4);
2115    }
2116}