Skip to content

Commit 18e244a

Browse files
slight optimisations
1 parent 1d7f818 commit 18e244a

File tree

1 file changed

+36
-15
lines changed

1 file changed

+36
-15
lines changed

src/lib.rs

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ where
476476
{
477477
/// Inserts each `(K, V)` pair into the map by pushing the value into the foreground layer.
478478
///
479-
/// This behaves the same as calling [`push`] for each element in the iterator. If a key
479+
/// This behaves the same as calling push for each element in the iterator. If a key
480480
/// already exists, the current foreground value is moved to the background, and the
481481
/// new value becomes the foreground. If the key is new, it is inserted.
482482
///
@@ -865,14 +865,12 @@ impl<T> Overlay<T> {
865865
#[inline]
866866
pub fn pull(&mut self) -> Option<T> {
867867
let fgi = self.fg_index();
868-
if !self.is_slot_present(fgi) {
869-
return None;
868+
if self.is_slot_present(fgi) {
869+
self.bits ^= FG_SLOT | (1 << fgi);
870+
Some(unsafe { self.slots[fgi].assume_init_read() })
871+
} else {
872+
None
870873
}
871-
872-
let evicted = unsafe { self.slots[fgi].assume_init_read() };
873-
self.bits &= !(1 << fgi);
874-
self.flip_unchecked();
875-
Some(evicted)
876874
}
877875

878876
/// Pull the current foreground value without checking if it is present.
@@ -894,10 +892,8 @@ impl<T> Overlay<T> {
894892
#[inline]
895893
pub fn pull_unchecked(&mut self) -> T {
896894
let fgi = self.fg_index();
897-
let evicted = unsafe { self.slots[fgi].assume_init_read() };
898-
self.bits &= !(1 << fgi);
899-
self.flip_unchecked();
900-
evicted
895+
self.bits ^= FG_SLOT | (1 << fgi);
896+
unsafe { self.slots[fgi].assume_init_read() }
901897
}
902898

903899
/// Swap in a new foreground value, returning the old background if present.
@@ -981,12 +977,37 @@ impl<T> Overlay<T> {
981977
/// ```
982978
#[inline]
983979
pub fn flip(&mut self) {
984-
let mask = ((self.bits & SLOT_MASK) >> 1) & 1;
985-
self.bits ^= mask << 2;
980+
if (self.bits & SLOT_MASK) == SLOT_MASK {
981+
self.bits ^= FG_SLOT;
982+
}
986983
}
987984

985+
/// Flips the foreground and background slots **without checking** if both are present.
986+
///
987+
/// This is the unchecked, zero-cost variant of [`flip`](Self::flip), intended for internal
988+
/// or performance-critical use when it is already known that both slots contain valid values.
989+
///
990+
/// This method **does not perform any presence checks**. If one of the slots is uninitialized,
991+
/// calling this method results in **undefined behavior** when those slots are later accessed.
992+
///
993+
/// # Safety
994+
///
995+
/// The caller must guarantee that:
996+
///
997+
/// - Both slots (foreground and background) are currently initialized.
998+
/// - A subsequent use of `fg_unchecked` or `bg_unchecked` will not access uninitialized memory.
999+
///
1000+
/// # Example
1001+
/// ```
1002+
/// use overlay_map::Overlay;
1003+
///
1004+
/// let mut entry = Overlay::new_both("a", "b");
1005+
/// entry.flip_unchecked(); // swaps roles without checks
1006+
/// assert_eq!(entry.fg(), Some(&"b"));
1007+
/// assert_eq!(entry.bg(), Some(&"a"));
1008+
/// ```
9881009
#[inline]
989-
fn flip_unchecked(&mut self) {
1010+
pub fn flip_unchecked(&mut self) {
9901011
self.bits ^= FG_SLOT;
9911012
}
9921013

0 commit comments

Comments
 (0)