use std::path::Path;
use serde::{Serialize, de::DeserializeOwned};
use crate::hnsw::*;
use crate::hnswio::*;
use anndists::dist::distances::Distance;
use log::info;
pub trait AnnT {
type Val;
fn insert_data(&mut self, data: &[Self::Val], id: usize);
fn search_neighbours(&self, data: &[Self::Val], knbn: usize, ef_s: usize) -> Vec<Neighbour>;
fn parallel_insert_data(&mut self, data: &[(&Vec<Self::Val>, usize)]);
fn parallel_search_neighbours(
&self,
data: &[Vec<Self::Val>],
knbn: usize,
ef_s: usize,
) -> Vec<Vec<Neighbour>>;
fn file_dump(&self, path: &Path, file_basename: &str) -> anyhow::Result<String>;
}
impl<T, D> AnnT for Hnsw<'_, T, D>
where
T: Serialize + DeserializeOwned + Clone + Send + Sync,
D: Distance<T> + Send + Sync,
{
type Val = T;
fn insert_data(&mut self, data: &[Self::Val], id: usize) {
self.insert((data, id));
}
fn search_neighbours(&self, data: &[T], knbn: usize, ef_s: usize) -> Vec<Neighbour> {
self.search(data, knbn, ef_s)
}
fn parallel_insert_data(&mut self, data: &[(&Vec<Self::Val>, usize)]) {
self.parallel_insert(data);
}
fn parallel_search_neighbours(
&self,
data: &[Vec<Self::Val>],
knbn: usize,
ef_s: usize,
) -> Vec<Vec<Neighbour>> {
self.parallel_search(data, knbn, ef_s)
}
fn file_dump(&self, path: &Path, file_basename: &str) -> anyhow::Result<String> {
info!(
"Hnsw::file_dump: dumping in dir {:#?} with (unique) basename : {}",
path, file_basename
);
let overwrite = !self.get_datamap_opt();
let mut dumpinit = DumpInit::new(path, file_basename, overwrite);
let dumpname = dumpinit.get_basename().clone();
let res = self.dump(DumpMode::Full, &mut dumpinit);
dumpinit.flush()?;
info!(
"\n End of dump, directory : {:#?} file basename : {}\n",
path, &dumpname
);
if res.is_ok() {
Ok(dumpname)
} else {
Err(anyhow::anyhow!("unexpected error"))
}
} }