use crate::triples::Id;
use crate::triples::TripleId;
use crate::triples::TriplesBitmap;
pub struct PredicateIter<'a> {
triples: &'a TriplesBitmap,
s: Id,
p: Id,
i: usize,
os: usize,
pos_z: usize,
occs: usize,
}
impl<'a> PredicateIter<'a> {
pub fn new(triples: &'a TriplesBitmap, p: Id) -> Self {
assert!(p != 0, "object 0 does not exist, cant iterate");
let occs = triples.wavelet_y.rank(triples.wavelet_y.len(), p as usize);
PredicateIter { triples, p, i: 0, pos_z: 0, os: 0, s: 0, occs }
}
}
impl<'a> Iterator for PredicateIter<'a> {
type Item = TripleId;
fn next(&mut self) -> Option<Self::Item> {
if self.i >= self.occs {
return None;
}
if self.os == 0 {
let pos_y = self.triples.wavelet_y.select(self.i, self.p as usize) as u64;
self.s = self.triples.bitmap_y.dict.rank(pos_y, true) as Id + 1;
self.pos_z = self.triples.adjlist_z.find(pos_y as Id);
let pos_z_end = self.triples.adjlist_z.last(pos_y as Id);
self.os = pos_z_end - self.pos_z;
} else {
self.os -= 1;
self.pos_z += 1;
}
let o = self.triples.adjlist_z.sequence.get(self.pos_z) as Id;
if self.os == 0 {
self.i += 1;
}
Some(self.triples.coord_to_triple(self.s, self.p, o).unwrap())
}
}