Created
March 20, 2018 22:12
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #![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