use super::index::HnswIndex;
use super::upsert::UpsertResult;
use crate::validation::validate_dimension_match;
#[cfg_attr(not(feature = "persistence"), allow(dead_code))]
pub(crate) struct DirectVectorWriter<'a> {
hnsw_index: &'a HnswIndex,
}
#[cfg_attr(not(feature = "persistence"), allow(dead_code))]
impl<'a> DirectVectorWriter<'a> {
#[must_use]
pub(crate) fn new(hnsw_index: &'a HnswIndex) -> Self {
Self { hnsw_index }
}
pub(crate) fn write_batch_direct(
&self,
vectors: &[(u64, &[f32])],
) -> crate::error::Result<Option<Vec<UpsertResult>>> {
for (_, vector) in vectors {
validate_dimension_match(self.hnsw_index.dimension, vector.len())?;
}
if !self.hnsw_index.enable_vector_storage {
return Ok(None);
}
if vectors.is_empty() {
return Ok(Some(Vec::new()));
}
let refs: Vec<&[f32]> = vectors.iter().map(|&(_, vector)| vector).collect();
let _publishing = self.hnsw_index.publishing.read();
let inner = self.hnsw_index.inner.read();
let placed = inner.place_unlinked(&refs)?;
let results = vectors
.iter()
.zip(placed)
.map(|(&(id, _), placed)| UpsertResult {
idx: placed.slot(),
old_idx: self.hnsw_index.mappings.assign(id, placed),
})
.collect();
drop(inner);
Ok(Some(results))
}
}