use bincode::{config::standard, encode_to_vec};
use super::{
address::{DimensionVector, SpaceId},
hyperedge::{EndpointRef, Hyperedge, HyperedgeId},
};
pub const ENDPOINT_INDEX_SPACE: SpaceId = SpaceId(u64::MAX - 1);
pub const ENDPOINT_INDEX_DIMS: usize = 16;
pub const ENDPOINT_INDEX_BITS_PER_DIM: u32 = 7;
pub fn endpoint_index_point(endpoint: &EndpointRef, edge_id: HyperedgeId) -> DimensionVector {
let mut coords = endpoint_lookup_prefix(endpoint);
coords.push((edge_id.0 & 0xFFFF_FFFF) as u32);
coords.push(((edge_id.0 >> 32) & 0xFFFF_FFFF) as u32);
while coords.len() < ENDPOINT_INDEX_DIMS {
coords.push(0);
}
DimensionVector::new(coords)
}
pub fn endpoint_lookup_prefix(endpoint: &EndpointRef) -> Vec<u32> {
let mut prefix = vec![
(endpoint.space.0 & 0xFFFF_FFFF) as u32,
((endpoint.space.0 >> 32) & 0xFFFF_FFFF) as u32,
];
prefix.extend_from_slice(&endpoint.node.coords);
prefix
}
pub fn encode_hyperedge_id(id: HyperedgeId) -> Vec<u8> {
encode_to_vec(id, standard()).expect("HyperedgeId must encode")
}
pub fn decode_hyperedge_id(data: &[u8]) -> Option<HyperedgeId> {
bincode::decode_from_slice(data, standard())
.ok()
.map(|(id, _)| id)
}
pub fn edge_endpoints(edge: &Hyperedge) -> impl Iterator<Item = &EndpointRef> {
edge.endpoints.iter()
}