mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
Double the capacity when BlobVec is full (#11167)
# Objective - Fixes #10797 ## Solution - Double the capacity of a full `BlobVec` before pushing a new element.
This commit is contained in:
parent
eb07d16871
commit
8ad1b93e63
1 changed files with 22 additions and 5 deletions
|
@ -124,6 +124,23 @@ impl BlobVec {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reserves the minimum capacity for at least `additional` more elements to be inserted in the given `BlobVec`.
|
||||||
|
#[inline]
|
||||||
|
pub fn reserve(&mut self, additional: usize) {
|
||||||
|
/// Similar to `reserve_exact`. This method ensures that the capacity will grow at least `self.capacity()` if there is no
|
||||||
|
/// enough space to hold `additional` more elements.
|
||||||
|
#[cold]
|
||||||
|
fn do_reserve(slf: &mut BlobVec, additional: usize) {
|
||||||
|
let increment = slf.capacity.max(additional - (slf.capacity - slf.len));
|
||||||
|
let increment = NonZeroUsize::new(increment).unwrap();
|
||||||
|
slf.grow_exact(increment);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.capacity - self.len < additional {
|
||||||
|
do_reserve(self, additional);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Grows the capacity by `increment` elements.
|
/// Grows the capacity by `increment` elements.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
|
@ -241,7 +258,7 @@ impl BlobVec {
|
||||||
/// The `value` must match the [`layout`](`BlobVec::layout`) of the elements in the [`BlobVec`].
|
/// The `value` must match the [`layout`](`BlobVec::layout`) of the elements in the [`BlobVec`].
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn push(&mut self, value: OwningPtr<'_>) {
|
pub unsafe fn push(&mut self, value: OwningPtr<'_>) {
|
||||||
self.reserve_exact(1);
|
self.reserve(1);
|
||||||
let index = self.len;
|
let index = self.len;
|
||||||
self.len += 1;
|
self.len += 1;
|
||||||
self.initialize_unchecked(index, value);
|
self.initialize_unchecked(index, value);
|
||||||
|
@ -530,7 +547,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(blob_vec.len(), 1_000);
|
assert_eq!(blob_vec.len(), 1_000);
|
||||||
assert_eq!(blob_vec.capacity(), 1_000);
|
assert_eq!(blob_vec.capacity(), 1_024);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone)]
|
#[derive(Debug, Eq, PartialEq, Clone)]
|
||||||
|
@ -590,19 +607,19 @@ mod tests {
|
||||||
|
|
||||||
push(&mut blob_vec, foo3.clone());
|
push(&mut blob_vec, foo3.clone());
|
||||||
assert_eq!(blob_vec.len(), 3);
|
assert_eq!(blob_vec.len(), 3);
|
||||||
assert_eq!(blob_vec.capacity(), 3);
|
assert_eq!(blob_vec.capacity(), 4);
|
||||||
|
|
||||||
let last_index = blob_vec.len() - 1;
|
let last_index = blob_vec.len() - 1;
|
||||||
let value = swap_remove::<Foo>(&mut blob_vec, last_index);
|
let value = swap_remove::<Foo>(&mut blob_vec, last_index);
|
||||||
assert_eq!(foo3, value);
|
assert_eq!(foo3, value);
|
||||||
|
|
||||||
assert_eq!(blob_vec.len(), 2);
|
assert_eq!(blob_vec.len(), 2);
|
||||||
assert_eq!(blob_vec.capacity(), 3);
|
assert_eq!(blob_vec.capacity(), 4);
|
||||||
|
|
||||||
let value = swap_remove::<Foo>(&mut blob_vec, 0);
|
let value = swap_remove::<Foo>(&mut blob_vec, 0);
|
||||||
assert_eq!(foo1, value);
|
assert_eq!(foo1, value);
|
||||||
assert_eq!(blob_vec.len(), 1);
|
assert_eq!(blob_vec.len(), 1);
|
||||||
assert_eq!(blob_vec.capacity(), 3);
|
assert_eq!(blob_vec.capacity(), 4);
|
||||||
|
|
||||||
foo2.a = 8;
|
foo2.a = 8;
|
||||||
assert_eq!(get_mut::<Foo>(&mut blob_vec, 0), &foo2);
|
assert_eq!(get_mut::<Foo>(&mut blob_vec, 0), &foo2);
|
||||||
|
|
Loading…
Reference in a new issue