diff --git a/Cargo.lock b/Cargo.lock index 9e3d014ba..edc9ef28b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5031,6 +5031,7 @@ dependencies = [ name = "solana-bucket-map" version = "1.16.0" dependencies = [ + "bv", "fs_extra", "log", "memmap2", diff --git a/bucket_map/Cargo.toml b/bucket_map/Cargo.toml index 5da8fb56a..956bc3ad0 100644 --- a/bucket_map/Cargo.toml +++ b/bucket_map/Cargo.toml @@ -11,6 +11,7 @@ license = { workspace = true } edition = { workspace = true } [dependencies] +bv = { workspace = true, features = ["serde"] } log = { workspace = true } memmap2 = { workspace = true } modular-bitfield = { workspace = true } diff --git a/bucket_map/src/bucket_storage.rs b/bucket_map/src/bucket_storage.rs index f5cf3d83c..12373c8ce 100644 --- a/bucket_map/src/bucket_storage.rs +++ b/bucket_map/src/bucket_storage.rs @@ -205,12 +205,6 @@ impl BucketStorage { unsafe { &mut *item } } - pub(crate) fn get_from_parts(item_slice: &[u8]) -> &T { - assert!(std::mem::size_of::() <= item_slice.len()); - let item = item_slice.as_ptr() as *const T; - unsafe { &*item } - } - pub fn get_mut(&mut self, ix: u64) -> &mut T { let start = self.get_start_offset_no_header(ix); let item_slice = &mut self.mmap[start..]; diff --git a/bucket_map/src/index_entry.rs b/bucket_map/src/index_entry.rs index 1e9c4817d..4cfb14afe 100644 --- a/bucket_map/src/index_entry.rs +++ b/bucket_map/src/index_entry.rs @@ -6,6 +6,7 @@ use { bucket_storage::{BucketOccupied, BucketStorage}, RefCount, }, + bv::BitVec, modular_bitfield::prelude::*, solana_sdk::{clock::Slot, pubkey::Pubkey}, std::fmt::Debug, @@ -25,38 +26,35 @@ struct OccupiedHeader { } /// allocated in `contents` in a BucketStorage -pub struct BucketWithHeader {} +pub struct BucketWithBitVec { + pub occupied: BitVec, +} -impl BucketOccupied for BucketWithHeader { - fn occupy(&mut self, element: &mut [u8], _ix: usize) { - let entry: &mut OccupiedHeader = - BucketStorage::::get_mut_from_parts(element); - assert_eq!(entry.occupied, OCCUPIED_FREE); - entry.occupied = OCCUPIED_OCCUPIED; +impl BucketOccupied for BucketWithBitVec { + fn occupy(&mut self, element: &mut [u8], ix: usize) { + assert!(self.is_free(element, ix)); + self.occupied.set(ix as u64, true); } - fn free(&mut self, element: &mut [u8], _ix: usize) { - let entry: &mut OccupiedHeader = - BucketStorage::::get_mut_from_parts(element); - assert_eq!(entry.occupied, OCCUPIED_OCCUPIED); - entry.occupied = OCCUPIED_FREE; + fn free(&mut self, element: &mut [u8], ix: usize) { + assert!(!self.is_free(element, ix)); + self.occupied.set(ix as u64, false); } - fn is_free(&self, element: &[u8], _ix: usize) -> bool { - let entry: &OccupiedHeader = BucketStorage::::get_from_parts(element); - let free = entry.occupied == OCCUPIED_FREE; - assert!(free || entry.occupied == OCCUPIED_OCCUPIED); - free + fn is_free(&self, _element: &[u8], ix: usize) -> bool { + !self.occupied.get(ix as u64) } fn offset_to_first_data() -> usize { - std::mem::size_of::() + // no header, nothing stored in data stream + 0 } - /// initialize this struct - fn new(_num_elements: usize) -> Self { - Self {} + fn new(num_elements: usize) -> Self { + Self { + occupied: BitVec::new_fill(false, num_elements as u64), + } } } -pub type DataBucket = BucketWithHeader; -pub type IndexBucket = BucketWithHeader; +pub type DataBucket = BucketWithBitVec; +pub type IndexBucket = BucketWithBitVec; #[repr(C)] #[derive(Debug, Copy, Clone, PartialEq, Eq)] diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index f52903478..246bffede 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -4466,6 +4466,7 @@ dependencies = [ name = "solana-bucket-map" version = "1.16.0" dependencies = [ + "bv", "log", "memmap2", "modular-bitfield",