MCPcopy Create free account
hub / github.com/apache/arrow / ExecArrayCaseWhen

Function ExecArrayCaseWhen

cpp/src/arrow/compute/kernels/scalar_if_else.cc:1571–1688  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1569// given helper functions to copy data from a source array to a target array
1570template <typename Type>
1571Status ExecArrayCaseWhen(KernelContext* ctx, const ExecSpan& batch, ExecResult* out) {
1572 const ArraySpan& conds_array = batch[0].array;
1573 if (conds_array.GetNullCount() > 0) {
1574 return Status::Invalid(
1575 "cond struct must not be a null scalar or "
1576 "have top-level nulls");
1577 }
1578 ArraySpan* output = out->array_span_mutable();
1579 const int64_t out_offset = output->offset;
1580 const auto num_value_args = batch.values.size() - 1;
1581 const bool have_else_arg =
1582 static_cast<size_t>(conds_array.type->num_fields()) < num_value_args;
1583 uint8_t* out_valid = output->buffers[0].data;
1584 uint8_t* out_values = output->buffers[1].data;
1585
1586 if (have_else_arg) {
1587 // Copy 'else' value into output
1588 CopyValues<Type>(batch.values.back(), /*in_offset=*/0, batch.length, out_valid,
1589 out_values, out_offset);
1590 } else {
1591 // There's no 'else' argument, so we should have an all-null validity bitmap
1592 bit_util::SetBitsTo(out_valid, out_offset, batch.length, false);
1593 }
1594
1595 // Allocate a temporary bitmap to determine which elements still need setting.
1596 ARROW_ASSIGN_OR_RAISE(auto mask_buffer, ctx->AllocateBitmap(batch.length));
1597 uint8_t* mask = mask_buffer->mutable_data();
1598 std::memset(mask, 0xFF, mask_buffer->size());
1599
1600 // Then iterate through each argument in turn and set elements.
1601 for (int i = 0; i < batch.num_values() - (have_else_arg ? 2 : 1); i++) {
1602 const ArraySpan& cond_array = conds_array.child_data[i];
1603 const int64_t cond_offset = conds_array.offset + cond_array.offset;
1604 const uint8_t* cond_values = cond_array.buffers[1].data;
1605 const ExecValue& value = batch[i + 1];
1606 int64_t offset = 0;
1607
1608 if (cond_array.GetNullCount() == 0) {
1609 // If no valid buffer, visit mask & cond bitmap simultaneously
1610 BinaryBitBlockCounter counter(mask, /*start_offset=*/0, cond_values, cond_offset,
1611 batch.length);
1612 while (offset < batch.length) {
1613 const auto block = counter.NextAndWord();
1614 if (block.AllSet()) {
1615 CopyValues<Type>(value, offset, block.length, out_valid, out_values,
1616 out_offset + offset);
1617 bit_util::SetBitsTo(mask, offset, block.length, false);
1618 } else if (block.popcount) {
1619 for (int64_t j = 0; j < block.length; ++j) {
1620 if (bit_util::GetBit(mask, offset + j) &&
1621 bit_util::GetBit(cond_values, cond_offset + offset + j)) {
1622 CopyValues<Type>(value, offset + j, /*length=*/1, out_valid, out_values,
1623 out_offset + offset + j);
1624 bit_util::SetBitTo(mask, offset + j, false);
1625 }
1626 }
1627 }
1628 offset += block.length;

Callers

nothing calls this directly

Calls 15

VisitWordsFunction · 0.85
BytesForBitsFunction · 0.85
ClearBitFunction · 0.85
GetNullCountMethod · 0.80
backMethod · 0.80
NoneSetMethod · 0.80
InvalidFunction · 0.50
SetBitsToFunction · 0.50
GetBitFunction · 0.50
SetBitToFunction · 0.50
OKFunction · 0.50
sizeMethod · 0.45

Tested by

no test coverage detected