microsoft/DiskANN v0.47.0
microsoft/DiskANN
Captured source
source ↗DiskANN v0.47.0
Repository: microsoft/DiskANN
Tag: v0.47.0
Published: 2026-02-23T17:51:16Z
Prerelease: no
Release notes:
DiskANN v0.47.0
Summary
- This version contains a major breaking change to the search interface of
DiskANNIndex. Please read the upgrade instructions below. - An Aarch64 Neon has been added to
diskann-wide. - Various bug-fixes and code-quality improvements.
Changes to Search
The search interface has been unified around a single index.search() entry point using the Search trait. The old per-search-type methods on DiskANNIndex (search, search_recorded, range_search, multihop_search) have been removed and replaced by typed parameter structs that carry their own search logic.
What Changed
| Removed | Replacement | |------------------------------------------------------------|--------------------------------------------------------------| | SearchParams struct | diskann::graph::search::Knn | | RangeSearchParams struct | diskann::graph::search::Range | | SearchParamsError | diskann::graph::KnnSearchError | | RangeSearchParamsError | diskann::graph::RangeSearchError | | index.search(&strategy, &ctx, &query, ¶ms, &mut out) | index.search(knn, &strategy, &ctx, &query, &mut out) | | index.search_recorded(..., &mut recorder) | index.search(RecordedKnn::new(knn, &mut recorder), ...) | | index.range_search(&strategy, &ctx, &query, ¶ms) | index.search(range, &strategy, &ctx, &query, &mut ()) | | index.multihop_search(..., &label_eval) | index.search(MultihopSearch::new(knn, &label_eval), ...) | | index.diverse_search(...) | index.search(Diverse::new(knn, diverse_params), ...) |
`flat_search` remains an inherent method on DiskANNIndex Its search_params argument changed from &SearchParams to &Knn.
Upgrade Instructions
1. k-NN Search (search)
Before:
use diskann::graph::SearchParams; let params = SearchParams::new(10, 100, None)?; let stats = index.search(&strategy, &ctx, &query, ¶ms, &mut output).await?;
After:
use diskann::graph::{Search, search::Knn};
let params = Knn::new(10, 100, None)?;
// Note: params is now the FIRST argument (moved before strategy)
let stats = index.search(params, &strategy, &ctx, &query, &mut output).await?;Key differences:
SearchParams->Knn(import fromdiskann::graph::search::Knn)SearchParamsError->KnnSearchError(import fromdiskann::graph::KnnSearchError)- Search params moved to the first argument of
index.search() k_value,l_valuefields are now private; use.k_value(),.l_value()accessors (returnNonZeroUsize)
2. Recorded/Debug Search (search_recorded)
Before:
use diskann::graph::SearchParams; let params = SearchParams::new(10, 100, None)?; let stats = index .search_recorded(&strategy, &ctx, &query, ¶ms, &mut output, &mut recorder) .await?;
After:
use diskann::graph::{Search, search::{Knn, RecordedKnn}};
let params = Knn::new(10, 100, None)?;
let recorded = RecordedKnn::new(params, &mut recorder);
let stats = index.search(recorded, &strategy, &ctx, &query, &mut output).await?;3. Range Search (range_search)
Before:
use diskann::graph::RangeSearchParams; let params = RangeSearchParams::new(None, 100, None, 0.5, None, 1.0, 1.0)?; let (stats, ids, distances) = index .range_search(&strategy, &ctx, &query, ¶ms) .await?;
After:
use diskann::graph::{
Search,
search::Range,
RangeSearchOutput,
};
// Simple form:
let params = Range::new(100, 0.5)?;
// Or full options form:
let params = Range::with_options(None, 100, None, 0.5, None, 1.0, 1.0)?;
// Note: output buffer is `&mut ()` — results come back in the return type
let result: RangeSearchOutput = index
.search(params, &strategy, &ctx, &query, &mut ())
.await?;
// Access results:
let stats = result.stats;
let ids = result.ids; // Vec
let distances = result.distances; // VecKey differences:
RangeSearchParams->Range(import fromdiskann::graph::search::Range)RangeSearchParamsError->RangeSearchError(import fromdiskann::graph::RangeSearchError)- Return type changed from
(SearchStats, Vec, Vec)toRangeSearchOutput(a struct with.stats,.ids,.distancesfields) - Pass
&mut ()as the output buffer - Field
starting_l_value-> constructor argstarting_l(accessor:.starting_l()) - Field
initial_search_slack-> constructor arginitial_slack(accessor:.initial_slack()) - Field
range_search_slack-> constructor argrange_slack(accessor:.range_slack())
4. Multihop / Label-Filtered Search (multihop_search)
Before:
use diskann::graph::SearchParams; let params = SearchParams::new(10, 100, None)?; let stats = index .multihop_search(&strategy, &ctx, &query, ¶ms, &mut output, &label_eval) .await?;
After:
use diskann::graph::{Search, search::{Knn, MultihopSearch}};
let knn = Knn::new(10, 100, None)?;
let params = MultihopSearch::new(knn, &label_eval);
let stats = index.search(params, &strategy, &ctx, &query, &mut output).await?;Key differences:
MultihopSearchwraps aKnn-> label evaluator into a single params object- The label evaluator is part of the params, not a separate argument
5. Flat Search (unchanged method, new param type)
Before:
use diskann::graph::SearchParams; let params = SearchParams::new(10, 100, None)?; index.flat_search(&strategy, &ctx, &query, &filter, ¶ms, &mut output).await?;
After:
use diskann::graph::search::Knn; let params = Knn::new(10, 100, None)?; index.flat_search(&strategy, &ctx, &query, &filter, ¶ms, &mut output).await?;
Only the parameter type changed (SearchParams -> Knn).
Import Path Changes
| Old | New | |------------------------------------------|--------------------------------------------------------| | diskann::graph::SearchParams | diskann::graph::search::Knn | | diskann::graph::RangeSearchParams | diskann::graph::search::Range | | diskann::graph::SearchParamsError | diskann::graph::KnnSearchError | | diskann::graph::RangeSearchParamsError | diskann::graph::RangeSearchError | | — | diskann::graph::search::MultihopSearch (new) | | — | diskann::graph::search::RecordedKnn (new) | | — | diskann::graph::search::Diverse (new, feature-gated) | | — | diskann::graph::Search (trait,...
Excerpt shown — open the source for the full document.