use succinct::stream::{BitBuffer};
use succinct::BitVector;
use succinct::bit_vec::BitVecMut;
use succinct::rank::{JacobsonRank, RankSupport};
use rand::distributions::WeightedIndex;
use rand::prelude::*;
use std::time::Instant;
fn main() {
// Preprocessing
let keys: Vec<usize> = vec![0,32,48,52,54,56,58,60,62,63];
let vals: Vec<(u8,u8)> = vec![(0,1),(1,2),(2,4),(3,5),(4,5),(5,5),(6,5),(7,5),(8,6),(9,6)];
// Generation of BitVector
let mut bv: BitVector<usize> = BitVector::with_fill(keys[keys.len()-1] as u64 +1, false);
for k in keys {
bv.set_bit(k as u64, true);
}
let jbv = JacobsonRank::new(bv);
// Generation of random values for lookup with rank operation
let size = 770_044;
let look_up_values = get_lookup_values(size);
// Actual lookup
let now = Instant::now();
for val in look_up_values {
vals[jbv.rank(val as u64, true) as usize];
}
// Timing
let time = now.elapsed().as_secs_f32();
let throughput = size as f32 / time / 1024f32 / 1024f32;
println!("Elapsed: {} ({} MiB/s)", time, throughput);
}
/// Generates vector of values to be looked up in BitVector
fn get_lookup_values(size: usize) -> Vec<u8> {
let words: Vec<u8> = vec![20, 17, 6, 3, 2, 2, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
];
generate_random_byte_vector(0, words.len() as u8, size, &words)
}
fn generate_random_byte_vector(min: u8, max: u8, count: usize, weights: &[u8]) -> Vec<u8> {
let mut rng = rand::thread_rng();
let choices: Vec<_> = (min..max).collect();
let dist = WeightedIndex::new(weights).unwrap();
assert_eq!(choices.len(), weights.len());
(0..count).map(|_| choices[dist.sample(&mut rng)]).collect()
}