[C-API] Add getter and setter for index threadpool size#305
[C-API] Add getter and setter for index threadpool size#305
Conversation
There was a problem hiding this comment.
Pull request overview
Adds C API support to query and modify the search thread pool size for an SVS index after construction, by persisting thread pool configuration alongside the index implementation.
Changes:
- Added
svs_index_get_num_threads/svs_index_set_num_threadsto the public C API. - Extended C-binding index wrappers to retain a
ThreadPoolBuilderand rebuild the underlying thread pool on resize. - Enhanced
ThreadPoolBuilderwith thread-count querying and resize support.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| bindings/c/src/threadpool.hpp | Adds threadpool kind/user-threadpool tracking plus get_threads_num() and resize() support. |
| bindings/c/src/svs_c.cpp | Implements the new C API getter/setter wrappers. |
| bindings/c/src/index_builder.hpp | Passes ThreadPoolBuilder into built/loaded index wrappers. |
| bindings/c/src/index.hpp | Stores ThreadPoolBuilder inside index wrappers; adds virtual get/set thread count hooks. |
| bindings/c/include/svs/c_api/svs_c.h | Declares and documents the new C API functions. |
fc0d9fa to
07a2493
Compare
|
@rfsaliev, when you are happy with the Copilot review, please ask Kelly for a review as well. |
|
@klmckeig, can you please review the feature? |
|
@klmckeig, we would still like your review for this PR. |
matt-welch
left a comment
There was a problem hiding this comment.
Perspective from downstream C API integrations
This fills a genuine gap. The current C API only allows setting the thread pool through the builder before load, which means a loaded index's parallelism is fixed for its lifetime. Having set_num_threads on the live index handle is the right approach for integrations that need to honor runtime configuration changes without tearing down and reloading the index.
Concurrency contract is the main question this raises at the integration level. Database workloads call svs_index_search() concurrently with configuration changes — a session may call set_num_threads() on the same index handle that another thread is actively searching. The PR doesn't document whether resize() is safe to call concurrently with in-flight searches, or whether the caller is expected to quiesce the index first. Making that contract explicit in the API documentation would allow integrations to make correct decisions about whether additional locking is needed on their side.
Getter reliability: get_num_threads() reads from the retained ThreadPoolBuilder rather than the live pool. For an integration tracking applied state, this means the getter can't be used to verify that a set took effect — the integration has to track the last-applied value itself. That's workable, but it limits the practical utility of the getter for anything beyond initial inspection.
These are design-level observations, not blockers. The core API shape is exactly what's needed.
|
Thank you @matt-welch for the review comment. According to the concurrency issues, the comment is right. This limitation is applicable to all index modifications in all SVS APIs. We will reflected it in the main documentation in form of "SVS indices generally not thread-safe for concurrent modifications". According to the "getter reliability", thank you for the confirmation of Copilot's comment. Will fix it soon. |
534161d to
7fdd3fb
Compare
|
@copilot I want to restore the initial PR description prior to Copilot changes made today |
Done — the PR description has been restored to the original content, with the |
Adds
svs_index_get_num_threads/svs_index_set_num_threadsto the C API, enabling dynamic inspection and resizing of the search threadpool after index construction.ThreadPoolBuilder
get_threads_num()— delegates to the custom pool'ssize()op whenkind == CUSTOM, otherwise returns the stored countresize(n)— updates stored thread count; throwsstd::invalid_argumentforn == 0,SINGLE_THREAD, orCUSTOMkinds (surfaced asSVS_ERROR_INVALID_ARGUMENTthroughwrap_exceptions)Index wrappers (
index.hpp)Indexstores aThreadPoolBuilder;get_num_threads()is pure-virtual — implemented inIndexVamanaandDynamicIndexVamanaby delegating to the wrappedsvs::Vamana/svs::DynamicVamanainstance, so the value reflects actual runtime stateset_num_threads(n)callspool_builder.resize(n)then rebuilds and installs the threadpool viaset_threadpool()C API (
svs_c.cpp/svs_c.h)index->implnon-null before dereferencing (consistent with existing handle-check pattern)