From 51495cffb4f8878d55da5b301c3bb06f75c87d29 Mon Sep 17 00:00:00 2001 From: s1341 Date: Mon, 13 Sep 2021 17:43:14 +0300 Subject: [PATCH] Add shrink_to_fit Shamelessly stolen from https://github.com/fitzgen/generational-arena/pull/37 --- src/lib.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 7252d0e..f51a627 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -318,6 +318,35 @@ impl Arena { self.len = 0; } + /// Reduces allocated space to the minimum possible to fit all the elements in the arena. + /// + /// # Examples + /// + /// ``` + /// use generational_arena::Arena; + /// + /// let mut arena = Arena::new(); + /// arena.extend([1, 2, 3, 4, 5].iter().copied()); + /// assert!(arena.capacity() >= 5); + /// arena.shrink_to_fit(); + /// assert_eq!(arena.capacity(), 5); + /// ``` + pub fn shrink_to_fit(&mut self) { + self.items.truncate(self.items.iter().rposition(|entry| matches!(entry, Entry::Occupied { .. })).map(|n| n + 1).unwrap_or(0)); + self.items.shrink_to_fit(); + + self.free_list_head = None; + for (i, item) in self.items.iter_mut().enumerate() { + match item { + Entry::Occupied { .. } => (), + Entry::Free { next_free } => { + *next_free = self.free_list_head; + self.free_list_head = Some(i); + } + } + } + } + /// Attempts to insert `value` into the arena using existing capacity. /// /// This method will never allocate new capacity in the arena.