tdb-succinct 0.1.2

succinct data structures used by terminusdb
Documentation
#[derive(Clone)]
pub struct SmallBitArray {
    val: u64,
}

impl std::fmt::Debug for SmallBitArray {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "<{:b}>", self.val)
    }
}

impl SmallBitArray {
    pub const LEN: usize = u64::BITS as usize - 1;
    pub fn new(val: u64) -> Self {
        if val & 1 != 0 {
            panic!("lsb set for a small bit array. this is reserved for future expansion");
        }

        Self { val }
    }

    pub fn get(&self, index: usize) -> bool {
        if index >= Self::LEN {
            panic!("index too high");
        }

        (self.val >> (Self::LEN - index) & 1) != 0
    }

    pub fn iter(&self) -> impl Iterator<Item = bool> {
        SmallBitArrayIter {
            val: self.val,
            ix: 0,
        }
    }

    pub fn inner(&self) -> u64 {
        self.val
    }

    pub fn rank1(&self, index: usize) -> usize {
        if index >= Self::LEN {
            panic!("index too high");
        }

        let mask = !(u64::MAX >> (index as u32 + 1));
        (self.val & mask).count_ones() as usize
    }
}

#[derive(Clone)]
pub struct SmallBitArrayIter {
    val: u64,
    ix: usize,
}

impl Iterator for SmallBitArrayIter {
    type Item = bool;

    fn next(&mut self) -> Option<bool> {
        if self.ix >= SmallBitArray::LEN {
            return None;
        }

        let result = (self.val & 0x80000000_00000000) != 0;

        self.val <<= 1;
        self.ix += 1;

        Some(result)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    #[should_panic(
        expected = "lsb set for a small bit array. this is reserved for future expansion"
    )]
    fn panic_with_set_lsb() {
        let val: u64 = 0b01101011_10111001_10010010_00000111_10010001_01100101_00000000_11111111;

        let _x = SmallBitArray::new(val);
    }
    #[test]
    fn get_from_small_bit_array() {
        let val: u64 = 0b01101011_10111001_10010010_00000111_10010001_01100101_00000000_11111110;

        let arr = SmallBitArray::new(val);

        #[rustfmt::skip]
        let expecteds = [
            false, true, true, false, true, false, true, true,
            true, false, true, true, true, false, false, true,
            true, false, false, true, false, false, true, false,
            false, false, false, false, false, true, true, true,
            true, false, false, true, false, false, false, true,
            false, true, true, false, false, true, false, true,
            false, false, false, false, false, false, false, false,
            true, true, true, true, true, true, true
        ];

        for (ix, &expected) in expecteds.iter().enumerate() {
            assert_eq!(expected, arr.get(ix));
        }
    }
    #[test]

    fn iterate_small_bit_array() {
        let val: u64 = 0b01101011_10111001_10010010_00000111_10010001_01100101_00000000_11111110;

        let arr = SmallBitArray::new(val);

        #[rustfmt::skip]
        let expecteds = [
            false, true, true, false, true, false, true, true,
            true, false, true, true, true, false, false, true,
            true, false, false, true, false, false, true, false,
            false, false, false, false, false, true, true, true,
            true, false, false, true, false, false, false, true,
            false, true, true, false, false, true, false, true,
            false, false, false, false, false, false, false, false,
            true, true, true, true, true, true, true
        ];

        let iter = arr.iter();

        for (&expected, actual) in expecteds.iter().zip(iter) {
            assert_eq!(expected, actual);
        }
    }

    #[test]
    fn small_bit_array_rank() {
        let val: u64 = 0b01101011_10111001_10010010_00000111_10010001_01100101_00000000_11111110;

        let arr = SmallBitArray::new(val);

        #[rustfmt::skip]
        let expecteds = [
            0, 1, 2, 2, 3, 3, 4, 5,
            6, 6, 7, 8, 9, 9, 9, 10,
            11, 11, 11, 12, 12, 12, 13, 13,
            13, 13, 13, 13, 13, 14, 15, 16,
            17, 17, 17, 18, 18, 18, 18, 19,
            19, 20, 21, 21, 21, 22, 22, 23,
            23, 23, 23, 23, 23, 23, 23, 23,
            24, 25, 26, 27, 28, 29, 30
        ];

        for (ix, &expected) in expecteds.iter().enumerate() {
            let rank = arr.rank1(ix);
            assert_eq!(expected, rank);
        }
    }
}