AcctIdx: disk bucket cleanup (#21520)
This commit is contained in:
parent
f5b0764795
commit
f598ee696c
|
@ -185,7 +185,6 @@ impl<T: Clone + Copy> Bucket<T> {
|
||||||
key: &Pubkey,
|
key: &Pubkey,
|
||||||
elem_uid: Uid,
|
elem_uid: Uid,
|
||||||
random: u64,
|
random: u64,
|
||||||
ref_count: u64,
|
|
||||||
) -> Result<u64, BucketMapError> {
|
) -> Result<u64, BucketMapError> {
|
||||||
let ix = Self::bucket_index_ix(index, key, random);
|
let ix = Self::bucket_index_ix(index, key, random);
|
||||||
for i in ix..ix + index.max_search() {
|
for i in ix..ix + index.max_search() {
|
||||||
|
@ -196,7 +195,9 @@ impl<T: Clone + Copy> Bucket<T> {
|
||||||
index.allocate(ii, elem_uid).unwrap();
|
index.allocate(ii, elem_uid).unwrap();
|
||||||
let mut elem: &mut IndexEntry = index.get_mut(ii);
|
let mut elem: &mut IndexEntry = index.get_mut(ii);
|
||||||
elem.key = *key;
|
elem.key = *key;
|
||||||
elem.ref_count = ref_count;
|
// These will be overwritten after allocation by callers.
|
||||||
|
// Since this part of the mmapped file could have previously been used by someone else, there can be garbage here.
|
||||||
|
elem.ref_count = 0;
|
||||||
elem.storage_offset = 0;
|
elem.storage_offset = 0;
|
||||||
elem.storage_capacity_when_created_pow2 = 0;
|
elem.storage_capacity_when_created_pow2 = 0;
|
||||||
elem.num_slots = 0;
|
elem.num_slots = 0;
|
||||||
|
@ -218,14 +219,8 @@ impl<T: Clone + Copy> Bucket<T> {
|
||||||
Some(elem.ref_count)
|
Some(elem.ref_count)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_key(&self, key: &Pubkey, ref_count: u64) -> Result<u64, BucketMapError> {
|
fn create_key(&self, key: &Pubkey) -> Result<u64, BucketMapError> {
|
||||||
Self::bucket_create_key(
|
Self::bucket_create_key(&self.index, key, IndexEntry::key_uid(key), self.random)
|
||||||
&self.index,
|
|
||||||
key,
|
|
||||||
IndexEntry::key_uid(key),
|
|
||||||
self.random,
|
|
||||||
ref_count,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_value(&self, key: &Pubkey) -> Option<(&[T], RefCount)> {
|
pub fn read_value(&self, key: &Pubkey) -> Option<(&[T], RefCount)> {
|
||||||
|
@ -248,31 +243,26 @@ impl<T: Clone + Copy> Bucket<T> {
|
||||||
let index_entry = self.find_entry_mut(key);
|
let index_entry = self.find_entry_mut(key);
|
||||||
let (elem, elem_ix) = match index_entry {
|
let (elem, elem_ix) = match index_entry {
|
||||||
None => {
|
None => {
|
||||||
let ii = self.create_key(key, ref_count)?;
|
let ii = self.create_key(key)?;
|
||||||
let elem = self.index.get_mut(ii); // get_mut here is right?
|
let elem: &mut IndexEntry = self.index.get_mut(ii);
|
||||||
(elem, ii)
|
(elem, ii)
|
||||||
}
|
}
|
||||||
Some(res) => {
|
Some(res) => res,
|
||||||
if ref_count != res.0.ref_count {
|
|
||||||
res.0.ref_count = ref_count;
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
elem.ref_count = ref_count;
|
||||||
let elem_uid = self.index.uid(elem_ix);
|
let elem_uid = self.index.uid(elem_ix);
|
||||||
let bucket_ix = elem.data_bucket_ix();
|
let bucket_ix = elem.data_bucket_ix();
|
||||||
let current_bucket = &self.data[bucket_ix as usize];
|
let current_bucket = &self.data[bucket_ix as usize];
|
||||||
if best_fit_bucket == bucket_ix && elem.num_slots > 0 {
|
if best_fit_bucket == bucket_ix && elem.num_slots > 0 {
|
||||||
//in place update
|
// in place update
|
||||||
let elem_loc = elem.data_loc(current_bucket);
|
let elem_loc = elem.data_loc(current_bucket);
|
||||||
let slice: &mut [T] = current_bucket.get_mut_cell_slice(elem_loc, data.len() as u64);
|
let slice: &mut [T] = current_bucket.get_mut_cell_slice(elem_loc, data.len() as u64);
|
||||||
//let elem: &mut IndexEntry = self.index.get_mut(elem_ix);
|
|
||||||
assert!(current_bucket.uid(elem_loc) == elem_uid);
|
assert!(current_bucket.uid(elem_loc) == elem_uid);
|
||||||
elem.num_slots = data.len() as u64;
|
elem.num_slots = data.len() as u64;
|
||||||
slice.clone_from_slice(data);
|
slice.clone_from_slice(data);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
//need to move the allocation to a best fit spot
|
// need to move the allocation to a best fit spot
|
||||||
let best_bucket = &self.data[best_fit_bucket as usize];
|
let best_bucket = &self.data[best_fit_bucket as usize];
|
||||||
let cap_power = best_bucket.capacity_pow2;
|
let cap_power = best_bucket.capacity_pow2;
|
||||||
let cap = best_bucket.capacity();
|
let cap = best_bucket.capacity();
|
||||||
|
@ -284,7 +274,6 @@ impl<T: Clone + Copy> Bucket<T> {
|
||||||
if elem.num_slots > 0 {
|
if elem.num_slots > 0 {
|
||||||
current_bucket.free(elem_loc, elem_uid);
|
current_bucket.free(elem_loc, elem_uid);
|
||||||
}
|
}
|
||||||
// elem: &mut IndexEntry = self.index.get_mut(elem_ix);
|
|
||||||
elem.storage_offset = ix;
|
elem.storage_offset = ix;
|
||||||
elem.storage_capacity_when_created_pow2 = best_bucket.capacity_pow2;
|
elem.storage_capacity_when_created_pow2 = best_bucket.capacity_pow2;
|
||||||
elem.num_slots = data.len() as u64;
|
elem.num_slots = data.len() as u64;
|
||||||
|
@ -339,9 +328,7 @@ impl<T: Clone + Copy> Bucket<T> {
|
||||||
let uid = self.index.uid(ix);
|
let uid = self.index.uid(ix);
|
||||||
if UID_UNLOCKED != uid {
|
if UID_UNLOCKED != uid {
|
||||||
let elem: &IndexEntry = self.index.get(ix);
|
let elem: &IndexEntry = self.index.get(ix);
|
||||||
let ref_count = 0; // ??? TODO
|
let new_ix = Self::bucket_create_key(&index, &elem.key, uid, random);
|
||||||
let new_ix =
|
|
||||||
Self::bucket_create_key(&index, &elem.key, uid, random, ref_count);
|
|
||||||
if new_ix.is_err() {
|
if new_ix.is_err() {
|
||||||
valid = false;
|
valid = false;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue