use super::degree_sampling::DeterministicDegreeValues;
use super::set_sampling::CyclicStrideDegreeSets;
pub struct CyclicStrideDegreeSetGenerator {
k: usize,
degree_values: DeterministicDegreeValues,
sampler: CyclicStrideDegreeSets,
current_range: (usize, usize),
current_degree_set: Vec<Vec<usize>>,
}
impl CyclicStrideDegreeSetGenerator {
pub fn new(k: usize, cdf: Vec<u32>) -> Self {
let degree_values = DeterministicDegreeValues::new_from_cdf(cdf);
let sampler = CyclicStrideDegreeSets::new(k);
Self {
k,
degree_values,
sampler,
current_range: (0, 0),
current_degree_set: Vec::new(),
}
}
pub fn degree_set(&mut self, coded_id: usize) -> Vec<usize> {
let (start, end) = self.current_range;
if coded_id >= start && coded_id < end {
self.current_degree_set[coded_id - start].clone()
} else {
let degree = self
.degree_values
.additional_degrees(coded_id as u32, coded_id as u32 + self.k as u32);
self.current_range = (coded_id, coded_id + self.k);
self.current_degree_set = self.sampler.sample_sets(°ree);
self.current_degree_set[0].clone()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn tiny_cdf() -> Vec<u32> {
vec![0, 2, 4]
}
#[test]
fn cyclic_stride_generator_first_block_cached() {
let k = 4;
let mut g = CyclicStrideDegreeSetGenerator::new(k, tiny_cdf());
for id in 0..k {
let s = g.degree_set(id);
assert!(s.len() <= k, "degree set size should not exceed k");
}
}
#[test]
fn cyclic_stride_generator_second_block() {
let k = 4;
let mut g = CyclicStrideDegreeSetGenerator::new(k, tiny_cdf());
for id in 0..k {
let _ = g.degree_set(id);
}
let _ = g.degree_set(k);
}
}