diff --git a/bucket_map/src/bucket.rs b/bucket_map/src/bucket.rs index be0d1a831..1f9668030 100644 --- a/bucket_map/src/bucket.rs +++ b/bucket_map/src/bucket.rs @@ -447,6 +447,7 @@ impl<'b, T: Clone + Copy + 'static> Bucket { let new_ix = new_ix.unwrap(); let new_elem: &mut IndexEntry = index.get_mut(new_ix); *new_elem = *elem; + index.copying_entry(new_ix, &self.index, ix); /* let dbg_elem: IndexEntry = *new_elem; assert_eq!( diff --git a/bucket_map/src/bucket_storage.rs b/bucket_map/src/bucket_storage.rs index 7b6a8482f..3bded3578 100644 --- a/bucket_map/src/bucket_storage.rs +++ b/bucket_map/src/bucket_storage.rs @@ -51,6 +51,17 @@ pub trait BucketOccupied { /// initialize this struct /// `num_elements` is the number of elements allocated in the bucket fn new(num_elements: usize) -> Self; + /// copying entry. Any in-memory (per-bucket) data structures may need to be copied for this `ix_old`. + /// no-op by default + fn copying_entry( + &mut self, + _element_new: &mut [u8], + _ix_new: usize, + _other: &Self, + _element_old: &[u8], + _ix_old: usize, + ) { + } } pub struct BucketStorage { @@ -130,6 +141,18 @@ impl BucketStorage { ) } + pub(crate) fn copying_entry(&mut self, ix_new: u64, other: &Self, ix_old: u64) { + let start = self.get_start_offset_with_header(ix_new); + let start_old = other.get_start_offset_with_header(ix_old); + self.contents.copying_entry( + &mut self.mmap[start..], + ix_new as usize, + &other.contents, + &other.mmap[start_old..], + ix_old as usize, + ); + } + /// true if the entry at index 'ix' is free (as opposed to being occupied) pub fn is_free(&self, ix: u64) -> bool { let start = self.get_start_offset_with_header(ix); @@ -294,6 +317,8 @@ impl BucketStorage { let index_grow = 1 << increment; (0..old_cap as usize).for_each(|i| { if !old_bucket.is_free(i as u64) { + self.copying_entry((i * index_grow) as u64, old_bucket, i as u64); + { // copying from old to new. If 'occupied' bit is stored outside the data, then // occupied has to be set on the new entry in the new bucket.