Skip to content

Commit

Permalink
disk index: break ref_count u64 into reserved bits (#30997)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffwashington authored Mar 31, 2023
1 parent 24f81be commit 3f6c33d
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 11 deletions.
2 changes: 1 addition & 1 deletion bucket_map/src/bucket_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ mod tests {
let v = (0..count)
.map(|x| (x as usize, x as usize /*thread_rng().gen::<usize>()*/))
.collect::<Vec<_>>();
let rc = thread_rng().gen::<RefCount>();
let rc = thread_rng().gen_range(0, RefCount::MAX >> 2);
(v, rc)
};

Expand Down
2 changes: 1 addition & 1 deletion bucket_map/src/bucket_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ mod test {
let mut storage = BucketStorage::<IndexBucket<u64>>::new(
Arc::new(paths),
1,
1,
std::mem::size_of::<crate::index_entry::IndexEntry<u64>>() as u64,
1,
Arc::default(),
Arc::default(),
Expand Down
32 changes: 23 additions & 9 deletions bucket_map/src/index_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,23 +66,34 @@ pub struct IndexEntryPlaceInBucket<T: 'static> {

#[repr(C)]
#[derive(Copy, Clone)]
// one instance of this per item in the index
// stored in the index bucket
/// one instance of this per item in the index
/// stored in the index bucket
pub struct IndexEntry<T: 'static> {
pub key: Pubkey, // can this be smaller if we have reduced the keys into buckets already?
ref_count: RefCount, // can this be smaller? Do we ever need more than 4B refcounts?
pub(crate) key: Pubkey, // can this be smaller if we have reduced the keys into buckets already?
packed_ref_count: PackedRefCount,
multiple_slots: MultipleSlots,
_phantom: PhantomData<&'static T>,
}

/// hold a big `RefCount` while leaving room for extra bits to be used for things like 'Occupied'
#[bitfield(bits = 64)]
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
struct PackedRefCount {
/// reserved for future use
unused: B2,
/// ref_count of this entry. We don't need any where near 62 bits for this value
ref_count: B62,
}

/// required fields when an index element references the data file
#[repr(C)]
#[derive(Debug, Default, Copy, Clone)]
pub(crate) struct MultipleSlots {
// if the bucket doubled, the index can be recomputed using storage_cap_and_offset.create_bucket_capacity_pow2
storage_cap_and_offset: PackedStorage,
/// num elements in the slot list
num_slots: Slot, // can this be smaller? epoch size should ~ be the max len. this is the num elements in the slot list
num_slots: Slot,
}

impl MultipleSlots {
Expand Down Expand Up @@ -154,7 +165,7 @@ impl<T> IndexEntryPlaceInBucket<T> {
pub fn init(&self, index_bucket: &mut BucketStorage<IndexBucket<T>>, pubkey: &Pubkey) {
let index_entry = index_bucket.get_mut::<IndexEntry<T>>(self.ix);
index_entry.key = *pubkey;
index_entry.ref_count = 0;
index_entry.packed_ref_count.set_ref_count(0);
index_entry.multiple_slots = MultipleSlots::default();
}

Expand Down Expand Up @@ -194,7 +205,7 @@ impl<T> IndexEntryPlaceInBucket<T> {

pub fn ref_count(&self, index_bucket: &BucketStorage<IndexBucket<T>>) -> RefCount {
let index_entry = index_bucket.get::<IndexEntry<T>>(self.ix);
index_entry.ref_count
index_entry.packed_ref_count.ref_count()
}

pub fn read_value<'a>(
Expand Down Expand Up @@ -235,7 +246,10 @@ impl<T> IndexEntryPlaceInBucket<T> {
ref_count: RefCount,
) {
let index_entry = index_bucket.get_mut::<IndexEntry<T>>(self.ix);
index_entry.ref_count = ref_count;
index_entry
.packed_ref_count
.set_ref_count_checked(ref_count)
.expect("ref count must fit into 62 bits!");
}
}

Expand All @@ -251,7 +265,7 @@ mod tests {
pub fn new(key: Pubkey) -> Self {
IndexEntry {
key,
ref_count: 0,
packed_ref_count: PackedRefCount::default(),
multiple_slots: MultipleSlots::default(),
_phantom: PhantomData,
}
Expand Down

0 comments on commit 3f6c33d

Please sign in to comment.