pub mod bm25;
pub mod hnsw;
pub mod postings;
pub mod varint;
pub mod vecpool;
use alloc::vec::Vec;
use crate::id::FactId;
use postings::PostingStore;
pub type IdListIndex<'a> = PostingStore<'a, false>;
#[derive(Debug, Default)]
pub struct IntersectScratch {
a: Vec<u32>,
b: Vec<u32>,
}
impl IntersectScratch {
pub fn new() -> Self {
Self::default()
}
}
pub fn intersect(
index: &IdListIndex<'_>,
keys: &[u32],
scratch: &mut IntersectScratch,
out: &mut Vec<FactId>,
) {
out.clear();
let Some((first, rest)) = keys
.iter()
.min_by_key(|&&k| index.count(k))
.map(|&smallest| {
(
smallest,
keys.iter().copied().filter(move |&k| k != smallest),
)
})
else {
return;
};
scratch.a.clear();
scratch.a.extend(index.entries(first).map(|(id, _)| id.0));
for key in rest {
if scratch.a.is_empty() {
break;
}
scratch.b.clear();
let mut other = index.entries(key).map(|(id, _)| id.0).peekable();
for &id in &scratch.a {
while other.peek().is_some_and(|&o| o < id) {
other.next();
}
if other.peek() == Some(&id) {
scratch.b.push(id);
}
}
core::mem::swap(&mut scratch.a, &mut scratch.b);
}
out.extend(scratch.a.iter().map(|&id| FactId(id)));
}