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#[derive(Clone, Default)]
26pub struct OooTracker(BTreeSet<usize>);
27
28#[derive(Default)]
104pub struct OnceVec<T> {
105 len: AtomicUsize,
106 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 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 pub fn ooo_elements(&self) -> Vec<usize> {
185 self.ooo.lock().unwrap().0.iter().copied().collect()
186 }
187
188 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 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 pub fn lock(&self) -> MutexGuard<'_, OooTracker> {
232 self.ooo.lock().unwrap()
233 }
234
235 pub fn push_checked(&self, value: T, index: usize) {
244 assert_eq!(self.push(value), index);
245 }
246
247 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 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 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 self.len.store(i + 1, Ordering::Release)
367 }
368 }
369
370 pub fn iter(&self) -> OnceVecIter<'_, T> {
382 OnceVecIter {
383 grove: &self.data,
384 range: 0..self.len(),
385 }
386 }
387}
388
389pub 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 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 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 #[cfg_attr(miri, doc = "```ignore")]
443 #[cfg_attr(not(miri), doc = "```")]
444 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 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#[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 pub fn new(min_degree: i32) -> Self {
592 Self {
593 data: OnceVec::new(),
594 min_degree,
595 }
596 }
597
598 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 pub fn from_bivec(data: bivec::BiVec<T>) -> Self {
633 Self::from_vec(data.min_degree(), data.into_vec())
634 }
635
636 pub const fn min_degree(&self) -> i32 {
647 self.min_degree
648 }
649
650 pub fn max_degree(&self) -> i32 {
659 self.len() - 1
660 }
661
662 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 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 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 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 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
773pub 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 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 #[cfg_attr(miri, doc = "```ignore")]
829 #[cfg_attr(not(miri), doc = "```")]
830 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 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 v.push_ooo(100, 10);
962 assert_eq!(v.len(), 0); assert_eq!(v.ooo_elements(), vec![10]);
964
965 v.push_ooo(0, 0);
967 assert_eq!(v.len(), 1); assert_eq!(v.ooo_elements(), vec![10]);
969
970 v.push_ooo(10, 1);
972 v.push_ooo(20, 2);
973 v.push_ooo(30, 3);
974 assert_eq!(v.len(), 4); assert_eq!(v.ooo_elements(), vec![10]);
976
977 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); assert_eq!(v.ooo_elements().len(), 0);
986
987 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 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), }
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 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 if all_indices.contains(&idx) {
1099 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); }
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 for i in 0..vec.len().min(reference.len()) {
1128 assert_eq!(vec[i], reference[i]);
1129 }
1130 }
1131 }
1132 }
1133 }
1134
1135 #[test]
1138 fn test_oncebivec_basic() {
1139 let v = OnceBiVec::<i32>::new(-3);
1140
1141 assert_eq!(v.min_degree(), -3);
1143 assert_eq!(v.len(), -3);
1144 assert!(v.is_empty());
1145
1146 v.push(10); v.push(20); v.push(30); assert_eq!(v.len(), 0); assert_eq!(v.max_degree(), -1); assert!(!v.is_empty());
1155
1156 assert_eq!(v[-3], 10);
1158 assert_eq!(v[-2], 20);
1159 assert_eq!(v[-1], 30);
1160
1161 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 assert_eq!(v.min_degree(), -5);
1172 assert_eq!(v.len(), -1); 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 v.push_ooo(100, 0);
1186 assert_eq!(v.len(), -3); v.push_ooo(10, -3);
1190 v.push_ooo(20, -2);
1191 v.push_ooo(30, -1);
1192
1193 assert_eq!(v.len(), 1); 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 v.extend(2, |i| i * 10);
1209
1210 assert_eq!(v.len(), 3); 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 v.push(10);
1225 v.push(20);
1226 v.push(30);
1227
1228 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 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 let vec1 = Arc::clone(&vec);
1351 let t1 = thread::spawn(move || {
1352 vec1.push(1);
1353 vec1.push(3);
1354 });
1355
1356 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 let vec1 = Arc::clone(&vec);
1377 let t1 = thread::spawn(move || {
1378 vec1.push(1);
1379 vec1.push(2);
1380 });
1381
1382 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 let vec1 = Arc::clone(&vec);
1408 let t1 = thread::spawn(move || {
1409 vec1.extend(2, |i| i + 1);
1410 });
1411
1412 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 let vec1 = Arc::clone(&vec);
1434 let t1 = thread::spawn(move || {
1435 vec1.push(10);
1436 vec1.push(20);
1437 });
1438
1439 let vec2 = Arc::clone(&vec);
1441 let t2 = thread::spawn(move || {
1442 let len = vec2.len();
1443 if len > -2 {
1444 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 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}