mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-06 04:52:55 +00:00
Change finish_shrink to remap entries in shrunk space
This commit is contained in:
@@ -282,7 +282,7 @@ where
|
|||||||
inner.buckets = buckets;
|
inner.buckets = buckets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rehash the map. Intended for benchmarking only.
|
/// Rehash the map. Intended for benchmarking only.
|
||||||
pub fn shuffle(&mut self) {
|
pub fn shuffle(&mut self) {
|
||||||
let map = unsafe { self.shared_ptr.as_mut() }.unwrap();
|
let map = unsafe { self.shared_ptr.as_mut() }.unwrap();
|
||||||
let inner = &mut map.inner;
|
let inner = &mut map.inner;
|
||||||
@@ -352,7 +352,7 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Begin a shrink, limiting all new allocations to be in buckets with index less than `num_buckets`.
|
/// Begin a shrink, limiting all new allocations to be in buckets with index less than `num_buckets`.
|
||||||
pub fn begin_shrink(&mut self, num_buckets: u32) {
|
pub fn begin_shrink(&mut self, num_buckets: u32) {
|
||||||
let map = unsafe { self.shared_ptr.as_mut() }.unwrap();
|
let map = unsafe { self.shared_ptr.as_mut() }.unwrap();
|
||||||
if num_buckets > map.inner.get_num_buckets() as u32 {
|
if num_buckets > map.inner.get_num_buckets() as u32 {
|
||||||
@@ -377,32 +377,28 @@ where
|
|||||||
|
|
||||||
if inner.get_num_buckets() == num_buckets as usize {
|
if inner.get_num_buckets() == num_buckets as usize {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
} else if inner.get_num_buckets() > num_buckets as usize {
|
||||||
|
panic!("called finish_shrink before enough entries were removed");
|
||||||
|
}
|
||||||
|
|
||||||
for i in (num_buckets as usize)..inner.buckets.len() {
|
for i in (num_buckets as usize)..inner.buckets.len() {
|
||||||
if inner.buckets[i].inner.is_some() {
|
if let Some((k, v)) = inner.buckets[i].inner.take() {
|
||||||
// TODO(quantumish) Do we want to treat this as a violation of an invariant
|
inner.alloc_bucket(k, v, inner.buckets[i].prev.unwrap_first()).unwrap();
|
||||||
// or a legitimate error the caller can run into? Originally I thought this
|
} else {
|
||||||
// could return something like a UnevictedError(index) as soon as it runs
|
match inner.buckets[i].prev {
|
||||||
// into something (that way a caller could clear their soon-to-be-shrinked
|
PrevPos::First(_) => {
|
||||||
// buckets by repeatedly trying to call `finish_shrink`).
|
let next_pos = inner.buckets[i].next;
|
||||||
//
|
inner.free_head = next_pos;
|
||||||
// Would require making a wider error type enum with this and shmem errors.
|
if next_pos != INVALID_POS {
|
||||||
panic!("unevicted entries in shrinked space")
|
inner.buckets[next_pos as usize].prev = PrevPos::First(INVALID_POS);
|
||||||
}
|
}
|
||||||
match inner.buckets[i].prev {
|
},
|
||||||
PrevPos::First(_) => {
|
PrevPos::Chained(j) => {
|
||||||
let next_pos = inner.buckets[i].next;
|
let next_pos = inner.buckets[i].next;
|
||||||
inner.free_head = next_pos;
|
inner.buckets[j as usize].next = next_pos;
|
||||||
if next_pos != INVALID_POS {
|
if next_pos != INVALID_POS {
|
||||||
inner.buckets[next_pos as usize].prev = PrevPos::First(INVALID_POS);
|
inner.buckets[next_pos as usize].prev = PrevPos::Chained(j);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
PrevPos::Chained(j) => {
|
|
||||||
let next_pos = inner.buckets[i].next;
|
|
||||||
inner.buckets[j as usize].next = next_pos;
|
|
||||||
if next_pos != INVALID_POS {
|
|
||||||
inner.buckets[next_pos as usize].prev = PrevPos::Chained(j);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,6 +417,5 @@ where
|
|||||||
inner.alloc_limit = INVALID_POS;
|
inner.alloc_limit = INVALID_POS;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,15 @@ pub(crate) enum PrevPos {
|
|||||||
Chained(u32),
|
Chained(u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PrevPos {
|
||||||
|
pub fn unwrap_first(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
Self::First(i) => *i,
|
||||||
|
_ => panic!("not first entry in chain")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct OccupiedEntry<'a, 'b, K, V> {
|
pub struct OccupiedEntry<'a, 'b, K, V> {
|
||||||
pub(crate) map: &'b mut CoreHashMap<'a, K, V>,
|
pub(crate) map: &'b mut CoreHashMap<'a, K, V>,
|
||||||
pub(crate) _key: K, // The key of the occupied entry
|
pub(crate) _key: K, // The key of the occupied entry
|
||||||
|
|||||||
Reference in New Issue
Block a user