diff --git a/crates/re_query_cache/Cargo.toml b/crates/re_query_cache/Cargo.toml index 1667852607968..1f2365dfb683c 100644 --- a/crates/re_query_cache/Cargo.toml +++ b/crates/re_query_cache/Cargo.toml @@ -28,15 +28,14 @@ re_types_core.workspace = true # External dependencies: ahash.workspace = true document-features.workspace = true -itertools = { workspace = true } +itertools.workspace = true thiserror.workspace = true [dev-dependencies] re_log_types = { workspace = true, features = ["testing"] } -criterion = "0.5" -itertools = { workspace = true } +criterion.workspace = true mimalloc.workspace = true similar-asserts.workspace = true diff --git a/crates/re_query_cache/benches/flat_vec_deque.rs b/crates/re_query_cache/benches/flat_vec_deque.rs index 6932ae039d1c5..d12e10293c0e3 100644 --- a/crates/re_query_cache/benches/flat_vec_deque.rs +++ b/crates/re_query_cache/benches/flat_vec_deque.rs @@ -4,8 +4,6 @@ use itertools::Itertools as _; use re_query_cache::FlatVecDeque; -// TODO: all of this should be core_benchmarks - // --- #[global_allocator] @@ -15,8 +13,8 @@ criterion_group!( benches, range, insert, - insert_range, - insert_with, + insert_many, + insert_deque, remove, remove_range ); @@ -104,7 +102,7 @@ fn insert(c: &mut Criterion) { group.bench_function("insert/empty", |b| { b.iter(|| { let mut v: FlatVecDeque = FlatVecDeque::new(); - v.insert(0, added.clone().into_iter()); + v.insert(0, added.clone()); v }); }); @@ -115,7 +113,7 @@ fn insert(c: &mut Criterion) { let base = create_prefilled(); b.iter(|| { let mut v: FlatVecDeque = base.clone(); - v.insert(0, added.clone().into_iter()); + v.insert(0, added.clone()); v }); }); @@ -123,7 +121,7 @@ fn insert(c: &mut Criterion) { let base = create_prefilled(); b.iter(|| { let mut v: FlatVecDeque = base.clone(); - v.insert(INITIAL_NUM_ENTRIES / 2, added.clone().into_iter()); + v.insert(INITIAL_NUM_ENTRIES / 2, added.clone()); v }); }); @@ -131,14 +129,14 @@ fn insert(c: &mut Criterion) { let base = create_prefilled(); b.iter(|| { let mut v: FlatVecDeque = base.clone(); - v.insert(INITIAL_NUM_ENTRIES, added.clone().into_iter()); + v.insert(INITIAL_NUM_ENTRIES, added.clone()); v }); }); } } -fn insert_range(c: &mut Criterion) { +fn insert_many(c: &mut Criterion) { if std::env::var("CI").is_ok() { return; } @@ -153,54 +151,51 @@ fn insert_range(c: &mut Criterion) { )); { - group.bench_function("insert_range/empty", |b| { + group.bench_function("insert_many/empty", |b| { b.iter(|| { let mut v: FlatVecDeque = FlatVecDeque::new(); - v.insert_range(0, added.clone()); + v.insert_many(0, added.clone()); v }); }); } { - group.bench_function("insert_range/prefilled/front", |b| { + group.bench_function("insert_many/prefilled/front", |b| { let base = create_prefilled(); b.iter(|| { let mut v: FlatVecDeque = base.clone(); - v.insert_range(0, added.clone()); + v.insert_many(0, added.clone()); v }); }); - group.bench_function("insert_range/prefilled/middle", |b| { + group.bench_function("insert_many/prefilled/middle", |b| { let base = create_prefilled(); b.iter(|| { let mut v: FlatVecDeque = base.clone(); - v.insert_range(INITIAL_NUM_ENTRIES / 2, added.clone()); + v.insert_many(INITIAL_NUM_ENTRIES / 2, added.clone()); v }); }); - group.bench_function("insert_range/prefilled/back", |b| { + group.bench_function("insert_many/prefilled/back", |b| { let base = create_prefilled(); b.iter(|| { let mut v: FlatVecDeque = base.clone(); - v.insert_range(INITIAL_NUM_ENTRIES, added.clone()); + v.insert_many(INITIAL_NUM_ENTRIES, added.clone()); v }); }); } } -fn insert_with(c: &mut Criterion) { +fn insert_deque(c: &mut Criterion) { if std::env::var("CI").is_ok() { return; } let mut added: FlatVecDeque = FlatVecDeque::new(); for i in 0..ADDED_NUM_ENTRIES { - added.insert( - i, - (0..ADDED_VALUES_PER_ENTRY as i64).collect_vec().into_iter(), - ); + added.insert(i, (0..ADDED_VALUES_PER_ENTRY as i64).collect_vec()); } let added = FlatVecDeque::from_vecs( @@ -214,37 +209,37 @@ fn insert_with(c: &mut Criterion) { )); { - group.bench_function("insert_with/empty", |b| { + group.bench_function("insert_deque/empty", |b| { b.iter(|| { let mut v: FlatVecDeque = FlatVecDeque::new(); - v.insert_with(0, added.clone()); + v.insert_deque(0, added.clone()); v }); }); } { - group.bench_function("insert_with/prefilled/front", |b| { + group.bench_function("insert_deque/prefilled/front", |b| { let base = create_prefilled(); b.iter(|| { let mut v: FlatVecDeque = base.clone(); - v.insert_with(0, added.clone()); + v.insert_deque(0, added.clone()); v }); }); - group.bench_function("insert_with/prefilled/middle", |b| { + group.bench_function("insert_deque/prefilled/middle", |b| { let base = create_prefilled(); b.iter(|| { let mut v: FlatVecDeque = base.clone(); - v.insert_with(INITIAL_NUM_ENTRIES / 2, added.clone()); + v.insert_deque(INITIAL_NUM_ENTRIES / 2, added.clone()); v }); }); - group.bench_function("insert_with/prefilled/back", |b| { + group.bench_function("insert_deque/prefilled/back", |b| { let base = create_prefilled(); b.iter(|| { let mut v: FlatVecDeque = base.clone(); - v.insert_with(INITIAL_NUM_ENTRIES, added.clone()); + v.insert_deque(INITIAL_NUM_ENTRIES, added.clone()); v }); }); diff --git a/crates/re_query_cache/src/flat_vec_deque.rs b/crates/re_query_cache/src/flat_vec_deque.rs index 1acf9877c5df3..eb8d93a19dde5 100644 --- a/crates/re_query_cache/src/flat_vec_deque.rs +++ b/crates/re_query_cache/src/flat_vec_deque.rs @@ -72,15 +72,33 @@ impl ErasedFlatVecDeque for FlatVecDeque { /// A double-ended queue implemented with a pair of growable ring buffers, where every single /// entry is a flattened array of values. /// -/// You can think of this as the native/deserialized version of an Arrow `ListArray`. +/// Logically like a `VecDeque>`, but with a less fragmented memory layout (each `Box<[T]>` +/// gets copied/inlined into the `FlatVecDeque`). +/// `FlatVecDeque` therefore optimizes for reads (cache locality, specifically) while `VecDeque>` +/// optimizes for writes. /// -/// This is particularly when working with many small arrays of data (e.g. Rerun's `TimeSeriesScalar`s). +/// You can think of this as the native/deserialized version of an Arrow `ListArray`. +/// This is particularly useful when working with many small arrays of data (e.g. Rerun's +/// `TimeSeriesScalar`s). // // TODO(cmc): We could even use a bitmap for T=Option, which would bring this that much // closer to a deserialized version of an Arrow array. #[derive(Debug, Clone)] pub struct FlatVecDeque { + /// Stores every value in the `FlatVecDeque` in a flattened `VecDeque`. + /// + /// E.g.: + /// - `FlatVecDeque[]` -> values=`[]`. + /// - `FlatVecDeque[[], [], []]` -> values=`[]`. + /// - `FlatVecDeque[[], [0], [1, 2, 3], [4, 5]]` -> values=`[0, 1, 2, 3, 4, 5]`. values: VecDeque, + + /// Keeps track of each entry, i.e. logical slices of data. + /// + /// E.g.: + /// - `FlatVecDeque[]` -> offsets=`[]`. + /// - `FlatVecDeque[[], [], []]` -> offsets=`[0, 0, 0]`. + /// - `FlatVecDeque[[], [0], [1, 2, 3], [4, 5]]` -> offsets=`[0, 1, 4, 6]`. offsets: VecDeque, } @@ -155,11 +173,6 @@ impl FlatVecDeque { self.values.len() } - #[inline] - pub fn is_empty(&self) -> bool { - self.num_entries() == 0 - } - #[inline] fn value_offset(&self, entry_index: usize) -> usize { if entry_index == 0 { @@ -222,7 +235,7 @@ fn range() { assert_eq!(0, v.num_entries()); assert_eq!(0, v.num_values()); - v.insert_range(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); + v.insert_many(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7], &[8, 9, 10]], &v); assert_iter_eq(&[&[1, 2, 3]], v.range(0..1)); @@ -246,7 +259,7 @@ impl FlatVecDeque { /// /// See [`Self::insert`] for more information. #[inline] - pub fn push_front(&mut self, values: impl ExactSizeIterator) { + pub fn push_front(&mut self, values: impl IntoIterator) { self.insert(0, values); } @@ -256,7 +269,7 @@ impl FlatVecDeque { /// /// See [`Self::insert`] for more information. #[inline] - pub fn push_back(&mut self, values: impl ExactSizeIterator) { + pub fn push_back(&mut self, values: impl IntoIterator) { self.insert(self.num_entries(), values); } @@ -269,35 +282,36 @@ impl FlatVecDeque { /// Panics if `entry_index` is out of bounds. /// Panics if `values` is empty. #[inline] - pub fn insert(&mut self, entry_index: usize, values: impl ExactSizeIterator) { + pub fn insert(&mut self, entry_index: usize, values: impl IntoIterator) { + let values: VecDeque = values.into_iter().collect(); let num_values = values.len(); let deque = Self { - values: values.collect(), + values, offsets: std::iter::once(num_values).collect(), }; - self.insert_with(entry_index, deque); + self.insert_deque(entry_index, deque); } /// Prepends multiple entries, each comprised of the multiple elements given in `entries`, /// to the deque. /// - /// This is the same as `self.insert_range(0, entries)`. + /// This is the same as `self.insert_many(0, entries)`. /// - /// See [`Self::insert_range`] for more information. + /// See [`Self::insert_many`] for more information. #[inline] - pub fn push_range_front(&mut self, entries: impl IntoIterator>) { - self.insert_range(0, entries); + pub fn push_many_front(&mut self, entries: impl IntoIterator>) { + self.insert_many(0, entries); } /// Appends multiple entries, each comprised of the multiple elements given in `entries`, /// to the deque. /// - /// This is the same as `self.insert_range(self.num_entries(), entries)`. + /// This is the same as `self.insert_many(self.num_entries(), entries)`. /// - /// See [`Self::insert_range`] for more information. + /// See [`Self::insert_many`] for more information. #[inline] - pub fn push_range_back(&mut self, entries: impl IntoIterator>) { - self.insert_range(self.num_entries(), entries); + pub fn push_many_back(&mut self, entries: impl IntoIterator>) { + self.insert_many(self.num_entries(), entries); } /// Inserts multiple entries, starting at `entry_index` onwards, each comprised of the multiple elements @@ -310,29 +324,29 @@ impl FlatVecDeque { /// Panics if `entry_index` is out of bounds. /// Panics if any of the value arrays in `entries` is empty. #[inline] - pub fn insert_range(&mut self, entry_index: usize, entries: impl IntoIterator>) { + pub fn insert_many(&mut self, entry_index: usize, entries: impl IntoIterator>) { let deque = Self::from_vecs(entries); - self.insert_with(entry_index, deque); + self.insert_deque(entry_index, deque); } /// Prepends another full deque to the deque. /// - /// This is the same as `self.insert_with(0, rhs)`. + /// This is the same as `self.insert_deque(0, rhs)`. /// - /// See [`Self::insert_with`] for more information. + /// See [`Self::insert_deque`] for more information. #[inline] - pub fn push_front_with(&mut self, rhs: FlatVecDeque) { - self.insert_with(0, rhs); + pub fn push_front_deque(&mut self, rhs: FlatVecDeque) { + self.insert_deque(0, rhs); } /// Appends another full deque to the deque. /// - /// This is the same as `self.insert_with(0, rhs)`. + /// This is the same as `self.insert_deque(0, rhs)`. /// - /// See [`Self::insert_with`] for more information. + /// See [`Self::insert_deque`] for more information. #[inline] - pub fn push_back_with(&mut self, rhs: FlatVecDeque) { - self.insert_with(self.num_entries(), rhs); + pub fn push_back_deque(&mut self, rhs: FlatVecDeque) { + self.insert_deque(self.num_entries(), rhs); } /// Inserts another full deque, starting at `entry_index` and onwards. @@ -343,7 +357,8 @@ impl FlatVecDeque { /// /// Panics if `entry_index` is out of bounds. /// Panics if any of the value arrays in `entries` is empty. - pub fn insert_with(&mut self, entry_index: usize, mut rhs: FlatVecDeque) { + pub fn insert_deque(&mut self, entry_index: usize, mut rhs: FlatVecDeque) { + // NOTE: We're inserting _beyond_ the last element. if entry_index == self.num_entries() { let max_value_offset = self.offsets.back().copied().unwrap_or_default(); self.offsets @@ -351,16 +366,16 @@ impl FlatVecDeque { self.values.extend(rhs.values); return; } else if entry_index == 0 { - rhs.push_back_with(std::mem::take(self)); + rhs.push_back_deque(std::mem::take(self)); *self = rhs; return; } let right = self.split_off(entry_index); - self.push_back_with(rhs); - self.push_back_with(right); + self.push_back_deque(rhs); + self.push_back_deque(right); - debug_assert!(!self.iter_offset_ranges().any(|or| or.start >= or.end)); + debug_assert!(self.iter_offset_ranges().all(|r| r.start < r.end)); } } @@ -371,19 +386,19 @@ fn insert() { assert_eq!(0, v.num_entries()); assert_eq!(0, v.num_values()); - v.insert(0, [1, 2, 3].into_iter()); + v.insert(0, [1, 2, 3]); assert_deque_eq(&[&[1, 2, 3]], &v); - v.insert(0, [4, 5, 6, 7].into_iter()); + v.insert(0, [4, 5, 6, 7]); assert_deque_eq(&[&[4, 5, 6, 7], &[1, 2, 3]], &v); - v.insert(0, [8, 9].into_iter()); + v.insert(0, [8, 9]); assert_deque_eq(&[&[8, 9], &[4, 5, 6, 7], &[1, 2, 3]], &v); - v.insert(2, [10, 11, 12, 13].into_iter()); + v.insert(2, [10, 11, 12, 13]); assert_deque_eq(&[&[8, 9], &[4, 5, 6, 7], &[10, 11, 12, 13], &[1, 2, 3]], &v); - v.insert(v.num_entries(), [14, 15].into_iter()); + v.insert(v.num_entries(), [14, 15]); assert_deque_eq( &[ &[8, 9], @@ -394,25 +409,52 @@ fn insert() { ], &v, ); + + v.insert(v.num_entries() - 1, [42]); + assert_deque_eq( + &[ + &[8, 9], + &[4, 5, 6, 7], + &[10, 11, 12, 13], + &[1, 2, 3], + &[42], + &[14, 15], + ], + &v, + ); +} + +#[test] +fn insert_empty() { + let mut v: FlatVecDeque = FlatVecDeque::new(); + + assert_eq!(0, v.num_entries()); + assert_eq!(0, v.num_values()); + + v.push_back([]); + v.push_back([]); + v.push_back([]); + + assert_deque_eq(&[&[], &[], &[]], &v); } #[test] -fn insert_range() { +fn insert_many() { let mut v: FlatVecDeque = FlatVecDeque::new(); assert_eq!(0, v.num_entries()); assert_eq!(0, v.num_values()); - v.insert_range(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); + v.insert_many(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7], &[8, 9, 10]], &v); - v.insert_range(0, [vec![20], vec![21], vec![22]]); + v.insert_many(0, [vec![20], vec![21], vec![22]]); assert_deque_eq( &[&[20], &[21], &[22], &[1, 2, 3], &[4, 5, 6, 7], &[8, 9, 10]], &v, ); - v.insert_range(4, [vec![41, 42], vec![43]]); + v.insert_many(4, [vec![41, 42], vec![43]]); assert_deque_eq( &[ &[20], @@ -427,7 +469,7 @@ fn insert_range() { &v, ); - v.insert_range(v.num_entries(), [vec![100], vec![200, 300, 400]]); + v.insert_many(v.num_entries(), [vec![100], vec![200, 300, 400]]); assert_deque_eq( &[ &[20], @@ -446,25 +488,25 @@ fn insert_range() { } #[test] -fn insert_with() { +fn insert_deque() { let mut v: FlatVecDeque = FlatVecDeque::new(); assert_eq!(0, v.num_entries()); assert_eq!(0, v.num_values()); - v.insert_with( + v.insert_deque( 0, FlatVecDeque::from_vecs([vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]), ); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7], &[8, 9, 10]], &v); - v.insert_with(0, FlatVecDeque::from_vecs([vec![20], vec![21], vec![22]])); + v.insert_deque(0, FlatVecDeque::from_vecs([vec![20], vec![21], vec![22]])); assert_deque_eq( &[&[20], &[21], &[22], &[1, 2, 3], &[4, 5, 6, 7], &[8, 9, 10]], &v, ); - v.insert_with(4, FlatVecDeque::from_vecs([vec![41, 42], vec![43]])); + v.insert_deque(4, FlatVecDeque::from_vecs([vec![41, 42], vec![43]])); assert_deque_eq( &[ &[20], @@ -479,7 +521,7 @@ fn insert_with() { &v, ); - v.insert_with( + v.insert_deque( v.num_entries(), FlatVecDeque::from_vecs([vec![100], vec![200, 300, 400]]), ); @@ -533,8 +575,8 @@ impl FlatVecDeque { /// Panics if `entry_index` is out of bounds. #[inline] pub fn truncate(&mut self, entry_index: usize) { - self.offsets.truncate(entry_index); self.values.truncate(self.value_offset(entry_index)); + self.offsets.truncate(entry_index); } /// Removes the entry at `entry_index` from the deque. @@ -549,11 +591,11 @@ impl FlatVecDeque { self.value_offset(entry_index), self.value_offset(entry_index + 1), ); - let offset_range = end_offset - start_offset; + let offset_count = end_offset - start_offset; - if entry_index == self.num_entries() { + if entry_index + 1 == self.num_entries() { self.offsets.truncate(self.num_entries() - 1); - self.values.truncate(self.values.len() - offset_range); + self.values.truncate(self.values.len() - offset_count); return; } else if entry_index == 0 { *self = self.split_off(entry_index + 1); @@ -563,15 +605,15 @@ impl FlatVecDeque { // NOTE: elegant, but way too slow :) // let right = self.split_off(entry_index + 1); // _ = self.split_off(self.num_entries() - 1); - // self.push_back_with(right); + // self.push_back_deque(right); _ = self.offsets.remove(entry_index); for offset in self.offsets.range_mut(entry_index..) { - *offset -= offset_range; + *offset -= offset_count; } let right = self.values.split_off(end_offset); - self.values.truncate(self.values.len() - offset_range); + self.values.truncate(self.values.len() - offset_count); self.values.extend(right); } @@ -580,21 +622,28 @@ impl FlatVecDeque { /// This is O(1) if `entry_range` either starts at the beginning of the deque, or ends at /// the end of the deque, or both. /// Otherwise, this requires splitting the deque into three pieces, dropping the superfluous - /// one, then stitching the two remaining pices back together. + /// one, then stitching the two remaining pieces back together. /// - /// Panics if `entry_range` is out of bounds. + /// Panics if `entry_range` is either out of bounds or isn't monotonically increasing. #[inline] pub fn remove_range(&mut self, entry_range: Range) { + assert!(entry_range.start <= entry_range.end); + + if entry_range.start == entry_range.end { + return; + } + let (start_offset, end_offset) = ( self.value_offset(entry_range.start), self.value_offset(entry_range.end), ); - let offset_range = end_offset - start_offset; + let offset_count = end_offset - start_offset; + // Reminder: `entry_range.end` is exclusive. if entry_range.end == self.num_entries() { self.offsets .truncate(self.num_entries() - entry_range.len()); - self.values.truncate(self.values.len() - offset_range); + self.values.truncate(self.values.len() - offset_count); return; } else if entry_range.start == 0 { *self = self.split_off(entry_range.end); @@ -603,7 +652,7 @@ impl FlatVecDeque { let right = self.split_off(entry_range.end); _ = self.split_off(self.num_entries() - entry_range.len()); - self.push_back_with(right); + self.push_back_deque(right); } } @@ -614,7 +663,7 @@ fn truncate() { assert_eq!(0, v.num_entries()); assert_eq!(0, v.num_values()); - v.insert_range(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); + v.insert_many(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7], &[8, 9, 10]], &v); { @@ -649,7 +698,7 @@ fn split_off() { assert_eq!(0, v.num_entries()); assert_eq!(0, v.num_values()); - v.insert_range(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); + v.insert_many(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7], &[8, 9, 10]], &v); { @@ -692,31 +741,31 @@ fn remove() { assert_eq!(0, v.num_entries()); assert_eq!(0, v.num_values()); - v.insert(0, [1, 2, 3].into_iter()); + v.insert(0, [1, 2, 3]); assert_deque_eq(&[&[1, 2, 3]], &v); v.remove(0); assert_deque_eq(&[], &v); - v.insert(0, [1, 2, 3].into_iter()); + v.insert(0, [1, 2, 3]); assert_deque_eq(&[&[1, 2, 3]], &v); - v.insert(1, [4, 5, 6, 7].into_iter()); + v.insert(1, [4, 5, 6, 7]); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7]], &v); - v.insert(2, [8, 9].into_iter()); + v.insert(2, [8, 9]); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7], &[8, 9]], &v); v.remove(0); assert_deque_eq(&[&[4, 5, 6, 7], &[8, 9]], &v); - v.insert(0, [1, 2, 3].into_iter()); + v.insert(0, [1, 2, 3]); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7], &[8, 9]], &v); v.remove(1); assert_deque_eq(&[&[1, 2, 3], &[8, 9]], &v); - v.insert(1, [4, 5, 6, 7].into_iter()); + v.insert(1, [4, 5, 6, 7]); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7], &[8, 9]], &v); v.remove(2); @@ -729,6 +778,34 @@ fn remove() { assert_deque_eq(&[], &v); } +#[test] +#[should_panic(expected = "Out of bounds access")] +fn remove_empty() { + let mut v: FlatVecDeque = FlatVecDeque::new(); + + assert_eq!(0, v.num_entries()); + assert_eq!(0, v.num_values()); + + v.remove(0); +} + +#[test] +#[should_panic(expected = "Out of bounds access")] +fn remove_oob() { + let mut v: FlatVecDeque = FlatVecDeque::new(); + + assert_eq!(0, v.num_entries()); + assert_eq!(0, v.num_values()); + + v.insert(0, [1, 2, 3]); + assert_deque_eq(&[&[1, 2, 3]], &v); + + assert_eq!(1, v.num_entries()); + assert_eq!(3, v.num_values()); + + v.remove(1); +} + #[test] fn remove_range() { let mut v: FlatVecDeque = FlatVecDeque::new(); @@ -736,7 +813,7 @@ fn remove_range() { assert_eq!(0, v.num_entries()); assert_eq!(0, v.num_values()); - v.insert_range(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); + v.insert_many(0, [vec![1, 2, 3], vec![4, 5, 6, 7], vec![8, 9, 10]]); assert_deque_eq(&[&[1, 2, 3], &[4, 5, 6, 7], &[8, 9, 10]], &v); {