use crate::common::counter::hardware_accumulator::HwMeasurementAcc;
#[cfg(debug_assertions)]
use crate::common::generic_consts::Random;
use crate::common::types::{PointOffsetType, ScoreType};
use crate::segment::common::operation_error::OperationResult;
use crate::segment::data_types::vectors::{QueryVector, VectorInternal};
#[cfg(debug_assertions)]
use crate::segment::vector_storage::VectorStorageRead;
use crate::segment::vector_storage::{RawScorer, VectorStorageEnum, new_raw_scorer};
pub struct LazyMatrix<'storage> {
scorers: Vec<Box<dyn RawScorer + 'storage>>,
matrix: Vec<Vec<Option<ScoreType>>>,
}
impl<'storage> LazyMatrix<'storage> {
pub fn new(
vectors: Vec<VectorInternal>,
storage: &'storage VectorStorageEnum,
hw_measurement_acc: HwMeasurementAcc,
) -> OperationResult<Self> {
#[cfg(debug_assertions)]
{
for (i, vector) in vectors.iter().enumerate() {
let stored_vector = storage.get_vector::<Random>(i as u32);
assert_eq!(stored_vector.to_owned(), *vector);
}
}
let matrix = vec![vec![None; vectors.len()]; vectors.len()];
let scorers = vectors
.into_iter()
.map(|vector| {
let query = QueryVector::Nearest(vector);
new_raw_scorer(query, storage, hw_measurement_acc.get_counter_cell())
})
.collect::<OperationResult<Vec<_>>>()?;
Ok(Self { scorers, matrix })
}
pub fn get_similarity(&mut self, i: usize, j: usize) -> ScoreType {
if let Some(similarity) = self.matrix[i][j] {
return similarity;
}
let similarity = self.compute_similarity(i, j);
self.matrix[i][j] = Some(similarity);
similarity
}
fn compute_similarity(&self, i: usize, j: usize) -> ScoreType {
self.scorers[i].score_point(j as PointOffsetType)
}
}