Uh oh!
There was an error while loading. Please reload this page.
GH-46677: [C++] Expose an BinaryViewBuilder interface for append a binary and multiple subslice - #46730
GH-46677: [C++] Expose an BinaryViewBuilder interface for append a binary and multiple subslice#46730IndifferentArea wants to merge 12 commits into
Conversation
IndifferentArea
commented
Jun 7, 2025
@mapleFU is currently implemented interface expected? |
| return AppendBlock(value.data(), static_cast<int64_t>(value.size())); | ||
| } | ||
| Status AppendViewFromBuffer(int32_t buffer_id, int32_t buffer_offset, int32_t start, |
There was a problem hiding this comment.
Personally both is ok for me, I prefer Buffer since a variable is buffer_index
| UnsafeAppend(value.data(), static_cast<int64_t>(value.size())); | ||
| } | ||
| Result<std::pair<int32_t, int32_t>> AppendBlock(const uint8_t* value, |
There was a problem hiding this comment.
Can we use more specific name rather than pair<i32, i32>?
There was a problem hiding this comment.
can i directly use BinaryViewType::c_type since it already contains these two info we need?
There was a problem hiding this comment.
The syntax is a bit weird here? Append a BinaryView and then append the sub-slice of the view?
| Result<std::pair<int32_t, int32_t>> BinaryViewBuilder::AppendBlock(const uint8_t* value, | ||
| const int64_t length) { | ||
| DCHECK_GT(length, TypeClass::kInlineSize); |
There was a problem hiding this comment.
If length <= kInlineSize, should this return false or ok? Why just DCHECK here?
| c_type GetViewFromBlock(int32_t block_id, int32_t block_offset, int32_t offset, | ||
| int32_t length) const { | ||
| const auto* value = blocks_.at(block_id)->data_as<uint8_t>() + block_offset + offset; | ||
| if (length <= BinaryViewType::kInlineSize) { |
Should we rename Maybe aligning with arrow-rs's impl is fine.. |
mapleFU
commented
Jun 7, 2025
Some personal thoughts:
|
IndifferentArea
commented
Jun 8, 2025
Not sure why these 2 ci always failed.. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
To implement interface aligned with what arrow-rs did, i have to change some behavior of More specific, before If this change is unacceptable, plz let me know, i'll try to find another way. |
| return AppendBuffer(reinterpret_cast<const uint8_t*>(value), length); | ||
| } | ||
| Result<int32_t> AppendBuffer(const std::string& value) { |
There was a problem hiding this comment.
Can std::string_view being used rather than const std::string&?
There was a problem hiding this comment.
Can we remove this one since std::string_view is added here?
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| void UnsafeAppendViewFromBuffer(const int32_t buffer_idx, const int32_t start, | ||
| const int32_t length) { | ||
| UnsafeAppendToBitmap(true); | ||
| const auto v = data_heap_builder_.GetViewFromBuffer<false>(buffer_idx, start, length); |
There was a problem hiding this comment.
| const auto v=data_heap_builder_.GetViewFromBuffer<false>(buffer_idx, start, length); | |
| const auto v=data_heap_builder_.GetViewFromBuffer</*Safe=*/false>(buffer_idx, start, length); |
| const int32_t length) { | ||
| ARROW_RETURN_NOT_OK(Reserve(1)); | ||
| UnsafeAppendToBitmap(true); | ||
| ARROW_ASSIGN_OR_RAISE(const auto v, data_heap_builder_.GetViewFromBuffer<true>( |
There was a problem hiding this comment.
| ARROW_ASSIGN_OR_RAISE(constautov, data_heap_builder_.GetViewFromBuffer<true>( | |
| ARROW_ASSIGN_OR_RAISE(constautov, data_heap_builder_.GetViewFromBuffer</*Safe=*/true>( |
mapleFU
commented
Jun 26, 2025
Gentle ping @pitrou |
pitrou
commented
Jun 26, 2025
Isn't this approach wasteful? If you have lots of strings <= 12 bytes, you will still store their contents in a data buffer, while they're inlined in the string views. |
mapleFU
commented
Jun 26, 2025
@pitrou I suppose this is used to append a whole parquet page and add buffer for it |
pitrou
commented
Jun 26, 2025
Is it a win, though? If most Parquet strings are <= 12 bytes we would pointlessly waste space and CPU time. |
mapleFU
commented
Jun 26, 2025
A nice question. I agree when most Parquet strings are <= 12 bytes, it would be memory wasted because a huge memcpy is applied. But when read large binary it would benefit a lot from this. I think usally a large memcpy might much faster than little un-continogous memcpy Maybe we can also try to pick this way when average len is huge enough? |
pitrou
commented
Jun 26, 2025
That's true, but another cost is to create the views themselves. It would be nice if a prototype could tell us which speedup we can expect.
Yes, that's definitely a possibility. |
mapleFU
commented
Jun 26, 2025
So can we start to review this? We can set a ratio when average length > 12 or > 20 |
andishgar
commented
Jun 29, 2025
@mapleFU@pitrou 1- API and Handling of the Last Buffer 2-
In this pull request, I proposed a method that could help avoid memory bloat when buffers are shared. Additionally, in this issue, I think this metadata could help determine when CompactArray should be called. Overall, my suggestion is to either modify this pull request or create a new API to support buffer sharing. It is possible to decide whether a created array should be compacted based on some metadata, in order to avoid memory bloat. |
mapleFU
commented
Jun 30, 2025
Looks (1) would work in buffer style api, but for parquet reader, it might append buffer one by one. The (2) is a good way for compute, but here I don't know the best way to handle this: whether to adaptive read it, or just throw it to "cast" or "compact". I prefer handling this in reader, and the later handling can "compact" the data when output or throwing to compute |
Besides parquet related issue, there is NO buffer sharing mechanism in current api.
These new interfaces won't introduce more cost for current interfaces from my view. Maybe we can open another issue/PR to discuss specifically whether/how parquet should use this api on appending a huge page and append view from it? |
pitrou
commented
Jun 30, 2025
That sounds fair to me. |
pitrou
commented
Jul 1, 2025
Thanks for the reminder, and sorry that this is taking a long time :) I propose that we review these PRs one by one. I've started with the This PR here is slightly more contentious so I think we should tackle it only after the other APIs have settled semantics. |
Thank you for your contribution. Unfortunately, this pull request has been marked as stale because it has had no activity in the past 365 days. Please remove the stale label or comment below, or this PR will be closed in 14 days. Feel free to re-open this if it has been closed in error. If you do not have repository permissions to reopen the PR, please tag a maintainer. |
Rationale for this change
see #46677
What changes are included in this PR?
see #46677
Are these changes tested?
Yes
Are there any user-facing changes?
No