use std::collections::HashSet;
use crate::error::Error;
use crate::id::NodeId;
use crate::objects::{AdjacencyBucket, Edge, IncomingAdjacencyBucket, IndexSet};
use crate::prolly::{self, ProllyKey};
use crate::repo::readonly::decode_from_store;
use crate::store::Blockstore;
pub(super) fn load_outgoing(
bs: &dyn Blockstore,
indexes: Option<&IndexSet>,
src: NodeId,
want: &HashSet<&str>,
cap: usize,
) -> Result<(Vec<Edge>, bool), Error> {
if want.is_empty() {
return Ok((Vec::new(), false));
}
let Some(idx) = indexes else {
return Ok((Vec::new(), false));
};
let Some(adj_root) = &idx.outgoing else {
return Ok((Vec::new(), false));
};
let Some(bucket_cid) = prolly::lookup(bs, adj_root, &ProllyKey::from(src))? else {
return Ok((Vec::new(), false));
};
let bucket: AdjacencyBucket = decode_from_store(bs, &bucket_cid)?;
let mut out = Vec::new();
let mut truncated = false;
for ae in &bucket.edges {
if want.contains(ae.label.as_str()) {
if out.len() >= cap {
truncated = true;
break;
}
let edge: Edge = decode_from_store(bs, &ae.edge)?;
out.push(edge);
}
}
Ok((out, truncated))
}
pub(super) fn load_incoming(
bs: &dyn Blockstore,
indexes: Option<&IndexSet>,
dst: NodeId,
want: &HashSet<&str>,
cap: usize,
) -> Result<(Vec<Edge>, bool), Error> {
if want.is_empty() {
return Ok((Vec::new(), false));
}
let Some(idx) = indexes else {
return Ok((Vec::new(), false));
};
let Some(inc_root) = &idx.incoming else {
return Ok((Vec::new(), false));
};
let Some(bucket_cid) = prolly::lookup(bs, inc_root, &ProllyKey::from(dst))? else {
return Ok((Vec::new(), false));
};
let bucket: IncomingAdjacencyBucket = decode_from_store(bs, &bucket_cid)?;
let mut out = Vec::new();
let mut truncated = false;
for ae in &bucket.edges {
if want.contains(ae.label.as_str()) {
if out.len() >= cap {
truncated = true;
break;
}
let edge: Edge = decode_from_store(bs, &ae.edge)?;
out.push(edge);
}
}
Ok((out, truncated))
}