| 401 | |
| 402 | template <bool OUTPUT_BYTE_ALIGNED> |
| 403 | void ExecBatchBuilder::CollectBitsImp(const uint8_t* input_bits, |
| 404 | int64_t input_bits_offset, uint8_t* output_bits, |
| 405 | int64_t output_bits_offset, int num_rows, |
| 406 | const uint16_t* row_ids) { |
| 407 | if (!OUTPUT_BYTE_ALIGNED) { |
| 408 | ARROW_DCHECK(output_bits_offset % 8 > 0); |
| 409 | output_bits[output_bits_offset / 8] &= |
| 410 | static_cast<uint8_t>((1 << (output_bits_offset % 8)) - 1); |
| 411 | } else { |
| 412 | ARROW_DCHECK(output_bits_offset % 8 == 0); |
| 413 | } |
| 414 | constexpr int unroll = 8; |
| 415 | for (int i = 0; i < num_rows / unroll; ++i) { |
| 416 | const uint16_t* row_ids_base = row_ids + unroll * i; |
| 417 | uint8_t result; |
| 418 | result = bit_util::GetBit(input_bits, input_bits_offset + row_ids_base[0]) ? 1 : 0; |
| 419 | result |= bit_util::GetBit(input_bits, input_bits_offset + row_ids_base[1]) ? 2 : 0; |
| 420 | result |= bit_util::GetBit(input_bits, input_bits_offset + row_ids_base[2]) ? 4 : 0; |
| 421 | result |= bit_util::GetBit(input_bits, input_bits_offset + row_ids_base[3]) ? 8 : 0; |
| 422 | result |= bit_util::GetBit(input_bits, input_bits_offset + row_ids_base[4]) ? 16 : 0; |
| 423 | result |= bit_util::GetBit(input_bits, input_bits_offset + row_ids_base[5]) ? 32 : 0; |
| 424 | result |= bit_util::GetBit(input_bits, input_bits_offset + row_ids_base[6]) ? 64 : 0; |
| 425 | result |= bit_util::GetBit(input_bits, input_bits_offset + row_ids_base[7]) ? 128 : 0; |
| 426 | if (OUTPUT_BYTE_ALIGNED) { |
| 427 | output_bits[output_bits_offset / 8 + i] = result; |
| 428 | } else { |
| 429 | output_bits[output_bits_offset / 8 + i] |= |
| 430 | static_cast<uint8_t>(result << (output_bits_offset % 8)); |
| 431 | output_bits[output_bits_offset / 8 + i + 1] = |
| 432 | static_cast<uint8_t>(result >> (8 - (output_bits_offset % 8))); |
| 433 | } |
| 434 | } |
| 435 | if (num_rows % unroll > 0) { |
| 436 | for (int i = num_rows - (num_rows % unroll); i < num_rows; ++i) { |
| 437 | bit_util::SetBitTo(output_bits, output_bits_offset + i, |
| 438 | bit_util::GetBit(input_bits, input_bits_offset + row_ids[i])); |
| 439 | } |
| 440 | } |
| 441 | } |
| 442 | |
| 443 | void ExecBatchBuilder::CollectBits(const uint8_t* input_bits, int64_t input_bits_offset, |
| 444 | uint8_t* output_bits, int64_t output_bits_offset, |