|
29 | 29 | #include "arrow/result.h" |
30 | 30 | #include "arrow/type.h" |
31 | 31 | #include "arrow/type_traits.h" |
| 32 | +#include "arrow/util/bit_util.h" |
32 | 33 | #include "arrow/util/formatting.h" |
33 | 34 | #include "arrow/util/int_util.h" |
34 | 35 | #include "arrow/util/logging_internal.h" |
@@ -305,23 +306,33 @@ BinaryToBinaryCastExec(KernelContext* ctx, const ExecSpan& batch, ExecResult* ou |
305 | 306 | } |
306 | 307 | } |
307 | 308 |
|
308 | | - std::shared_ptr<ArrayData> input_arr = input.ToArrayData(); |
309 | | - ArrayData* output = out->array_data().get(); |
310 | | - output->length = input_arr->length; |
311 | | - output->SetNullCount(input_arr->null_count); |
312 | | - output->buffers = std::move(input_arr->buffers); |
313 | | - output->child_data = std::move(input_arr->child_data); |
314 | | - |
315 | | - if (output->buffers[0]) { |
316 | | - // If reusing the null bitmap, ensure offset into the first byte is the same as input. |
317 | | - output->offset = input_arr->offset % 8; |
318 | | - output->buffers[0] = SliceBuffer(output->buffers[0], input_arr->offset / 8); |
| 309 | + if constexpr (sizeof(typename I::offset_type) != sizeof(typename O::offset_type)) { |
| 310 | + std::shared_ptr<ArrayData> input_arr = input.ToArrayData(); |
| 311 | + ArrayData* output = out->array_data().get(); |
| 312 | + output->length = input_arr->length; |
| 313 | + // output->offset is set below |
| 314 | + output->SetNullCount(input_arr->null_count); |
| 315 | + output->buffers = std::move(input_arr->buffers); |
| 316 | + |
| 317 | + // Slice buffers to reduce allocation when casting the offsets buffer |
| 318 | + int64_t offset = input_arr->offset; |
| 319 | + size_t input_offset_type_size = sizeof(typename I::offset_type); |
| 320 | + if (output->null_count != 0 && output->buffers[0]) { |
| 321 | + // Avoid reallocation of the validity buffer by allowing some padding bits |
| 322 | + output->offset = input_arr->offset % 8; |
| 323 | + } else { |
| 324 | + output->offset = 0; |
| 325 | + } |
| 326 | + if (output->buffers[0]) { |
| 327 | + output->buffers[0] = SliceBuffer(output->buffers[0], offset / 8); |
| 328 | + } |
| 329 | + output->buffers[1] = SliceBuffer(output->buffers[1], offset * input_offset_type_size); |
| 330 | + |
| 331 | + return CastBinaryToBinaryOffsets<typename I::offset_type, typename O::offset_type>( |
| 332 | + ctx, input, out->array_data().get()); |
319 | 333 | } else { |
320 | | - output->offset = 0; |
| 334 | + return ZeroCopyCastExec(ctx, batch, out); |
321 | 335 | } |
322 | | - |
323 | | - return CastBinaryToBinaryOffsets<typename I::offset_type, typename O::offset_type>( |
324 | | - ctx, input, out->array_data().get()); |
325 | 336 | } |
326 | 337 |
|
327 | 338 | // String View -> Offset String |
|
0 commit comments