use crate::Vector;
use std::cmp::Ordering;
use std::collections::HashSet;
#[derive(Debug, Clone, Copy)]
pub struct Candidate {
pub distance: f32,
pub id: usize,
}
impl PartialEq for Candidate {
fn eq(&self, other: &Self) -> bool {
self.distance == other.distance && self.id == other.id
}
}
impl Eq for Candidate {}
impl PartialOrd for Candidate {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for Candidate {
fn cmp(&self, other: &Self) -> Ordering {
other
.distance
.partial_cmp(&self.distance)
.unwrap_or(Ordering::Equal)
.then_with(|| self.id.cmp(&other.id))
}
}
impl Candidate {
pub fn new(id: usize, distance: f32) -> Self {
Self { id, distance }
}
}
#[derive(Debug, Clone)]
pub struct Node {
pub vector: Vector,
pub uri: String,
pub connections: Vec<HashSet<usize>>,
pub vector_data_f32: Vec<f32>,
pub access_count: u64,
pub metadata: std::collections::HashMap<String, String>,
}
impl Node {
pub fn new(uri: String, vector: Vector, max_level: usize) -> Self {
let vector_data_f32 = vector.as_f32();
Self {
vector,
uri,
connections: vec![HashSet::new(); max_level + 1],
vector_data_f32,
access_count: 0,
metadata: std::collections::HashMap::new(),
}
}
pub fn with_metadata(
uri: String,
vector: Vector,
max_level: usize,
metadata: std::collections::HashMap<String, String>,
) -> Self {
let vector_data_f32 = vector.as_f32();
Self {
vector,
uri,
connections: vec![HashSet::new(); max_level + 1],
vector_data_f32,
access_count: 0,
metadata,
}
}
pub fn record_access(&mut self) {
self.access_count = self.access_count.saturating_add(1);
}
pub fn level(&self) -> usize {
self.connections.len().saturating_sub(1)
}
pub fn get_connections(&self, level: usize) -> Option<&HashSet<usize>> {
self.connections.get(level)
}
pub fn get_connections_mut(&mut self, level: usize) -> Option<&mut HashSet<usize>> {
self.connections.get_mut(level)
}
pub fn add_connection(&mut self, level: usize, node_id: usize) {
if let Some(connections) = self.connections.get_mut(level) {
connections.insert(node_id);
}
}
pub fn remove_connection(&mut self, level: usize, node_id: usize) {
if let Some(connections) = self.connections.get_mut(level) {
connections.remove(&node_id);
}
}
}
#[derive(Debug, Clone)]
pub struct ConnectivityStats {
pub total_nodes: usize,
pub total_connections: usize,
pub avg_connections: f64,
pub max_connections: usize,
pub isolated_nodes: usize,
pub connectivity_ratio: f64,
}