Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
beling committed Oct 3, 2024
1 parent 3553f6b commit 5e8ddca
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 21 deletions.
5 changes: 5 additions & 0 deletions csf/src/fp/collision_solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ pub trait CollisionSolver {
/// Try to assign `value` (of size `bits_per_value`) to the given `index` which is not under collision.
fn add_value(&mut self, index: usize, value: u8, bits_per_value: u8);

/// If the index is not under collision then try to assign `value` (of size `bits_per_value`) to them.
#[inline] fn process_value(&mut self, index: usize, value: u8, bits_per_value: u8) {
if !self.is_under_collision(index) { self.add_value(index, value, bits_per_value); }
}

/// Array that shows indices which have assigned values and are not under collision.
fn to_collision_array(self) -> Box<[u64]>;

Expand Down
13 changes: 13 additions & 0 deletions csf/src/fp/kvset.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::bits_to_store_any_of_ref;

use super::CollisionSolver;

/// Moves all non-zeros to the begging of `values` and returns their number.
pub fn remove_zeros(values: &mut [usize]) -> usize {
let mut new_len: usize = 0usize;
Expand All @@ -23,6 +25,17 @@ pub trait KVSet<K> {
/// If `self` doesn't remember which keys are retained it uses `retained_hint` to check this.
fn for_each_key_value<F>(&self, f: F/*, retained_hint: P*/) where F: FnMut(&K, u8)/*, P: FnMut(&K) -> bool*/;

/// Call `collision_solver.process_value(key_to_index(key), value, self.bits_per_value())` for each `key`-`value` pair.
#[inline]
fn process_all_values<I, CS>(&self, mut key_to_index: I, collision_solver: &mut CS)
where I: FnMut(&K) -> usize, CS: CollisionSolver
{
let bits_per_value = self.bits_per_value();
self.for_each_key_value(|key, value| {
collision_solver.process_value(key_to_index(key), value, bits_per_value);
});
}

/// Returns minimal number of bits that can store any value.
fn bits_per_value(&self) -> u8;

Expand Down
1 change: 0 additions & 1 deletion csf/src/fp/map/conf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ pub struct MapConf<
LSC = OptimalLevelSize,
CSB: CollisionSolverBuilder = LoMemAcceptEquals,
S: BuildSeededHasher = BuildDefaultSeededHasher
/*, BS: stats::BuildStatsCollector = ()*/
> {
/// Choose the size of each level.
pub level_sizer: LSC,
Expand Down
32 changes: 12 additions & 20 deletions csf/src/fp/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct Map<S = BuildDefaultSeededHasher> {
values: Box<[u64]>, // BitVec
bits_per_value: u8,
level_sizes: Box<[u64]>,
hash_builder: S
hash: S
}

impl<S: BuildSeededHasher> GetSize for Map<S> {
Expand All @@ -37,19 +37,20 @@ impl<S: BuildSeededHasher> GetSize for Map<S> {
const USES_DYN_MEM: bool = true;
}

impl<S: BuildSeededHasher> Map<S> {
#[inline]
fn index<H: BuildSeededHasher, K: Hash>(hash: &H, k: &K, level_nr: u32, level_size: usize) -> usize {
ph::utils::map64_to_64(hash.hash_one(k, level_nr), level_size as u64) as usize
}

#[inline(always)] fn index<K: Hash>(&self, k: &K, level_nr: u32, size: usize) -> usize {
utils::map64_to_64(self.hash_builder.hash_one(k, level_nr), size as u64) as usize
}
impl<S: BuildSeededHasher> Map<S> {

/// Gets the value associated with the given key k and reports statistics to access_stats.
pub fn get_stats<K: Hash, A: stats::AccessStatsCollector>(&self, k: &K, access_stats: &mut A) -> Option<u8> {
let mut array_begin_index = 0usize;
let mut level = 0u32;
loop {
let level_size = (*self.level_sizes.get(level as usize)? as usize) << 6usize;
let i = array_begin_index + self.index(k, level, level_size);
let i = array_begin_index + index(&self.hash, k, level, level_size);
if self.array.content.get_bit(i) {
access_stats.found_on_level(level);
return Some(self.values.get_fragment(self.array.rank(i), self.bits_per_value) as u8);
Expand Down Expand Up @@ -90,19 +91,10 @@ impl<S: BuildSeededHasher> Map<S> {
let level_size_segments = conf.level_sizer.size_segments(&kv);
let level_size = level_size_segments * 64;
stats.level(input_size, level_size);
let mut collision_solver = conf.collision_solver.new(level_size_segments, bits_per_value);
kv.for_each_key_value(|k, v| { // TODO ?? move this code to kv method
let a_index = utils::map64_to_64(conf.hash.hash_one(k, level_nr), level_size as u64) as usize;
if !collision_solver.is_under_collision(a_index) {
collision_solver.add_value(a_index, v, bits_per_value);
}
});
let mut collision_solver: <CSB as CollisionSolverBuilder>::CollisionSolver = conf.collision_solver.new(level_size_segments, bits_per_value);
kv.process_all_values(|k| index(&conf.hash, k, level_nr, level_size), &mut collision_solver);
let (current_array, current_values, current_values_len) = collision_solver.to_collision_and_values(bits_per_value);
kv.retain_keys(|k| {
!current_array.get_bit(
utils::map64_to_64(conf.hash.hash_one(k, level_nr), level_size as u64) as usize
)
});
kv.retain_keys(|k| !current_array.get_bit(index(&conf.hash, k, level_nr, level_size)));
arrays.push(current_array);
level_sizes.push(level_size_segments as u64);
values.push(current_values);
Expand All @@ -117,7 +109,7 @@ impl<S: BuildSeededHasher> Map<S> {
values: concatenate_values(&values, &values_lens, bits_per_value),
bits_per_value,
level_sizes: level_sizes.into_boxed_slice(),
hash_builder: conf.hash
hash: conf.hash
}
}

Expand Down Expand Up @@ -240,7 +232,7 @@ impl<S: BuildSeededHasher> Map<S> {
values,
bits_per_value,
level_sizes,
hash_builder: hasher
hash: hasher
})
}
}
Expand Down

0 comments on commit 5e8ddca

Please sign in to comment.