-
Notifications
You must be signed in to change notification settings - Fork 145
zero copy validity export to duckdb #7371
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -56,6 +56,21 @@ class DataVector : public Vector { | |
| inline void SetDataPtr(data_ptr_t ptr) { | ||
| data = ptr; | ||
| }; | ||
|
|
||
| inline ValidityMask &GetValidity() { | ||
| return validity; | ||
| }; | ||
| }; | ||
|
|
||
| // Same hack for ValidityMask: access protected fields via inheritance. | ||
| class ExternalValidityMask : public ValidityMask { | ||
| public: | ||
| inline void SetExternal(validity_t *ptr, idx_t cap, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, pass just the buffer and derive ptr from it |
||
| buffer_ptr<ValidityBuffer> keeper) { | ||
| validity_mask = ptr; | ||
| capacity = cap; | ||
| validity_data = std::move(keeper); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is right as TemplatedValidityMask(V* ptr, idx_t capacity) constructor sets the pointer but doesn't change validity_data, so these two aren't derived. |
||
| }; | ||
| }; | ||
|
|
||
| } // namespace vortex | ||
|
|
@@ -81,6 +96,26 @@ extern "C" void duckdb_vx_vector_set_data_ptr(duckdb_vector ffi_vector, void *pt | |
| dvector->SetDataPtr((data_ptr_t)ptr); | ||
| } | ||
|
|
||
| extern "C" void duckdb_vx_vector_set_validity_data(duckdb_vector ffi_vector, | ||
| void *validity_ptr, | ||
| idx_t capacity, | ||
| duckdb_vx_vector_buffer buffer) { | ||
| auto dvector = reinterpret_cast<vortex::DataVector *>(ffi_vector); | ||
| auto &validity = dvector->GetValidity(); | ||
| auto ext_validity = reinterpret_cast<vortex::ExternalValidityMask *>(&validity); | ||
|
|
||
| // Use the shared_ptr aliasing constructor: the control block ref-counts the | ||
| // ExternalVectorBuffer (preventing the Rust buffer from being freed), | ||
| // while the stored pointer satisfies ValidityMask's buffer_ptr<ValidityBuffer> type. | ||
| auto ext_buf = reinterpret_cast<shared_ptr<vortex::ExternalVectorBuffer> *>(buffer); | ||
| auto keeper = shared_ptr<TemplatedValidityData<validity_t>>( | ||
| *ext_buf, reinterpret_cast<TemplatedValidityData<validity_t> *>(ext_buf->get())); | ||
|
|
||
| // Set validity_mask, capacity, and validity_data (which keeps the buffer alive). | ||
| ext_validity->SetExternal(reinterpret_cast<validity_t *>(validity_ptr), capacity, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Technically this will slice the class to base's validity, but as derived class doesn't have any members, it's fine. Worth adding a comment |
||
| std::move(keeper)); | ||
| } | ||
|
|
||
| extern "C" duckdb_value duckdb_vx_vector_get_value(duckdb_vector ffi_vector, idx_t index) { | ||
| auto vector = reinterpret_cast<Vector *>(ffi_vector); | ||
| auto value = duckdb::make_uniq<Value>(vector->GetValue(index)); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If validity_ptr points to buffer, just pass the buffer