Repository navigation
Conversation
rfsaliev
force-pushed
the
rfsaliev/range-search-orchestrator
branch
from
November 13, 2026 15:06
a756143 to
9f75134
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Range search in the Vamana orchestrators
Summary
Exposes
range_search, added to the Vamana indexes in the PR #472, through orchestratorssvs::Vamana,svs::DynamicVamanaandsvs::ConcurrentDynamicVamana.Stacked on the #472.
API
The semantics are those of the index-level
range_search:search_parameterscaps the number of results per query; zero (orMutableBuffer::unbounded_capacity) means unbounded.Changes
VamanaInterface(include/svs/orchestrators/vamana.h) gets a new pure virtual,range_search(AnonymousArray<2> queries, float radius, const VamanaSearchParameters&, const lib::DefaultPredicate& cancel). It is appended at the end of the interface, following the existing guidance in that header.VamanaImplimplements it once for all three orchestrators:QueryTypes, likesearch(). Unsupported types throwANNException.impl().range_search(...). A newHasRangeSearch<Impl, Queries>concept guards the call, so an implementation withoutrange_searchthrows "not supported" at run time instead of failing to compile. All current implementation types (VamanaIndex,MutableVamanaIndex,concurrent::MutableVamanaIndex) provide it.Vamana::range_searchandDynamicVamana::range_searchare thin templated wrappers that build theAnonymousArray<2>.ConcurrentDynamicVamanainherits the method fromDynamicVamana.Compatibility
VamanaInterface, so the new pure virtual requires no changes elsewhere.DynamicVamanaInterfacederives fromVamanaInterface, so its virtual slots shift. Binaries that use orchestrators across a library boundary must be rebuilt against matching headers. ABI stability of the orchestrator interfaces is not a goal, so this is accepted.Testing
A new header-only helper,
tests/utils/range_search.h(svs_test::check_orchestrator_range_search), is used by one new test case per orchestrator:tests/svs/orchestrators/vamana.cpp: "Vamana Range Search"tests/svs/orchestrators/dynamic_vamana.cpp: "DynamicVamana Range Search"tests/svs/orchestrators/concurrent_dynamic_vamana.cpp: "ConcurrentDynamicVamana Range Search"Each one builds the orchestrator over the standard test dataset with L2 and checks:
uint8_tfor a float index) throwsANNException.The recall threshold is lower than in the index-level tests on purpose. On this dataset, recall for about 30 neighbors only rises from 0.88 at window 20 to 0.91 at window 100. These tests check the orchestrator plumbing; the base PR checks recall on the indexes directly.
All
[managers]tests pass.Notes for reviewers
HasRangeSearchconcept and the explicitthis->impl()are deliberate. Inside the generic dispatch lambda, GCC did not resolveimpl(), whichVamanaImplinherits from its dependent base class through ausingdeclaration. An inlinerequires { impl().range_search(...) }therefore evaluated tofalse, and the "not supported" branch was taken silently. The new tests fail if that regresses.range_searchin the Python bindings.range_searchfrom the batch iterator to this API. Bindings that call the method need a prebuilt library that contains it.predicated_searchthrough the orchestrators once filtered search defines the stop predicates it needs. Template stop predicates can't cross the virtual boundary as they are.