bbqvec 0.0.10

Scalable, embeddable, vector storage for approximate K-nearest-neighbors (AKNN)
Documentation
use std::fmt::Display;

use crate::Bitmap;

#[derive(Default)]
pub struct CountingBitmap<B: Bitmap> {
    bitmaps: Vec<B>,
}

impl<B: Bitmap> Display for CountingBitmap<B> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_fmt(format_args!("{:?}", self.cardinalities()))
    }
}

impl<B: Bitmap> CountingBitmap<B> {
    pub fn new(size: usize) -> Self {
        Self {
            bitmaps: vec![B::new(); size],
        }
    }

    pub fn or(&mut self, rhs: B) {
        let mut cur = rhs;
        for i in 0..self.bitmaps.len() {
            self.bitmaps[i].xor(&cur);
            cur.and_not(&self.bitmaps[i]);
            self.bitmaps[i].or(&cur);
            if cur.is_empty() {
                break;
            }
        }
    }

    pub fn cardinalities(&self) -> Vec<usize> {
        self.bitmaps.iter().map(|b| b.count()).collect::<Vec<_>>()
    }

    pub fn top_k(&self, search_k: usize) -> Option<&B> {
        self.bitmaps.iter().rev().find(|x| x.count() >= search_k)
    }
}

#[cfg(test)]
mod test {
    use bitvec::prelude::*;

    use super::*;

    #[test]
    fn finds_count() {
        let mut cbm = CountingBitmap::<crate::BitVec>::new(3);
        let bm_a = bitvec![usize, Lsb0; 0, 0, 1];
        let bm_b = bitvec![usize, Lsb0; 0, 1, 1];
        let bm_c = bitvec![usize, Lsb0; 1, 1, 1];
        cbm.or(bm_a);
        cbm.or(bm_b);
        cbm.or(bm_c);
        let v: Vec<u64> = cbm.top_k(1).unwrap().iter_elems().collect();
        assert_eq!(v.len(), 1);
        assert_eq!(v[0], 2);
        assert_eq!(cbm.top_k(10), None);
        assert_eq!(cbm.top_k(1).unwrap().count(), 1);
    }
}