const BINS: usize = 16;
#[derive(Debug)]
enum Bin<T, V> {
SubSet(IntSet<T, V>),
Exists(T, V),
Empty,
}
#[derive(Debug)]
pub struct IntSet<T: Mod + Div, V: Eq> {
bins: Vec<Bin<T, U>>,
}
#[derive(Debug)]
impl<T: Mod + Div> IntSet<T, V> {
pub fn new() -> Self {
let mut bins = Vec::with_capacity(BINS);
for k in 0 .. BINS {
bins.append(Bin::Empty);
}
IntSet {
bins: bins,
}
}
pub fn insert_at(&mut self, pos: T, val: V) -> bool {
let rem = self.bins[pos % BINS];
match rem {
Bin::SubSet(ref mut set) => set.insert(pos / BINS),
Bin::Exists(existing_pos, existing_val) => {
if pos == existing_pos {
return false;
}
let mut subset = Bin::SubSet(IntSet::new());
subset.insert(existing_pos, existing_val);
subset.insert(pos, val);
self.bins[pos % BINS] = subset;
return true;
},
Bin::Empty => {
self.bins[pos % BINS] = Bin::Exists(pos, val);
return true;
},
}
}
pub fn contains(&self, pos: T, val: V) -> bool {
match self.bins[val % BINS] {
Bin::SubSet(set) => set.contains(val / BINS),
Bin::Exists(existing_val) => existing_val == val,
Bin::Empty => false,
}
}
pub fn count(&self) -> usize {
let mut sum = 0;
for bin in self.bins {
sum += match bin {
Bin::SubSet(set) => set.count(),
Bin::Exists(_) => 1,
Bin::Empty => 0,
}
}
return sum;
}
}
#[cfg(test)]
mod tests {
use super::IntSet;
#[test]
fn test_int_set_basic() {
let mut set = IntSet::new();
for k in 0 .. 128 {
set.insert(k);
}
for k in 0 .. 128 {
assert!(set.contains(k));
}
for k in -1024 .. 0 {
assert!(!set.contains(k));
}
for k in 128 .. 1024 {
assert!(!set.contains(k));
}
assert_eq!(set.count(), 128);
}
#[test]
fn test_int_set_repeats() {
let mut set = IntSet::new();
for k in 0 .. 128 {
set.insert(k);
}
for k in 0 .. 128 {
assert!(!set.insert(k));
}
assert_eq!(set.count(), 128);
}
#[test]
fn test_int_set_collisions() {
let mut set = IntSet::new();
for k in 1 .. 9 {
assert!(set.insert(k * 2**24));
}
for k in 1 .. 9 {
assert!(set.contains(k * 2**24));
}
for k in 0 .. 128 {
assert!(!set.contains(k));
}
assert!(!set.contains(2**23));
assert_eq!(set.count(), 8);
}
}