Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions diskann-benchmark/src/inputs/save_and_load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
use std::{io::Read, mem::size_of, num::NonZeroUsize};

use diskann::{ANNError, ANNResult};
use diskann::{ANNError, ANNErrorKind, ANNResult};
use diskann_providers::storage::StorageReadProvider;

pub fn get_graph_num_frozen_points(
Expand All @@ -22,9 +22,9 @@ pub fn get_graph_num_frozen_points(
let file_frozen_pts = usize::from_le_bytes(usize_buffer);

NonZeroUsize::new(file_frozen_pts).ok_or_else(|| {
ANNError::log_index_config_error(
"num_frozen_pts".to_string(),
"num_frozen_pts is zero in saved file".to_string(),
ANNError::from_display(
ANNErrorKind::IndexConfigError,
"num_frozen_pts is invalid, err = num_frozen_pts is zero in saved file",
)
})
}
Expand Down
14 changes: 10 additions & 4 deletions diskann-bftree/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ impl TransientError<ANNError> for VectorUnavailable {
where
D: std::fmt::Display,
{
ANNError::log_index_error(format!("{self}, escalated: {why}"))
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
format!("{self}, escalated: {why}"),
)
}
}

Expand All @@ -107,11 +110,14 @@ pub(crate) fn validate_record_size(
let required = key_size + value_size;
let configured_max = config.get_cb_max_record_size();
if required > configured_max {
return Err(ANNError::log_index_error(format!(
"{provider_name}: cb_max_record_size ({configured_max}) is too small; \
return Err(ANNError::from_display(
diskann::ANNErrorKind::IndexError,
format!(
"{provider_name}: cb_max_record_size ({configured_max}) is too small; \
a record requires {required} bytes ({key_size}-byte key + {value_size}-byte value); \
increase cb_max_record_size to at least {required}"
)));
),
));
}
Ok(())
}
Expand Down
17 changes: 11 additions & 6 deletions diskann-bftree/src/neighbors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ impl<I: VectorId + IntoUsize> NeighborProvider<I> {
if read_size > 0 {
// A retrieved neighbor list should be exactly dim length
if read_size as usize != self.dim * std::mem::size_of::<I>() {
return Err(ANNError::log_index_error(
return Err(ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"Retrieved neighbor list is not expected length = max degree + 1",
));
}
Expand All @@ -135,7 +136,7 @@ impl<I: VectorId + IntoUsize> NeighborProvider<I> {

// The specified list length must be smaller than the retrieved data length
if count > self.max_degree() {
return Err(ANNError::log_index_error(
return Err(ANNError::from_display(diskann::ANNErrorKind::IndexError,
"Size of retrieved neighbor list is shorter than the stored neighbor count",
));
}
Expand All @@ -144,12 +145,14 @@ impl<I: VectorId + IntoUsize> NeighborProvider<I> {
}
}
bf_tree::LeafReadResult::Deleted => {
return Err(ANNError::log_index_error(
return Err(ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"The bf-tree entry for the vector is marked as deleted",
));
}
bf_tree::LeafReadResult::InvalidKey => {
return Err(ANNError::log_index_error(
return Err(ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"The bf-tree entry for the vector key is marked as invalid",
));
}
Expand Down Expand Up @@ -196,7 +199,8 @@ impl<I: VectorId + IntoUsize> NeighborProvider<I> {
self.num_get_calls.increment();

if buf.len() < self.dim {
return Err(ANNError::log_index_error(
return Err(ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"The provided buffer is not long enough",
));
}
Expand Down Expand Up @@ -227,7 +231,8 @@ impl<I: VectorId + IntoUsize> NeighborProvider<I> {
/// - Buffer length (in `I` cells) is smaller than `max_degree() + 1`
pub fn set_neighbors(&self, vector_id: I, neighbors: &[I], buf: &mut [I]) -> ANNResult<()> {
if neighbors.len() > self.dim - 1 {
return Err(ANNError::log_index_error(
return Err(ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"The provided neighbor list is longer than the max degree",
));
};
Expand Down
109 changes: 77 additions & 32 deletions diskann-bftree/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,14 @@ where
{
// Early validation before allocating resources
if start_points.nrows() != params.num_start_points.get() {
return Err(ANNError::log_async_index_error(format!(
"start_points matrix has {} rows, but params.num_start_points is {}",
start_points.nrows(),
params.num_start_points.get(),
)));
return Err(ANNError::from_display(
diskann::ANNErrorKind::AsyncIndexError,
format!(
"start_points matrix has {} rows, but params.num_start_points is {}",
start_points.nrows(),
params.num_start_points.get(),
),
));
}

let provider = Self::new_empty(params.clone(), quant_precursor)?;
Expand Down Expand Up @@ -732,11 +735,14 @@ where
fn set_start_points(&self, _hidden: Hidden, start_points: MatrixView<'_, T>) -> ANNResult<()> {
let start_point_ids = self.full_vectors.starting_points()?;
if start_points.nrows() != start_point_ids.len() {
return Err(ANNError::log_async_index_error(format!(
"expected start_points to contain `{}` rows, instead it has {}",
start_point_ids.len(),
start_points.nrows(),
)));
return Err(ANNError::from_display(
diskann::ANNErrorKind::AsyncIndexError,
format!(
"expected start_points to contain `{}` rows, instead it has {}",
start_point_ids.len(),
start_points.nrows(),
),
));
}

let mut scratch = self.neighbor_provider.scratch(&self.locks);
Expand All @@ -763,11 +769,14 @@ where
fn set_start_points(&self, _hidden: Hidden, start_points: MatrixView<'_, T>) -> ANNResult<()> {
let start_point_ids = self.full_vectors.starting_points()?;
if start_points.nrows() != start_point_ids.len() {
return Err(ANNError::log_async_index_error(format!(
"expected start_points to contain `{}` rows, instead it has {}",
start_point_ids.len(),
start_points.nrows(),
)));
return Err(ANNError::from_display(
diskann::ANNErrorKind::AsyncIndexError,
format!(
"expected start_points to contain `{}` rows, instead it has {}",
start_point_ids.len(),
start_points.nrows(),
),
));
}

let mut scratch = self.neighbor_provider.scratch(&self.locks);
Expand Down Expand Up @@ -1691,7 +1700,8 @@ fn save_bftree(
use_snapshot: bool,
) -> ANNResult<()> {
if !use_snapshot {
return Err(ANNError::log_index_error(
return Err(ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"cannot snapshot a BfTree that was not configured with use_snapshot(true)",
));
}
Expand Down Expand Up @@ -1725,8 +1735,12 @@ where
{
let saved_params = SavedParams {
max_points: self.max_points(),
frozen_points: NonZeroUsize::new(self.num_start_points())
.ok_or_else(|| ANNError::log_index_error("num_start_points is zero"))?,
frozen_points: NonZeroUsize::new(self.num_start_points()).ok_or_else(|| {
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"num_start_points is zero",
)
})?,
dim: self.dim(),
metric: self.metric().as_str().to_string(),
max_degree: self.max_degree(),
Expand Down Expand Up @@ -1756,7 +1770,10 @@ where
{
let params_filename = BfTreePaths::params_json(&saved_params.prefix);
let params_json = serde_json::to_string(&saved_params).map_err(|e| {
ANNError::log_index_error(format!("Failed to serialize params: {}", e))
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
format!("Failed to serialize params: {}", e),
)
})?;
let mut params_writer = storage.create_for_write(&params_filename)?;
params_writer.write_all(params_json.as_bytes())?;
Expand Down Expand Up @@ -1793,12 +1810,19 @@ where
let mut params_json = String::new();
params_reader.read_to_string(&mut params_json)?;
serde_json::from_str(&params_json).map_err(|e| {
ANNError::log_index_error(format!("Failed to deserialize params: {}", e))
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
format!("Failed to deserialize params: {}", e),
)
})?
};

let metric = Metric::from_str(&saved_params.metric)
.map_err(|e| ANNError::log_index_error(format!("Failed to parse metric: {}", e)))?;
let metric = Metric::from_str(&saved_params.metric).map_err(|e| {
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
format!("Failed to parse metric: {}", e),
)
})?;

let vector_index = load_bftree(
BfTreePaths::vectors_bftree(&saved_params.prefix),
Expand Down Expand Up @@ -1845,8 +1869,12 @@ where
{
let saved_params = SavedParams {
max_points: self.max_points(),
frozen_points: NonZeroUsize::new(self.num_start_points())
.ok_or_else(|| ANNError::log_index_error("num_start_points is zero"))?,
frozen_points: NonZeroUsize::new(self.num_start_points()).ok_or_else(|| {
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"num_start_points is zero",
)
})?,
dim: self.dim(),
metric: self.metric().as_str().to_string(),
max_degree: self.max_degree(),
Expand Down Expand Up @@ -1887,7 +1915,10 @@ where
{
let params_filename = BfTreePaths::params_json(&saved_params.prefix);
let params_json = serde_json::to_string(&saved_params).map_err(|e| {
ANNError::log_index_error(format!("Failed to serialize params: {}", e))
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
format!("Failed to serialize params: {}", e),
)
})?;
let mut params_writer = storage.create_for_write(&params_filename)?;
params_writer.write_all(params_json.as_bytes())?;
Expand All @@ -1914,7 +1945,9 @@ where
.quant_vectors
.quantizer
.serialize(GlobalAllocator)
.map_err(|e| ANNError::log_index_error(format!("{e}")))?;
.map_err(|e| {
ANNError::from_display(diskann::ANNErrorKind::IndexError, format!("{e}"))
})?;
let mut writer = storage.create_for_write(&filename)?;
writer.write_all(&serialized)?;

Expand All @@ -1938,16 +1971,26 @@ where
let mut params_json = String::new();
params_reader.read_to_string(&mut params_json)?;
serde_json::from_str(&params_json).map_err(|e| {
ANNError::log_index_error(format!("Failed to deserialize params: {}", e))
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
format!("Failed to deserialize params: {}", e),
)
})?
};

let _quant_params = saved_params.quant_params.ok_or_else(|| {
ANNError::log_index_error("Missing quant_params in saved params for quantized provider")
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"Missing quant_params in saved params for quantized provider",
)
})?;

let metric = Metric::from_str(&saved_params.metric)
.map_err(|e| ANNError::log_index_error(format!("Failed to parse metric: {}", e)))?;
let metric = Metric::from_str(&saved_params.metric).map_err(|e| {
ANNError::from_display(
diskann::ANNErrorKind::IndexError,
format!("Failed to parse metric: {}", e),
)
})?;

let vector_index = load_bftree(
BfTreePaths::vectors_bftree(&saved_params.prefix),
Expand All @@ -1973,8 +2016,10 @@ where
let mut reader = storage.open_reader(&filename)?;
let mut bytes = Vec::new();
reader.read_to_end(&mut bytes)?;
let quantizer: Poly<dyn Quantizer> = try_deserialize(&bytes, GlobalAllocator)
.map_err(|e| ANNError::log_index_error(format!("{e}")))?;
let quantizer: Poly<dyn Quantizer> =
try_deserialize(&bytes, GlobalAllocator).map_err(|e| {
ANNError::from_display(diskann::ANNErrorKind::IndexError, format!("{e}"))
})?;

let quant_vector_index = load_bftree(
BfTreePaths::quant_bftree(&saved_params.prefix),
Expand Down
22 changes: 12 additions & 10 deletions diskann-bftree/src/quant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,15 @@ impl QuantVectorProvider {
GlobalAllocator,
ScopedAllocator::global(),
)
.map_err(|e| ANNError::log_sq_error(e))?;
.map_err(|e| ANNError::new(diskann::ANNErrorKind::SQError, e))?;
Ok(QuantQueryComputer(inner))
}

/// Create a distance computer for the underlying schema
pub fn distance_computer(&self) -> ANNResult<DistanceComputer> {
self.quantizer
.distance_computer(GlobalAllocator)
.map_err(|e| ANNError::log_sq_error(e))
.map_err(|e| ANNError::new(diskann::ANNErrorKind::SQError, e))
}

pub(crate) fn get_vector_into(&self, i: usize, buffer: &mut [u8]) -> Result<(), AccessError> {
Expand All @@ -133,7 +133,7 @@ impl QuantVectorProvider {
match self.quant_vector_index.read(bytemuck::bytes_of(&i), buffer) {
bf_tree::LeafReadResult::Found(read_size) => {
if read_size as usize != expected {
return Err(AccessError::Error(ANNError::log_index_error(format!(
return Err(AccessError::Error(ANNError::from_display(diskann::ANNErrorKind::IndexError, format!(
"The bf-tree entry for vector id {} is marked as found but has size {} instead of the expected size {}",
i, read_size, expected,
))));
Expand All @@ -146,10 +146,10 @@ impl QuantVectorProvider {
}));
}
bf_tree::LeafReadResult::InvalidKey => {
return Err(AccessError::Error(ANNError::log_index_error(format!(
"The bf-tree entry for vector id {} is marked as invalid",
i,
))));
return Err(AccessError::Error(ANNError::from_display(
diskann::ANNErrorKind::IndexError,
format!("The bf-tree entry for vector id {} is marked as invalid", i,),
)));
}
bf_tree::LeafReadResult::NotFound => {
return Err(AccessError::Transient(VectorUnavailable {
Expand Down Expand Up @@ -183,7 +183,8 @@ impl QuantVectorProvider {
let vf32: &[f32] = &T::as_f32(v).into_ann_result()?;

if vf32.len() != self.full_dim() {
return Err(ANNError::log_dimension_mismatch_error(
return Err(ANNError::from_display(
diskann::ANNErrorKind::DimensionMismatchError,
"Vector f32 dimension is not equal to the expected dimension.".to_string(),
));
}
Expand All @@ -199,7 +200,7 @@ impl QuantVectorProvider {
OpaqueMut::new(quant_vector),
ScopedAllocator::global(),
)
.map_err(|e| ANNError::log_sq_error(e))?;
.map_err(|e| ANNError::new(diskann::ANNErrorKind::SQError, e))?;

bftree_insert(&self.quant_vector_index, key, quant_vector)?;

Expand All @@ -214,7 +215,8 @@ impl QuantVectorProvider {
#[cfg(test)]
pub(crate) fn set_quant_vector(&self, i: usize, v: &[u8]) -> ANNResult<()> {
if v.len() != self.quantizer.bytes() {
return Err(ANNError::log_index_error(
return Err(ANNError::from_display(
diskann::ANNErrorKind::IndexError,
"Vector dimension is not equal to the expected dimension.",
));
}
Expand Down
Loading
Loading