| 453 | // This is for fixed-size types only |
| 454 | template <typename Type> |
| 455 | void FillNullInDirectionImpl(const ArraySpan& current_chunk, const uint8_t* null_bitmap, |
| 456 | ExecResult* out, int8_t direction, |
| 457 | const ArraySpan& last_valid_value_chunk, |
| 458 | int64_t* last_valid_value_offset) { |
| 459 | ArrayData* out_arr = out->array_data().get(); |
| 460 | uint8_t* out_bitmap = out_arr->buffers[0]->mutable_data(); |
| 461 | uint8_t* out_values = out_arr->buffers[1]->mutable_data(); |
| 462 | arrow::internal::CopyBitmap(current_chunk.buffers[0].data, current_chunk.offset, |
| 463 | current_chunk.length, out_bitmap, out_arr->offset); |
| 464 | CopyDataUtils<Type>::CopyData(*current_chunk.type, current_chunk, /*in_offset=*/0, |
| 465 | out_values, /*out_offset=*/out_arr->offset, |
| 466 | current_chunk.length); |
| 467 | |
| 468 | bool has_fill_value = *last_valid_value_offset != -1; |
| 469 | int64_t write_offset = direction == 1 ? 0 : current_chunk.length - 1; |
| 470 | int64_t bitmap_offset = 0; |
| 471 | |
| 472 | arrow::internal::OptionalBitBlockCounter counter(null_bitmap, out_arr->offset, |
| 473 | current_chunk.length); |
| 474 | bool use_current_chunk = false; |
| 475 | while (bitmap_offset < current_chunk.length) { |
| 476 | BitBlockCount block = counter.NextBlock(); |
| 477 | if (block.AllSet()) { |
| 478 | *last_valid_value_offset = |
| 479 | write_offset + direction * (block.length - 1 + bitmap_offset); |
| 480 | has_fill_value = true; |
| 481 | use_current_chunk = true; |
| 482 | } else { |
| 483 | uint64_t block_start_offset = write_offset + direction * bitmap_offset; |
| 484 | uint64_t write_value_offset = block_start_offset; |
| 485 | if (block.popcount) { |
| 486 | for (int64_t i = 0; i < block.length; i++, write_value_offset += direction) { |
| 487 | auto current_bit = bit_util::GetBit(null_bitmap, bitmap_offset + i); |
| 488 | if (!current_bit) { |
| 489 | if (has_fill_value) { |
| 490 | CopyDataUtils<Type>::CopyData( |
| 491 | *current_chunk.type, |
| 492 | use_current_chunk ? current_chunk : last_valid_value_chunk, |
| 493 | *last_valid_value_offset, out_values, write_value_offset, |
| 494 | /*length=*/1); |
| 495 | bit_util::SetBitTo(out_bitmap, write_value_offset, true); |
| 496 | } |
| 497 | } else { |
| 498 | has_fill_value = true; |
| 499 | use_current_chunk = true; |
| 500 | *last_valid_value_offset = write_value_offset; |
| 501 | } |
| 502 | } |
| 503 | } else { |
| 504 | for (int64_t i = 0; i < block.length; i++, write_value_offset += direction) { |
| 505 | if (has_fill_value) { |
| 506 | CopyDataUtils<Type>::CopyData( |
| 507 | *current_chunk.type, |
| 508 | use_current_chunk ? current_chunk : last_valid_value_chunk, |
| 509 | *last_valid_value_offset, out_values, write_value_offset, |
| 510 | /*length=*/1); |
| 511 | bit_util::SetBitTo(out_bitmap, write_value_offset, true); |
| 512 | } |
nothing calls this directly
no test coverage detected