use serde::{Deserialize, Serialize};
use crate::distance::Metric;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct NodeRecord {
pub id: u64,
pub vector: Vec<f32>,
pub neighbors: Vec<Vec<u64>>,
}
impl NodeRecord {
#[inline]
pub fn top_level(&self) -> usize {
self.neighbors.len() - 1
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HnswHeader {
pub dim: usize,
pub metric: Metric,
pub m: usize,
pub ef_construction: usize,
pub ef_search: usize,
pub entry_point: Option<u64>,
pub max_level: usize,
}
pub(crate) fn to_bytes<T: Serialize>(value: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::serde::encode_to_vec(value, bincode::config::standard())
}
pub(crate) fn from_bytes<T: for<'de> Deserialize<'de>>(
bytes: &[u8],
) -> Result<T, bincode::error::DecodeError> {
bincode::serde::decode_from_slice(bytes, bincode::config::standard()).map(|(v, _)| v)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn node_record_round_trips() {
let node = NodeRecord {
id: 42,
vector: vec![0.1, 0.2, 0.3],
neighbors: vec![vec![1, 2, 3], vec![4, 5], vec![]],
};
let bytes = to_bytes(&node).unwrap();
let back: NodeRecord = from_bytes(&bytes).unwrap();
assert_eq!(node, back);
assert_eq!(back.top_level(), 2);
}
#[test]
fn header_round_trips() {
let header = HnswHeader {
dim: 128,
metric: Metric::Cosine,
m: 16,
ef_construction: 200,
ef_search: 64,
entry_point: Some(7),
max_level: 3,
};
let bytes = to_bytes(&header).unwrap();
let back: HnswHeader = from_bytes(&bytes).unwrap();
assert_eq!(header, back);
}
}