Skip to content

Instantly share code, notes, and snippets.

@haudan
Created March 20, 2018 22:12
Show Gist options
  • Select an option

  • Save haudan/85e59375b625db72fe6fe7647a2675d3 to your computer and use it in GitHub Desktop.

Select an option

Save haudan/85e59375b625db72fe6fe7647a2675d3 to your computer and use it in GitHub Desktop.
BitSet (aka BitMap) container based on 128bit integers. Can store values 0..1024
#![feature(i128_type)]
struct BitSet {
ints: [u128; 8],
}
impl BitSet {
fn new() -> Self {
Self {
ints: [0; 8],
}
}
fn iter(&self) -> BitSetIter {
BitSetIter {
set: self,
cur_int: 0,
cur_bit: 0,
}
}
fn insert(&mut self, val: u16) {
assert!(val < 1024);
let int = unsafe { self.ints.get_unchecked_mut((val / 128) as usize) };
*int |= 1 << val % 128;
}
fn union(lhs: &BitSet, rhs: &BitSet) -> BitSet {
Self {
ints: [
unsafe { lhs.ints.get_unchecked(0) & rhs.ints.get_unchecked(0) },
unsafe { lhs.ints.get_unchecked(1) & rhs.ints.get_unchecked(1) },
unsafe { lhs.ints.get_unchecked(2) & rhs.ints.get_unchecked(2) },
unsafe { lhs.ints.get_unchecked(3) & rhs.ints.get_unchecked(3) },
unsafe { lhs.ints.get_unchecked(4) & rhs.ints.get_unchecked(4) },
unsafe { lhs.ints.get_unchecked(5) & rhs.ints.get_unchecked(5) },
unsafe { lhs.ints.get_unchecked(6) & rhs.ints.get_unchecked(6) },
unsafe { lhs.ints.get_unchecked(7) & rhs.ints.get_unchecked(7) },
],
}
}
}
struct BitSetIter<'a> {
set: &'a BitSet,
cur_int: usize,
cur_bit: usize,
}
impl<'a> Iterator for BitSetIter<'a> {
type Item = u16;
fn next(&mut self) -> Option<Self::Item> {
loop {
if self.cur_bit >= 127 {
self.cur_bit = 0;
self.cur_int += 1;
}
if self.cur_int < 8 {
let int = unsafe { self.set.ints.get_unchecked(self.cur_int) };
let bit = self.cur_bit;
let val = (*int) & (1 << bit);
self.cur_bit += 1;
if val > 0 {
break Some(bit as u16 + 128 * self.cur_int as u16);
}
} else {
break None;
}
}
}
}
fn main() {
let mut set = BitSet::new();
set.insert(0);
set.insert(1);
set.insert(2);
set.insert(23);
set.insert(998);
let mut set2 = BitSet::new();
set2.insert(123);
set2.insert(444);
set2.insert(2);
set2.insert(998);
let res = BitSet::union(&set, &set2);
for val in res.iter() {
println!("{}", val);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment