use crate::triples::{Id, TripleId, TriplesBitmap};
use qwt::{RankUnsigned, SelectUnsigned};
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(p as usize, triples.wavelet_y.len()).unwrap();
PredicateIter { triples, p, i: 0, pos_z: 0, os: 0, s: 0, occs }
}
}
impl Iterator for PredicateIter<'_> {
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.p as usize, self.i).unwrap();
self.s = self.triples.bitmap_y.rank(pos_y) 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())
}
}