use std::alloc::Layout;
use std::borrow::Cow;
use crate::common::generic_consts::Sequential;
use crate::common::types::PointOffsetType;
use crate::segment::common::operation_error::{OperationError, OperationResult};
use crate::segment::vector_storage::quantized::quantized_vectors::QuantizedVectors;
use crate::segment::vector_storage::{VectorStorageEnum, VectorStorageRead};
pub trait GraphLinksVectors {
fn for_base_vector(
&self,
point_id: PointOffsetType,
f: &mut dyn FnMut(&[u8]) -> OperationResult<()>,
) -> OperationResult<()>;
fn get_link_vector(&self, point_id: PointOffsetType) -> OperationResult<Cow<'_, [u8]>>;
fn vectors_layout(&self) -> GraphLinksVectorsLayout;
}
#[derive(Copy, Clone)]
pub struct GraphLinksVectorsLayout {
pub base: Layout,
pub link: Layout,
}
pub struct StorageGraphLinksVectors<'a> {
vector_storage: &'a VectorStorageEnum, quantized_vectors: &'a QuantizedVectors, vectors_layout: GraphLinksVectorsLayout,
}
impl<'a> StorageGraphLinksVectors<'a> {
pub fn try_new(
vector_storage: &'a VectorStorageEnum,
quantized_vectors: Option<&'a QuantizedVectors>,
) -> Option<Self> {
let quantized_vectors = quantized_vectors?;
Some(Self {
vector_storage,
quantized_vectors,
vectors_layout: GraphLinksVectorsLayout {
base: vector_storage.get_vector_layout().ok()?,
link: quantized_vectors.get_quantized_vector_layout().ok()?,
},
})
}
}
impl<'a> GraphLinksVectors for StorageGraphLinksVectors<'a> {
fn for_base_vector(
&self,
point_id: PointOffsetType,
f: &mut dyn FnMut(&[u8]) -> OperationResult<()>,
) -> OperationResult<()> {
self.vector_storage
.with_vector_bytes_opt::<Sequential, _>(point_id, f)?
.unwrap_or_else(|| {
Err(OperationError::service_error(format!(
"Point {point_id} not found in vector storage"
)))
})
}
fn get_link_vector(&self, point_id: PointOffsetType) -> OperationResult<Cow<'_, [u8]>> {
Ok(self.quantized_vectors.get_quantized_vector(point_id))
}
fn vectors_layout(&self) -> GraphLinksVectorsLayout {
self.vectors_layout
}
}