once/
once.rs

1use core::ops::{Index, IndexMut};
2use std::{
3    cmp::{Eq, PartialEq},
4    collections::BTreeSet,
5    fmt,
6};
7
8use maybe_rayon::prelude::*;
9
10use crate::{
11    grove::Grove,
12    std_or_loom::sync::{
13        Mutex, MutexGuard,
14        atomic::{AtomicUsize, Ordering},
15    },
16};
17
18/// A wrapper around a `BTreeSet` that tracks out-of-order element insertions.
19///
20/// This is an internal implementation detail of [`OnceVec`] that keeps track of
21/// indices where elements have been inserted out of order. It's also used as the
22/// target of the mutex lock to prevent concurrent modifications.
23///
24/// See [`OnceVec`] documentation for more details on how out-of-order insertions work.
25#[derive(Clone, Default)]
26pub struct OooTracker(BTreeSet<usize>);
27
28/// A push-only vector which is thread-safe. To ensure thread-safety, we need to ensure three things
29///
30///  1. Never reallocate, since this would invalidate pointers held by other threads
31///  2. Prevent simultaneous pushes
32///  3. Avoid reading partially written data
33///
34/// To ensure (1), we use a [`Grove`] as the backing data structure.
35///
36/// To ensure (2), we use a mutex to lock when *writing* only. Note that data races are instant UB,
37/// even with `UnsafeCell`. An earlier attempt sought to panic if such a data race is detected with
38/// compare_exchange, but panicking after the fact is too late.
39///
40/// To ensure (3), we store the length of the vector in an `AtomicUsize`. We update this value
41/// *after* writing to the vec, and check the value *before* reading the vec. The invariant to be
42/// maintained is that at any point in time, the values up to `self.len` are always fully written.
43///
44/// # Key Features
45///
46/// - **Thread Safety**: Safe for concurrent reads and writes from multiple threads
47/// - **Out-of-Order Insertion**: Supports inserting elements at arbitrary positions
48/// - **Parallel Extension**: Can be extended in parallel using Rayon (with the `concurrent`
49///   feature)
50///
51/// # Examples
52///
53/// ```
54/// use std::{sync::Arc, thread};
55///
56/// use once::OnceVec;
57///
58/// // Create a shared vector
59/// let vec = Arc::new(OnceVec::<i32>::new());
60///
61/// // Spawn multiple threads to push elements
62/// let mut handles = vec![];
63/// for i in 0..5 {
64///     let vec_clone = Arc::clone(&vec);
65///     let handle = thread::spawn(move || {
66///         vec_clone.push(i);
67///     });
68///     handles.push(handle);
69/// }
70///
71/// // Wait for all threads to complete
72/// for handle in handles {
73///     handle.join().unwrap();
74/// }
75///
76/// // The vector now contains all elements (in some order)
77/// assert_eq!(vec.len(), 5);
78/// ```
79///
80/// # Out-of-Order Insertion
81///
82/// `OnceVec` supports inserting elements at arbitrary positions using `push_ooo`:
83///
84/// ```
85/// use once::OnceVec;
86///
87/// let vec = OnceVec::<i32>::new();
88///
89/// // Insert at position 0
90/// vec.push_ooo(10, 0);
91///
92/// // Insert at position 2 (leaving position 1 empty for now)
93/// vec.push_ooo(30, 2);
94///
95/// // Fill in position 1
96/// vec.push_ooo(20, 1);
97///
98/// assert_eq!(vec[0usize], 10);
99/// assert_eq!(vec[1usize], 20);
100/// assert_eq!(vec[2usize], 30);
101/// ```
102
103#[derive(Default)]
104pub struct OnceVec<T> {
105    len: AtomicUsize,
106    /// [`BTreeSet`] of elements that have been added out of order. We also use this mutex to
107    /// prevent conflicting concurrent pushes. We use a newtype to wrap the [`BTreeSet`] because
108    /// we want [`OnceVec::lock`] to be public, but we don't want to let people mess with the
109    /// internals of the tracker.
110    ooo: Mutex<OooTracker>,
111    data: Grove<T>,
112}
113
114impl<T: Clone> Clone for OnceVec<T> {
115    fn clone(&self) -> Self {
116        let result = Self::new();
117        for v in self.iter() {
118            result.push(v.clone());
119        }
120        result
121    }
122}
123
124impl<T: fmt::Debug> fmt::Debug for OnceVec<T> {
125    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126        write!(f, "[")?;
127        let mut it = self.iter();
128        match it.next() {
129            Some(x) => write!(f, "{x:?}")?,
130            None => {
131                return write!(f, "]");
132            }
133        }
134        for x in it {
135            write!(f, ", {x:?}")?;
136        }
137        write!(f, "]")
138    }
139}
140
141impl<T> PartialEq for OnceVec<T>
142where
143    T: PartialEq,
144{
145    fn eq(&self, other: &Self) -> bool {
146        self.len() == other.len() && self.iter().eq(other.iter())
147    }
148}
149
150impl<T> Eq for OnceVec<T> where T: Eq {}
151
152impl<T> OnceVec<T> {
153    /// Creates a OnceVec from a Vec.
154    ///
155    /// # Example
156    /// ```
157    /// # use once::OnceVec;
158    /// let v = vec![1, 3, 5, 2];
159    /// let w = OnceVec::from_vec(v.clone());
160    /// assert_eq!(w.len(), 4);
161    /// for i in 0..4 {
162    ///     assert_eq!(v[i], w[i]);
163    /// }
164    /// ```
165    pub fn from_vec(vec: Vec<T>) -> Self {
166        let data = Grove::from_vec(vec);
167        let len = data.len();
168        Self {
169            len: AtomicUsize::new(len),
170            ooo: Mutex::new(OooTracker::default()),
171            data,
172        }
173    }
174
175    pub fn new() -> Self {
176        Self {
177            len: AtomicUsize::new(0),
178            ooo: Mutex::new(OooTracker::default()),
179            data: Grove::new(),
180        }
181    }
182
183    /// Returns a list of out-of-order elements remaining.
184    pub fn ooo_elements(&self) -> Vec<usize> {
185        self.ooo.lock().unwrap().0.iter().copied().collect()
186    }
187
188    /// All data up to length self.len() are guaranteed to be fully written *after* reading
189    /// self.len().
190    pub fn len(&self) -> usize {
191        self.len.load(Ordering::Acquire)
192    }
193
194    pub fn is_empty(&self) -> bool {
195        self.len() == 0
196    }
197
198    pub fn get(&self, index: usize) -> Option<&T> {
199        if index < self.len() {
200            // Safety: we know that the data is fully written up to self.len(). We can use that
201            // information to skip all checks and just read the data.
202            Some(unsafe { self.data.get_unchecked(index) })
203        } else {
204            None
205        }
206    }
207
208    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
209        self.data.get_mut(index)
210    }
211
212    pub fn get_or_insert(&self, index: usize, to_insert: impl FnOnce() -> T) -> &T {
213        if let Some(val) = self.get(index) {
214            val
215        } else {
216            self.push_checked(to_insert(), index);
217            self.get(index).unwrap()
218        }
219    }
220
221    pub fn last(&self) -> Option<&T> {
222        if !self.is_empty() {
223            Some(&self[self.len() - 1])
224        } else {
225            None
226        }
227    }
228
229    /// Takes a lock on the `OnceVec`. The `OnceVec` cannot be updated while the lock is held.
230    /// This is useful when used in conjuction with [`OnceVec::extend`];
231    pub fn lock(&self) -> MutexGuard<'_, OooTracker> {
232        self.ooo.lock().unwrap()
233    }
234
235    /// Push an element into the vector and check that it was inserted into the `index` position.
236    ///
237    /// This is useful for situations where pushing into the wrong position can cause unexpected
238    /// future behaviour.
239    ///
240    /// # Panics
241    ///
242    /// Panics if the position of the new element is not `index`.
243    pub fn push_checked(&self, value: T, index: usize) {
244        assert_eq!(self.push(value), index);
245    }
246
247    /// Append an element to the end of the vector.
248    ///
249    /// Returns the index of the new element.
250    ///
251    /// # Example
252    /// ```
253    /// # use once::OnceVec;
254    /// let v = OnceVec::<u32>::new();
255    /// v.push(1);
256    /// v.push(2);
257    /// let x = &v[1usize];
258    /// v.push(3);
259    /// assert_eq!(*x, 2);
260    /// ```
261    pub fn push(&self, value: T) -> usize {
262        let ooo = self.lock();
263        assert!(
264            ooo.0.is_empty(),
265            "Cannot push while there are out-of-order elements"
266        );
267        let old_len = self.len.load(Ordering::Acquire);
268
269        self.data.insert(old_len, value);
270
271        self.len.store(old_len + 1, Ordering::Release);
272        old_len
273    }
274
275    /// Append an element to an arbitrary position in the OnceVec.
276    ///
277    /// Whenever an element is pushed out of order, the we revisit the whole `OnceVec` and update
278    /// the `len` to be the largest contiguous initial block that has been written to. The return
279    /// value indicates the newly valid range. Elements in this range will no longer be consider to
280    /// have been pushed out of order.
281    ///
282    /// It is invalid to use the ordinary push function when there are still elements pushed out of
283    /// order.
284    ///
285    /// # Example
286    /// ```
287    /// # use once::OnceVec;
288    /// let v = OnceVec::<u32>::new();
289    /// assert_eq!(v.push_ooo(1, 0), 0..1);
290    /// assert_eq!(v.len(), 1);
291    ///
292    /// v.push_checked(2, 1);
293    ///
294    /// assert_eq!(v.push_ooo(3, 3), 2..2);
295    /// assert_eq!(v.len(), 2);
296    ///
297    /// assert_eq!(v.push_ooo(5, 2), 2..4);
298    /// assert_eq!(v.len(), 4);
299    ///
300    /// v.push(4);
301    ///
302    /// assert_eq!(v[2usize], 5);
303    /// assert_eq!(v[3usize], 3);
304    /// assert_eq!(v[4usize], 4);
305    /// ```
306    pub fn push_ooo(&self, value: T, index: usize) -> std::ops::Range<usize> {
307        let mut ooo = self.lock();
308        if ooo.0.contains(&index) {
309            panic!("Cannot push element out of order at the same index {index} twice");
310        }
311
312        let old_len = self.len.load(Ordering::Acquire);
313
314        self.data.insert(index, value);
315
316        if index != old_len {
317            ooo.0.insert(index);
318            return old_len..old_len;
319        }
320        let mut end = old_len + 1;
321        while ooo.0.remove(&end) {
322            end += 1;
323        }
324
325        self.len.store(end, Ordering::Release);
326        old_len..end
327    }
328
329    /// Extend the `OnceVec` to up to index `new_max`, filling in the entries with the values of
330    /// `f`. This takes the lock before calling `f`, which is useful behaviour if used in
331    /// conjunction with [`OnceVec::lock`].
332    ///
333    /// This is thread-safe and guaranteed to be idempotent. `f` will only be called once per
334    /// index.
335    ///
336    /// In case multiple `OnceVec`'s have to be simultaneously updated, one can use `extend` on one
337    /// of them and `push_checked` into the others within the function.
338    ///
339    /// # Parameters
340    ///
341    /// * `new_max`: After calling this function, `self[new_max]` will be defined.
342    /// * `f`: We will fill in the vector with `f(i)` at the `i`th index.
343    ///
344    /// # Example
345    /// ```
346    /// # use once::OnceVec;
347    /// let v: OnceVec<usize> = OnceVec::new();
348    /// v.extend(5, |i| i + 5);
349    /// assert_eq!(v.len(), 6);
350    /// for (i, &n) in v.iter().enumerate() {
351    ///     assert_eq!(n, i + 5);
352    /// }
353    /// ```
354    pub fn extend(&self, new_max: usize, mut f: impl FnMut(usize) -> T) {
355        let ooo = self.lock();
356        assert!(ooo.0.is_empty());
357        let old_len = self.len.load(Ordering::Acquire);
358        if new_max < old_len {
359            return;
360        }
361
362        for i in old_len..=new_max {
363            self.data.insert(i, f(i));
364
365            // Do it inside the loop because f may use self
366            self.len.store(i + 1, Ordering::Release)
367        }
368    }
369
370    /// Iterate through the `OnceVec`.
371    ///
372    /// # Example
373    /// ```
374    /// # use once::OnceVec;
375    /// let v: OnceVec<usize> = OnceVec::new();
376    /// v.push(1);
377    /// v.push(5);
378    /// v.push(2);
379    /// assert_eq!(v.iter().count(), 3);
380    /// ```
381    pub fn iter(&self) -> OnceVecIter<'_, T> {
382        OnceVecIter {
383            grove: &self.data,
384            range: 0..self.len(),
385        }
386    }
387}
388
389/// An iterator over the values in a [`OnceVec`].
390///
391/// Created by [`OnceVec::iter`].
392pub struct OnceVecIter<'a, T> {
393    grove: &'a Grove<T>,
394    range: std::ops::Range<usize>,
395}
396
397impl<'a, T> Iterator for OnceVecIter<'a, T> {
398    type Item = &'a T;
399
400    fn next(&mut self) -> Option<Self::Item> {
401        let i = self.range.next()?;
402        // SAFETY: OnceVec is dense — every slot in 0..len is populated.
403        Some(unsafe { self.grove.get_unchecked(i) })
404    }
405
406    fn size_hint(&self) -> (usize, Option<usize>) {
407        self.range.size_hint()
408    }
409
410    fn count(self) -> usize {
411        self.len()
412    }
413}
414
415impl<T> DoubleEndedIterator for OnceVecIter<'_, T> {
416    fn next_back(&mut self) -> Option<Self::Item> {
417        let i = self.range.next_back()?;
418        // SAFETY: OnceVec is dense — every slot in 0..len is populated.
419        Some(unsafe { self.grove.get_unchecked(i) })
420    }
421}
422
423impl<T> std::iter::FusedIterator for OnceVecIter<'_, T> {}
424
425impl<T> ExactSizeIterator for OnceVecIter<'_, T> {}
426
427impl<'a, T> IntoIterator for &'a OnceVec<T> {
428    type IntoIter = OnceVecIter<'a, T>;
429    type Item = &'a T;
430
431    fn into_iter(self) -> Self::IntoIter {
432        self.iter()
433    }
434}
435
436impl<T: Send + Sync> OnceVec<T> {
437    /// A parallel version of `extend`. If the `concurrent` feature is enabled, the function `f`
438    /// will be run for different indices simultaneously using `rayon`, through the [`maybe_rayon`]
439    /// crate.
440    ///
441    /// # Example
442    #[cfg_attr(miri, doc = "```ignore")]
443    #[cfg_attr(not(miri), doc = "```")]
444    /// # use once::OnceVec;
445    /// let v: OnceVec<usize> = OnceVec::new();
446    /// v.maybe_par_extend(5, |i| i + 5);
447    /// assert_eq!(v.len(), 6);
448    /// for (i, &n) in v.iter().enumerate() {
449    ///     assert_eq!(n, i + 5);
450    /// }
451    /// ```
452    pub fn maybe_par_extend(&self, new_max: usize, f: impl Fn(usize) -> T + Send + Sync) {
453        let ooo = self.lock();
454        assert!(ooo.0.is_empty());
455
456        let old_len = self.len.load(Ordering::Acquire);
457        if new_max < old_len {
458            return;
459        }
460
461        (old_len..=new_max).into_maybe_par_iter().for_each(|i| {
462            self.data.insert(i, f(i));
463        });
464
465        self.len.store(new_max + 1, Ordering::Release)
466    }
467}
468
469impl<T> Index<usize> for OnceVec<T> {
470    type Output = T;
471
472    fn index(&self, index: usize) -> &T {
473        self.get(index).unwrap_or_else(|| {
474            panic!(
475                "Index out of bounds: the len is {} but the index is {index}",
476                self.len()
477            )
478        })
479    }
480}
481
482impl<T> IndexMut<usize> for OnceVec<T> {
483    fn index_mut(&mut self, index: usize) -> &mut T {
484        let len = self.len();
485        self.get_mut(index).unwrap_or_else(|| {
486            panic!("Index out of bounds: the len is {len} but the index is {index}")
487        })
488    }
489}
490
491impl<T> Index<u32> for OnceVec<T> {
492    type Output = T;
493
494    fn index(&self, index: u32) -> &T {
495        self.index(index as usize)
496    }
497}
498
499impl<T> IndexMut<u32> for OnceVec<T> {
500    fn index_mut(&mut self, index: u32) -> &mut T {
501        self.index_mut(index as usize)
502    }
503}
504
505unsafe impl<T: Send> Send for OnceVec<T> {}
506unsafe impl<T: Sync> Sync for OnceVec<T> {}
507
508impl<T> FromIterator<T> for OnceVec<T> {
509    /// ```
510    /// # use once::OnceVec;
511    /// let elements = vec![1, 2, 3];
512    ///
513    /// let v1 = OnceVec::from_vec(elements.clone());
514    /// // The `assert_eq` below lets the compiler infer that `v2` is a `OnceVec<i32>`.
515    /// let v2 = elements.into_iter().collect();
516    ///
517    /// assert_eq!(v1, v2);
518    /// ```
519    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
520        let result = Self::new();
521        for v in iter {
522            result.push(v);
523        }
524        result
525    }
526}
527
528/// A vector that supports negative indices, built on top of `OnceVec`.
529///
530/// `OnceBiVec` extends the functionality of `OnceVec` by allowing elements to be indexed
531/// using negative integers. This is useful for scenarios where you need to represent
532/// data that naturally starts from a negative index. Note that we still only support appending
533/// elements to the end of the vector, so it's not possible to insert elements at arbitrarily
534/// negative indices.
535///
536/// # Examples
537///
538/// ```
539/// use once::OnceBiVec;
540///
541/// // Create a bidirectional vector with minimum degree -3
542/// let vec = OnceBiVec::<i32>::new(-3);
543///
544/// // Insert elements at various positions
545/// vec.push_ooo(10, -3); // At minimum degree
546/// vec.push_ooo(30, -1);
547/// vec.push_ooo(20, -2);
548/// vec.push_ooo(50, 1);
549/// vec.push_ooo(40, 0);
550///
551/// // Access elements using their indices
552/// assert_eq!(vec[-3], 10);
553/// assert_eq!(vec[-2], 20);
554/// assert_eq!(vec[-1], 30);
555/// assert_eq!(vec[0], 40);
556/// assert_eq!(vec[1], 50);
557///
558/// // Get the range of valid indices
559/// assert_eq!(vec.range(), -3..2);
560/// ```
561#[derive(Clone, PartialEq, Eq)]
562pub struct OnceBiVec<T> {
563    data: OnceVec<T>,
564    min_degree: i32,
565}
566
567impl<T: fmt::Debug> fmt::Debug for OnceBiVec<T> {
568    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
569        write!(formatter, "BiVec({}) ", self.min_degree)?;
570        self.data.fmt(formatter)
571    }
572}
573
574impl<T> OnceBiVec<T> {
575    /// Creates a new empty `OnceBiVec` with the specified minimum degree.
576    ///
577    /// # Parameters
578    ///
579    /// * `min_degree`: The minimum degree (lowest index) of the vector
580    ///
581    /// # Examples
582    ///
583    /// ```
584    /// use once::OnceBiVec;
585    ///
586    /// let vec = OnceBiVec::<i32>::new(-5);
587    /// assert_eq!(vec.min_degree(), -5);
588    /// assert_eq!(vec.len(), -5);
589    /// assert!(vec.is_empty());
590    /// ```
591    pub fn new(min_degree: i32) -> Self {
592        Self {
593            data: OnceVec::new(),
594            min_degree,
595        }
596    }
597
598    /// Creates an `OnceBiVec` from a `Vec` with the specified minimum degree.
599    ///
600    /// # Parameters
601    ///
602    /// * `min_degree`: The minimum degree (lowest index) of the vector
603    /// * `data`: The vector of values to initialize with
604    ///
605    /// # Examples
606    ///
607    /// ```
608    /// use once::OnceBiVec;
609    ///
610    /// let vec = OnceBiVec::from_vec(-2, vec![10, 20, 30]);
611    /// assert_eq!(vec.min_degree(), -2);
612    /// assert_eq!(vec.len(), 1); // -2 + 3 = 1
613    /// assert_eq!(vec[-2], 10);
614    /// assert_eq!(vec[-1], 20);
615    /// assert_eq!(vec[0], 30);
616    /// ```
617    pub fn from_vec(min_degree: i32, data: Vec<T>) -> Self {
618        Self {
619            data: OnceVec::from_vec(data),
620            min_degree,
621        }
622    }
623
624    /// Creates an `OnceBiVec` from a `bivec::BiVec`.
625    ///
626    /// This is a convenience method for converting from the `bivec` crate's bidirectional vector
627    /// implementation.
628    ///
629    /// # Parameters
630    ///
631    /// * `data`: The `bivec::BiVec` to convert from
632    pub fn from_bivec(data: bivec::BiVec<T>) -> Self {
633        Self::from_vec(data.min_degree(), data.into_vec())
634    }
635
636    /// Returns the minimum degree (lowest index) of the vector.
637    ///
638    /// # Examples
639    ///
640    /// ```
641    /// use once::OnceBiVec;
642    ///
643    /// let vec = OnceBiVec::<i32>::new(-3);
644    /// assert_eq!(vec.min_degree(), -3);
645    /// ```
646    pub const fn min_degree(&self) -> i32 {
647        self.min_degree
648    }
649
650    /// This returns the largest degree in the bivector. This is equal to `self.len() - 1`.
651    ///
652    /// # Example
653    /// ```
654    /// # use bivec::BiVec;
655    /// let v = BiVec::from_vec(-2, vec![3, 4, 6, 8, 2]);
656    /// assert_eq!(v.max_degree(), 2);
657    /// ```
658    pub fn max_degree(&self) -> i32 {
659        self.len() - 1
660    }
661
662    /// This returns the "length" of the bivector, defined to be the smallest i such that `v[i]` is
663    /// not defined.
664    ///
665    /// # Example
666    /// ```
667    /// # use bivec::BiVec;
668    /// let v = BiVec::from_vec(-2, vec![3, 4, 6, 8, 2]);
669    /// assert_eq!(v.len(), 3);
670    /// ```
671    pub fn len(&self) -> i32 {
672        self.data.len() as i32 + self.min_degree
673    }
674
675    pub fn is_empty(&self) -> bool {
676        self.data.len() == 0
677    }
678
679    pub fn push_checked(&self, value: T, index: i32) {
680        assert_eq!(self.push(value), index);
681    }
682
683    pub fn push(&self, value: T) -> i32 {
684        self.data.push(value) as i32 + self.min_degree
685    }
686
687    /// See [`OnceVec::push_ooo`].
688    pub fn push_ooo(&self, value: T, index: i32) -> std::ops::Range<i32> {
689        let result = self
690            .data
691            .push_ooo(value, (index - self.min_degree) as usize);
692
693        (result.start as i32 + self.min_degree)..(result.end as i32 + self.min_degree)
694    }
695
696    pub fn ooo_elements(&self) -> Vec<i32> {
697        self.data
698            .ooo_elements()
699            .into_iter()
700            .map(|x| x as i32 + self.min_degree)
701            .collect()
702    }
703
704    /// Returns whether the `OnceBiVec` has remaining out-of-order elements
705    pub fn get(&self, index: i32) -> Option<&T> {
706        self.data.get((index - self.min_degree).try_into().ok()?)
707    }
708
709    pub fn get_or_insert(&self, index: i32, to_insert: impl FnOnce() -> T) -> &T {
710        self.data
711            .get_or_insert((index - self.min_degree).try_into().unwrap(), to_insert)
712    }
713
714    pub fn range(&self) -> std::ops::Range<i32> {
715        self.min_degree()..self.len()
716    }
717
718    /// Extend the `OnceBiVec` to up to index `new_max`, filling in the entries with the values of
719    /// `f`. This takes the lock before calling `f`, which is useful behaviour if used in
720    /// conjunction with [`OnceBiVec::lock`].
721    ///
722    /// This is thread-safe and guaranteed to be idempotent. `f` will only be called once per index.
723    ///
724    /// In case multiple `OnceVec`'s have to be simultaneously updated, one can use `extend` on one
725    /// of them and `push_checked` into the others within the function.
726    ///
727    /// # Parameters
728    ///
729    /// * `new_max`: After calling this function, `self[new_max]` will be defined.
730    /// * `f`: We will fill in the vector with `f(i)` at the `i`th index.
731    ///
732    /// # Example
733    /// ```
734    /// # use once::OnceBiVec;
735    /// let v: OnceBiVec<i32> = OnceBiVec::new(-4);
736    /// v.extend(5, |i| i + 5);
737    /// assert_eq!(v.len(), 6);
738    /// for (i, &n) in v.iter() {
739    ///     assert_eq!(n, i + 5);
740    /// }
741    /// ```
742    pub fn extend(&self, new_max: i32, mut f: impl FnMut(i32) -> T) {
743        if new_max < self.min_degree {
744            return;
745        }
746        self.data.extend((new_max - self.min_degree) as usize, |i| {
747            f(i as i32 + self.min_degree)
748        });
749    }
750
751    pub fn last(&self) -> Option<&T> {
752        self.data.last()
753    }
754
755    /// Takes a lock on the `OnceBiVec`. The `OnceBiVec` cannot be updated while the lock is held.
756    /// This is useful when used in conjuction with [`OnceBiVec::extend`];
757    pub fn lock(&self) -> MutexGuard<'_, OooTracker> {
758        self.data.lock()
759    }
760
761    pub fn values(&self) -> impl Iterator<Item = &T> {
762        self.data.iter()
763    }
764
765    pub fn iter(&self) -> OnceBiVecIter<'_, T> {
766        OnceBiVecIter {
767            inner: self.data.iter(),
768            pos: self.min_degree,
769        }
770    }
771}
772
773/// An iterator over the index-value pairs in a [`OnceBiVec`].
774///
775/// Created by [`OnceBiVec::iter`].
776pub struct OnceBiVecIter<'a, T> {
777    inner: OnceVecIter<'a, T>,
778    pos: i32,
779}
780
781impl<'a, T> Iterator for OnceBiVecIter<'a, T> {
782    type Item = (i32, &'a T);
783
784    fn next(&mut self) -> Option<Self::Item> {
785        let value = self.inner.next()?;
786        let idx = self.pos;
787        self.pos += 1;
788        Some((idx, value))
789    }
790
791    fn size_hint(&self) -> (usize, Option<usize>) {
792        self.inner.size_hint()
793    }
794
795    fn count(self) -> usize {
796        self.len()
797    }
798}
799
800impl<T> DoubleEndedIterator for OnceBiVecIter<'_, T> {
801    fn next_back(&mut self) -> Option<Self::Item> {
802        let value = self.inner.next_back()?;
803        // After inner.next_back() shrinks the range, inner.len() is the offset of the back element.
804        let idx = self.pos + self.inner.len() as i32;
805        Some((idx, value))
806    }
807}
808
809impl<T> std::iter::FusedIterator for OnceBiVecIter<'_, T> {}
810
811impl<T> ExactSizeIterator for OnceBiVecIter<'_, T> {}
812
813impl<'a, T> IntoIterator for &'a OnceBiVec<T> {
814    type IntoIter = OnceBiVecIter<'a, T>;
815    type Item = (i32, &'a T);
816
817    fn into_iter(self) -> Self::IntoIter {
818        self.iter()
819    }
820}
821
822impl<T: Send + Sync> OnceBiVec<T> {
823    /// A parallel version of `extend`. If the `concurrent` feature is enabled, the function `f`
824    /// will be run for different indices simultaneously using `rayon`, through the [`maybe_rayon`]
825    /// crate.
826    ///
827    /// # Example
828    #[cfg_attr(miri, doc = "```ignore")]
829    #[cfg_attr(not(miri), doc = "```")]
830    /// # use once::OnceBiVec;
831    /// let v: OnceBiVec<i32> = OnceBiVec::new(-4);
832    /// v.maybe_par_extend(5, |i| i + 5);
833    /// assert_eq!(v.len(), 6);
834    /// for (i, &n) in v.iter() {
835    ///     assert_eq!(n, i + 5);
836    /// }
837    /// ```
838    pub fn maybe_par_extend(&self, new_max: i32, f: impl (Fn(i32) -> T) + Send + Sync) {
839        if new_max < self.min_degree {
840            return;
841        }
842        self.data
843            .maybe_par_extend((new_max - self.min_degree) as usize, |i| {
844                f(i as i32 + self.min_degree)
845            });
846    }
847
848    pub fn maybe_par_iter(
849        &self,
850    ) -> impl MaybeParallelIterator<Item = (i32, &T)> + MaybeIndexedParallelIterator {
851        self.range().into_maybe_par_iter().map(|i| (i, &self[i]))
852    }
853}
854
855impl<T> Index<i32> for OnceBiVec<T> {
856    type Output = T;
857
858    fn index(&self, i: i32) -> &T {
859        assert!(
860            i >= self.min_degree(),
861            "Index out of bounds: the minimum degree is {} but the index is {i}",
862            self.min_degree()
863        );
864        assert!(
865            i < self.len(),
866            "Index out of bounds: the length is {} but the index is {i}",
867            self.len()
868        );
869        &(self.data[(i - self.min_degree) as usize])
870    }
871}
872
873impl<T> IndexMut<i32> for OnceBiVec<T> {
874    fn index_mut(&mut self, i: i32) -> &mut T {
875        assert!(
876            i >= self.min_degree(),
877            "Index out of bounds: the minimum degree is {} but the index is {i}",
878            self.min_degree()
879        );
880        assert!(
881            i < self.len(),
882            "Index out of bounds: the length is {} but the index is {i}",
883            self.len()
884        );
885        &mut (self.data[(i - self.min_degree) as usize])
886    }
887}
888
889#[cfg(test)]
890mod tests {
891    use std::{sync::Arc, thread};
892
893    use super::*;
894
895    #[test]
896    fn test_push() {
897        let v = OnceVec::new();
898        for i in 0u32..1000u32 {
899            v.push(i);
900            assert_eq!(v[i], i);
901        }
902    }
903
904    #[test]
905    fn test_drop_ooo() {
906        let v: OnceVec<u32> = OnceVec::new();
907        v.push(4);
908        v.push(3);
909        v.push_ooo(6, 7);
910        drop(v);
911    }
912
913    #[test]
914    fn test_concurrent_push() {
915        let v = Arc::new(OnceVec::<usize>::new());
916
917        let num_threads = crate::test_utils::num_threads();
918        let values_per_thread = crate::test_utils::values_per_thread();
919
920        let handles: Vec<_> = (0..num_threads)
921            .map(|thread_id| {
922                let v = Arc::clone(&v);
923                thread::spawn(move || {
924                    for i in 0..values_per_thread {
925                        v.push(thread_id * values_per_thread + i);
926                    }
927                })
928            })
929            .collect();
930
931        for handle in handles {
932            handle.join().unwrap();
933        }
934
935        assert_eq!(v.len(), num_threads * values_per_thread);
936
937        // All values should be present, though not necessarily in order
938        let mut found = vec![false; num_threads * values_per_thread];
939        for i in 0..v.len() {
940            found[v[i]] = true;
941        }
942        assert!(found.iter().all(|&x| x));
943    }
944
945    #[test]
946    fn test_extend() {
947        let v = OnceVec::<usize>::new();
948        v.extend(10, |i| i * 2);
949
950        assert_eq!(v.len(), 11);
951        for i in 0..=10usize {
952            assert_eq!(v[i], i * 2);
953        }
954    }
955
956    #[test]
957    fn test_push_ooo() {
958        let v = OnceVec::<usize>::new();
959
960        // Push out of order
961        v.push_ooo(100, 10);
962        assert_eq!(v.len(), 0); // Length is still 0 because there's a gap
963        assert_eq!(v.ooo_elements(), vec![10]);
964
965        // Fill the gap partially
966        v.push_ooo(0, 0);
967        assert_eq!(v.len(), 1); // Length is now 1
968        assert_eq!(v.ooo_elements(), vec![10]);
969
970        // Fill more of the gap
971        v.push_ooo(10, 1);
972        v.push_ooo(20, 2);
973        v.push_ooo(30, 3);
974        assert_eq!(v.len(), 4); // Length is now 4
975        assert_eq!(v.ooo_elements(), vec![10]);
976
977        // Fill the rest of the gap
978        v.push_ooo(40, 4);
979        v.push_ooo(50, 5);
980        v.push_ooo(60, 6);
981        v.push_ooo(70, 7);
982        v.push_ooo(80, 8);
983        v.push_ooo(90, 9);
984        assert_eq!(v.len(), 11); // Length is now 11 (0-10)
985        assert_eq!(v.ooo_elements().len(), 0);
986
987        // Verify all values
988        for i in 0..=10usize {
989            assert_eq!(v[i], i * 10);
990        }
991    }
992
993    #[test]
994    fn test_from_vec() {
995        let original = vec![10, 20, 30, 40, 50];
996        let v = OnceVec::from_vec(original.clone());
997
998        assert_eq!(v.len(), original.len());
999        for (i, &val) in original.iter().enumerate() {
1000            assert_eq!(v[i], val);
1001        }
1002    }
1003
1004    #[test]
1005    fn test_clone() {
1006        let v1 = OnceVec::new();
1007        v1.push(10);
1008        v1.push(20);
1009        v1.push(30);
1010
1011        let v2 = v1.clone();
1012        assert_eq!(v1.len(), v2.len());
1013        for i in 0..v1.len() {
1014            assert_eq!(v1[i], v2[i]);
1015        }
1016
1017        // Modifying one doesn't affect the other
1018        v1.push(40);
1019        assert_eq!(v1.len(), 4);
1020        assert_eq!(v2.len(), 3);
1021    }
1022
1023    #[test]
1024    fn test_iter() {
1025        let v = OnceVec::new();
1026        v.push(10);
1027        v.push(20);
1028        v.push(30);
1029
1030        let mut iter = v.iter();
1031        assert_eq!(iter.next(), Some(&10));
1032        assert_eq!(iter.next(), Some(&20));
1033        assert_eq!(iter.next(), Some(&30));
1034        assert_eq!(iter.next(), None);
1035    }
1036
1037    #[test]
1038    fn test_from_iterator() {
1039        let data = [1, 2, 3, 4, 5];
1040        let v: OnceVec<_> = data.iter().copied().collect();
1041
1042        assert_eq!(v.len(), data.len());
1043        for (i, &val) in data.iter().enumerate() {
1044            assert_eq!(v[i], val);
1045        }
1046    }
1047
1048    #[cfg(not(miri))]
1049    mod proptests {
1050        use std::collections::{HashMap, HashSet};
1051
1052        use proptest::prelude::*;
1053
1054        use super::*;
1055
1056        #[derive(Debug, Clone)]
1057        enum OnceVecOperation {
1058            Push(i32),
1059            PushOoo(i32, usize),
1060            Extend(usize, i32), // extend to index, with multiplier
1061        }
1062
1063        fn oncevec_operation_strategy() -> impl Strategy<Value = OnceVecOperation> {
1064            prop_oneof![
1065                prop::num::i32::ANY.prop_map(OnceVecOperation::Push),
1066                (prop::num::i32::ANY, 0..10usize)
1067                    .prop_map(|(v, i)| OnceVecOperation::PushOoo(v, i)),
1068                (0..10usize, prop::num::i32::ANY)
1069                    .prop_map(|(max, m)| OnceVecOperation::Extend(max, m)),
1070            ]
1071        }
1072
1073        proptest! {
1074            #[test]
1075            fn proptest_oncevec_operations(
1076                ops in prop::collection::vec(
1077                    oncevec_operation_strategy(),
1078                    1..50
1079                )
1080            ) {
1081                let vec = OnceVec::new();
1082                let mut reference = Vec::new();
1083                let mut ooo_indices = HashMap::new();
1084                let mut all_indices = HashSet::new();
1085
1086                for op in ops {
1087                    match op {
1088                        OnceVecOperation::Push(value) => {
1089                            // Only push if there are no out-of-order elements
1090                            if ooo_indices.is_empty() {
1091                                vec.push(value);
1092                                reference.push(value);
1093                                all_indices.insert(reference.len() - 1);
1094                            }
1095                        },
1096                        OnceVecOperation::PushOoo(value, idx) => {
1097                            // Only insert if the index doesn't already have a value
1098                            if all_indices.contains(&idx) {
1099                                // Skip invalid indices that would panic
1100                                continue;
1101                            } else if idx == reference.len() {
1102                                vec.push_ooo(value, idx);
1103                                reference.push(value);
1104                            } else {
1105                                vec.push_ooo(value, idx);
1106                                while reference.len() <= idx {
1107                                    reference.push(0); // Placeholder values
1108                                }
1109                                reference[idx] = value;
1110                                ooo_indices.insert(idx, value);
1111                            }
1112                            all_indices.insert(idx);
1113                        },
1114                        OnceVecOperation::Extend(max, multiplier) => {
1115                            if ooo_indices.is_empty() {
1116                                let to_insert = |i| (i as i32).saturating_mul(multiplier);
1117                                vec.extend(max, to_insert);
1118                                for i in reference.len()..=max {
1119                                    reference.push(to_insert(i));
1120                                    all_indices.insert(i);
1121                                }
1122                            }
1123                        }
1124                    }
1125
1126                    // Check that the vectors match
1127                    for i in 0..vec.len().min(reference.len()) {
1128                        assert_eq!(vec[i], reference[i]);
1129                    }
1130                }
1131            }
1132        }
1133    }
1134
1135    // OnceBiVec tests
1136
1137    #[test]
1138    fn test_oncebivec_basic() {
1139        let v = OnceBiVec::<i32>::new(-3);
1140
1141        // Check initial state
1142        assert_eq!(v.min_degree(), -3);
1143        assert_eq!(v.len(), -3);
1144        assert!(v.is_empty());
1145
1146        // Push values
1147        v.push(10); // This will be at index -3
1148        v.push(20); // This will be at index -2
1149        v.push(30); // This will be at index -1
1150
1151        // Check state after pushing
1152        assert_eq!(v.len(), 0); // -3 + 3 = 0
1153        assert_eq!(v.max_degree(), -1); // len() - 1
1154        assert!(!v.is_empty());
1155
1156        // Check values
1157        assert_eq!(v[-3], 10);
1158        assert_eq!(v[-2], 20);
1159        assert_eq!(v[-1], 30);
1160
1161        // Check range
1162        assert_eq!(v.range(), -3..0);
1163    }
1164
1165    #[test]
1166    fn test_oncebivec_from_vec() {
1167        let data = vec![5, 10, 15, 20];
1168        let v = OnceBiVec::from_vec(-5, data.clone());
1169
1170        // Check state
1171        assert_eq!(v.min_degree(), -5);
1172        assert_eq!(v.len(), -1); // -5 + 4 = -1
1173
1174        // Check values
1175        for (i, &val) in data.iter().enumerate() {
1176            assert_eq!(v[i as i32 - 5], val);
1177        }
1178    }
1179
1180    #[test]
1181    fn test_oncebivec_push_ooo() {
1182        let v = OnceBiVec::<i32>::new(-3);
1183
1184        // Push out of order
1185        v.push_ooo(100, 0);
1186        assert_eq!(v.len(), -3); // Length is still -3 because there's a gap
1187
1188        // Fill the gap
1189        v.push_ooo(10, -3);
1190        v.push_ooo(20, -2);
1191        v.push_ooo(30, -1);
1192
1193        // Check state
1194        assert_eq!(v.len(), 1); // All gaps filled, so len is 1
1195
1196        // Check values
1197        assert_eq!(v[-3], 10);
1198        assert_eq!(v[-2], 20);
1199        assert_eq!(v[-1], 30);
1200        assert_eq!(v[0], 100);
1201    }
1202
1203    #[test]
1204    fn test_oncebivec_extend() {
1205        let v = OnceBiVec::<i32>::new(-5);
1206
1207        // Extend from min_degree to 2
1208        v.extend(2, |i| i * 10);
1209
1210        // Check state
1211        assert_eq!(v.len(), 3); // -5 + 8 = 3
1212
1213        // Check values
1214        for i in -5..=2 {
1215            assert_eq!(v[i], i * 10);
1216        }
1217    }
1218
1219    #[test]
1220    fn test_oncebivec_iter() {
1221        let v = OnceBiVec::<i32>::new(-3);
1222
1223        // Add some values
1224        v.push(10);
1225        v.push(20);
1226        v.push(30);
1227
1228        // Check values iterator
1229        let mut iter = v.values();
1230        assert_eq!(iter.next(), Some(&10));
1231        assert_eq!(iter.next(), Some(&20));
1232        assert_eq!(iter.next(), Some(&30));
1233        assert_eq!(iter.next(), None);
1234
1235        // Check iter (yields (i32, &T))
1236        let expected_indices = [-3, -2, -1];
1237        let expected_values = [10, 20, 30];
1238        let actual_pairs: Vec<_> = v.iter().collect();
1239
1240        for (i, (idx, val)) in actual_pairs.iter().enumerate() {
1241            assert_eq!(*idx, expected_indices[i]);
1242            assert_eq!(**val, expected_values[i]);
1243        }
1244    }
1245
1246    #[test]
1247    fn test_oncevec_iter_rev() {
1248        let v = OnceVec::new();
1249        v.push(10);
1250        v.push(20);
1251        v.push(30);
1252
1253        let mut iter = v.iter().rev();
1254        assert_eq!(iter.next(), Some(&30));
1255        assert_eq!(iter.next(), Some(&20));
1256        assert_eq!(iter.next(), Some(&10));
1257        assert_eq!(iter.next(), None);
1258    }
1259
1260    #[test]
1261    fn test_oncevec_iter_double_ended() {
1262        let v = OnceVec::new();
1263        v.push(10);
1264        v.push(20);
1265        v.push(30);
1266        v.push(40);
1267
1268        let mut iter = v.iter();
1269        assert_eq!(iter.next(), Some(&10));
1270        assert_eq!(iter.next_back(), Some(&40));
1271        assert_eq!(iter.next_back(), Some(&30));
1272        assert_eq!(iter.next(), Some(&20));
1273        assert_eq!(iter.next(), None);
1274        assert_eq!(iter.next_back(), None);
1275    }
1276
1277    #[test]
1278    fn test_oncevec_iter_exact_size() {
1279        let v = OnceVec::new();
1280        v.push(10);
1281        v.push(20);
1282        v.push(30);
1283
1284        let mut iter = v.iter();
1285        assert_eq!(iter.len(), 3);
1286        iter.next();
1287        assert_eq!(iter.len(), 2);
1288        iter.next_back();
1289        assert_eq!(iter.len(), 1);
1290        iter.next();
1291        assert_eq!(iter.len(), 0);
1292    }
1293
1294    #[test]
1295    fn test_oncebivec_iter_rev() {
1296        let v = OnceBiVec::<i32>::new(-2);
1297        v.push(10);
1298        v.push(20);
1299        v.push(30);
1300
1301        let items: Vec<_> = v.iter().rev().collect();
1302        assert_eq!(items, vec![(0, &30), (-1, &20), (-2, &10)]);
1303    }
1304
1305    #[test]
1306    fn test_oncebivec_iter_double_ended() {
1307        let v = OnceBiVec::<i32>::new(-2);
1308        v.push(10);
1309        v.push(20);
1310        v.push(30);
1311        v.push(40);
1312
1313        let mut iter = v.iter();
1314        assert_eq!(iter.next(), Some((-2, &10)));
1315        assert_eq!(iter.next_back(), Some((1, &40)));
1316        assert_eq!(iter.next_back(), Some((0, &30)));
1317        assert_eq!(iter.next(), Some((-1, &20)));
1318        assert_eq!(iter.next(), None);
1319        assert_eq!(iter.next_back(), None);
1320    }
1321
1322    #[test]
1323    fn test_oncebivec_iter_exact_size() {
1324        let v = OnceBiVec::<i32>::new(-2);
1325        v.push(10);
1326        v.push(20);
1327        v.push(30);
1328
1329        let mut iter = v.iter();
1330        assert_eq!(iter.len(), 3);
1331        iter.next();
1332        assert_eq!(iter.len(), 2);
1333        iter.next_back();
1334        assert_eq!(iter.len(), 1);
1335        iter.next();
1336        assert_eq!(iter.len(), 0);
1337    }
1338
1339    #[cfg(loom)]
1340    mod loom_tests {
1341        use super::*;
1342        use crate::std_or_loom::{sync::Arc, thread};
1343
1344        #[test]
1345        fn loom_concurrent_push() {
1346            loom::model(|| {
1347                let vec = Arc::new(OnceVec::<usize>::new());
1348
1349                // Thread 1: Push values
1350                let vec1 = Arc::clone(&vec);
1351                let t1 = thread::spawn(move || {
1352                    vec1.push(1);
1353                    vec1.push(3);
1354                });
1355
1356                // Thread 2: Push values
1357                let vec2 = Arc::clone(&vec);
1358                let t2 = thread::spawn(move || {
1359                    vec2.push(2);
1360                    vec2.push(4);
1361                });
1362
1363                t1.join().unwrap();
1364                t2.join().unwrap();
1365
1366                assert_eq!(vec.len(), 4);
1367            });
1368        }
1369
1370        #[test]
1371        fn loom_push_and_read() {
1372            loom::model(|| {
1373                let vec = Arc::new(OnceVec::<usize>::new());
1374
1375                // Thread 1: Push values
1376                let vec1 = Arc::clone(&vec);
1377                let t1 = thread::spawn(move || {
1378                    vec1.push(1);
1379                    vec1.push(2);
1380                });
1381
1382                // Thread 2: Read values
1383                let vec2 = Arc::clone(&vec);
1384                let t2 = thread::spawn(move || {
1385                    let len = vec2.len();
1386                    if len > 0 {
1387                        let _ = vec2.get(0);
1388                    }
1389                    if len > 1 {
1390                        let _ = vec2.get(1);
1391                    }
1392                });
1393
1394                t1.join().unwrap();
1395                t2.join().unwrap();
1396
1397                assert_eq!(vec.len(), 2);
1398            });
1399        }
1400
1401        #[test]
1402        fn loom_extend_concurrent() {
1403            loom::model(|| {
1404                let vec = Arc::new(OnceVec::<usize>::new());
1405
1406                // Thread 1: Extend
1407                let vec1 = Arc::clone(&vec);
1408                let t1 = thread::spawn(move || {
1409                    vec1.extend(2, |i| i + 1);
1410                });
1411
1412                // Thread 2: Push
1413                let vec2 = Arc::clone(&vec);
1414                let t2 = thread::spawn(move || {
1415                    if vec2.len() == 0 {
1416                        vec2.push(100);
1417                    } else if vec2.len() == 3 {
1418                        vec2.push(200);
1419                    }
1420                });
1421
1422                t1.join().unwrap();
1423                t2.join().unwrap();
1424            });
1425        }
1426
1427        #[test]
1428        fn loom_oncebivec_iter() {
1429            loom::model(|| {
1430                let vec = Arc::new(OnceBiVec::<i32>::new(-3));
1431
1432                // Thread 1: Push values
1433                let vec1 = Arc::clone(&vec);
1434                let t1 = thread::spawn(move || {
1435                    vec1.push(10);
1436                    vec1.push(20);
1437                });
1438
1439                // Thread 2: Read and enumerate values
1440                let vec2 = Arc::clone(&vec);
1441                let t2 = thread::spawn(move || {
1442                    let len = vec2.len();
1443                    if len > -2 {
1444                        // At least one element
1445                        let pairs: Vec<_> = vec2.iter().collect();
1446                        for (idx, _) in pairs {
1447                            assert!(idx >= -3 && idx < len);
1448                        }
1449                    }
1450                });
1451
1452                t1.join().unwrap();
1453                t2.join().unwrap();
1454
1455                // Verify final state
1456                let pairs: Vec<_> = vec.iter().collect();
1457                assert_eq!(pairs.len(), 2);
1458                assert_eq!(pairs[0].0, -3);
1459                assert_eq!(*pairs[0].1, 10);
1460                assert_eq!(pairs[1].0, -2);
1461                assert_eq!(*pairs[1].1, 20);
1462            });
1463        }
1464    }
1465}