Repository navigation
Conversation
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Assembly can accept relocation-prone graph storage, and allocator detection and constructor overload resolution have compile-time defects.
Review effort: Balanced
Findings: 3
Open (4)
What changed in this PR
Adds the type-erased concurrent dynamic Vamana orchestrator with allocator-aware graph storage, assembly support, and integration tests.
Changes:
- Adds concurrent build, mutation, iteration, persistence, and concurrency APIs/tests.
- Generalizes blocked graph allocators and reverse-edge allocation.
- Adds segmented-storage traits and state-based index assembly.
| File | Description |
|---|---|
tests/svs/orchestrators/concurrent_dynamic_vamana.cpp |
Adds orchestrator integration tests. |
tests/CMakeLists.txt |
Registers the new tests. |
include/svs/orchestrators/vamana_iterator.h |
Selects index-specific iterator types. |
include/svs/orchestrators/concurrent_dynamic_vamana.h |
Adds the concurrent type-erased wrapper. |
include/svs/concurrent/README.md |
Documents allocator and wrapper APIs. |
include/svs/concurrent/graph.h |
Adds allocator-flexible blocked graphs. |
include/svs/concurrent/dynamic_index.h |
Adds allocator-aware build and state assembly. |
include/svs/concurrent/blocked_data.h |
Adds segmented allocator detection. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
4b8a37a to
a81dc4d
Compare
There was a problem hiding this comment.
I am worried about drift between sequential and concurrent code and I'm wondering why we can't pick the same approach as in #380. I have a suggestion below. Let's discuss why it's not the right choice:
Suggestion: pass the graph allocator the way #380 does for the sequential index. In #380 the sequential auto_dynamic_build builds the graph and hands it to a ready-graph build constructor. Here the same capability comes in a second way: an allocator overload of the build constructor, a std::monostate sentinel, and make_graph. Mirroring the sequential shape would:
- leave the existing build constructor exactly as it is on `main;
- drop the
requiresclause, so thenullptrlogger problem Copilot raised goes away; - allocate the graph once on the allocator path instead of twice.
I tried it locally to check that it holds. auto_dynamic_build becomes:
auto verified_parameters = parameters;
verify_and_set_default_index_parameters(verified_parameters, distance);
graph_type graph{data.size(), verified_parameters.graph_max_degree, graph_allocator};
auto entry_point = data.size() == 0 ? 0 : extensions::compute_entry_point(data, threadpool);
return MutableVamanaIndex<graph_type, data_type, Distance>(
verified_parameters, std::move(graph), std::move(data), lib::narrow<Idx>(entry_point),
std::move(distance), external_ids, std::move(threadpool), std::move(logger));Points I'm unsure about:
- Sequential has no reverse edges. Not sure if that already breaks the option to mirror #380.
- In sequential, direct callers of
MutableVamanaIndexcannot pass an allocator to the build-from-scratch constructor. They have to allocate the graph and compute the entry point themselves, then call the ready-graph constructor. Is this a limitation we could fix for both versions, assuming we decide to mirror the patterns?
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
Review effort: Lite
Findings: 3
Open (6)
reverse_edges_rebindable_vintends to evaluate tofalsefor allocators that cannot rebind to… · NewConcurrentDynamicVamana::build(...)takesstd::span<const size_t>but this header does not… · New This test file usesstd::span(line ~200) andstd::min(line ~300) but does not include… · New Theassemble(...)overload takesconst Distance&, but later forwards intomake(...)and uses… · New Initialize iterator implementation from the index factory Const-correct allocator equality to preserve huge-page allocation
Resolved since last review (2)
c678176 to
9a4c37d
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Construction retains costly reverse-edge bookkeeping, and important concurrency, allocator, and state-restoration paths need stronger coverage.
Review effort: Balanced
Findings: 4
Open (4)
Resolved since last review (6)
This test file usesstd::span(line ~200) andstd::min(line ~300) but does not include…ConcurrentDynamicVamana::build(...)takesstd::span<const size_t>but this header does not…reverse_edges_rebindable_vintends to evaluate tofalsefor allocators that cannot rebind to… Theassemble(...)overload takesconst Distance&, but later forwards intomake(...)and uses… Initialize iterator implementation from the index factory Const-correct allocator equality to preserve huge-page allocation
41a4f67 to
6775223
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The assembly constructor breaks an existing public signature, and key concurrent and hole-aware behavior lacks deterministic coverage.
3 open findings
🧠 Review effort: Balanced
Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.
| const Dist& distance_function, | ||
| const std::vector<SlotMetadata>& status, |
|
This pull request does not currently match the merge queue conditions, so it cannot be queued from here. The box comes back if it matches again. |
e753cca to
886bd8a
Compare
…VamanaIndex .ctors structure
886bd8a to
47164bc
Compare



This pull request introduces significant improvements to the concurrent dynamic Vamana index, focusing on allocator flexibility, type safety, and enhanced assembly and construction options. The changes make it easier to use custom allocators for graph storage, provide robust mechanisms for assembling indices from existing data, and improve the underlying type traits and loading mechanisms to ensure correctness and extensibility.
Key changes include:
Allocator and Storage Flexibility
SimpleBlockedGraphis now templated on its allocator type, allowing users to specify custom allocators instead of being limited toHugepageAllocator. All loading and construction methods inSimpleBlockedGraphnow accept an allocator parameter, making it easier to control memory management.std::allocator. This is determined by a newreverse_edges_rebindable_vtrait. [1] [2] [3]Type Traits and Compile-Time Safety
is_segmented_blocked_vtrait to detect at compile-time whether an allocator or dataset uses segmented blocked storage, ensuring that only compatible types are used with the concurrent index.Index Construction and Assembly
auto_dynamic_buildfunction that builds a concurrent dynamic Vamana index using grow-stable (segmented blocked) storage for both data and graph, enforcing allocator compatibility at compile time.MutableVamanaIndexthat assembles an index from arbitrary data, graph, status, and ID translator, with robust precondition checks to ensure consistency and correctness.API Improvements and Documentation
MutableVamanaIndexfor accessing the ID translator and obtaining a snapshot of slot statuses, improving observability and debugging.README.md) to describe the new type-erased wrapper and allocator selection mechanisms for concurrent dynamic Vamana.These changes collectively make the concurrent dynamic Vamana index more flexible, safer, and easier to use in a variety of memory management scenarios.