-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Naive garbage collection (Adopted) #11582
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -400,6 +400,45 @@ impl BlobVec { | |
std::slice::from_raw_parts(self.data.as_ptr() as *const UnsafeCell<T>, self.len) | ||
} | ||
|
||
/// Shrinks the backing storage for the [`BlobVec`] such that the `len == capacity`. | ||
/// | ||
/// This runs in `O(n)` time and may require reallocating backing buffer. | ||
pub fn shrink_to_fit(&mut self) { | ||
if self.item_layout.size() == 0 || self.len == self.capacity { | ||
return; | ||
} | ||
|
||
let current_layout = | ||
array_layout(&self.item_layout, self.capacity).expect("array layout should be valid"); | ||
self.data = if self.len == 0 { | ||
// SAFETY: | ||
// - layout has non-zero size as per safety requirement | ||
unsafe { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs a safety comment, as does the realloc below. If you need a reference, the safety comments on the allocation functions in |
||
std::alloc::dealloc(self.get_ptr_mut().as_ptr(), current_layout); | ||
} | ||
NonNull::dangling() | ||
} else { | ||
// SAFETY: | ||
// - ptr was be allocated via this allocator | ||
// - the layout of the ptr was `array_layout(self.item_layout, self.len)` | ||
// - `item_layout.size() > 0` and `new_capacity > 0`, so the layout size is non-zero | ||
// - "new_size, when rounded up to the nearest multiple of layout.align(), must not underflow (i.e., the rounded value must be more than usize::MIN)", | ||
// since the item size is always a multiple of its align, the rounding cannot happen | ||
// here and the underflow is handled in `array_layout` | ||
let new_layout = | ||
array_layout(&self.item_layout, self.len).expect("array layout should be valid"); | ||
let new_data = unsafe { | ||
std::alloc::realloc( | ||
self.get_ptr_mut().as_ptr(), | ||
current_layout, | ||
new_layout.size(), | ||
) | ||
}; | ||
NonNull::new(new_data).unwrap_or_else(|| handle_alloc_error(new_layout)) | ||
}; | ||
self.capacity = self.len; | ||
} | ||
|
||
/// Clears the vector, removing (and dropping) all values. | ||
/// | ||
/// Note that this method has no effect on the allocated capacity of the vector. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -323,6 +323,12 @@ impl ComponentSparseSet { | |
} | ||
} | ||
|
||
pub fn shrink_to_fit(&mut self) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably have a doc comment as it's actually usable outside of |
||
self.dense.shrink_to_fit(); | ||
self.entities.shrink_to_fit(); | ||
self.sparse.values.shrink_to_fit(); | ||
} | ||
|
||
pub(crate) fn check_change_ticks(&mut self, change_tick: Tick) { | ||
self.dense.check_change_ticks(change_tick); | ||
} | ||
|
@@ -610,6 +616,12 @@ impl SparseSets { | |
} | ||
} | ||
|
||
pub(crate) fn shrink_to_fit(&mut self) { | ||
for sparse_set in self.sets.values_mut() { | ||
sparse_set.shrink_to_fit(); | ||
} | ||
} | ||
|
||
pub(crate) fn check_change_ticks(&mut self, change_tick: Tick) { | ||
for set in self.sets.values_mut() { | ||
set.check_change_ticks(change_tick); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a test to this method, since everything else seems to depend on this? Some good things to test:
BlobVec
then shrinkingBlobVec
with a capacity of 0BlobVec
with a capacity >= 1 but a length of 0