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

Function ExecArrayCoalesce

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

Source from the content-addressed store, hash-verified

2110// Implement 'coalesce' for any mix of scalar/array arguments for any fixed-width type
2111template <typename Type>
2112Status ExecArrayCoalesce(KernelContext* ctx, const ExecSpan& batch, ExecResult* out) {
2113 ArraySpan* output = out->array_span_mutable();
2114 const int64_t out_offset = output->offset;
2115 // Use output validity buffer as mask to decide what values to copy
2116 uint8_t* out_valid = output->buffers[0].data;
2117
2118 // Clear output validity buffer - no values are set initially
2119 bit_util::SetBitsTo(out_valid, out_offset, batch.length, false);
2120 uint8_t* out_values = output->buffers[1].data;
2121
2122 for (const ExecValue& value : batch.values) {
2123 if (value.null_count() == 0) {
2124 // Valid scalar, or all-valid array
2125 CopyValuesAllValid<Type>(value, out_valid, out_values, out_offset, batch.length);
2126 break;
2127 } else if (value.is_array()) {
2128 // Array with nulls
2129 const ArraySpan& arr = value.array;
2130 const int64_t in_offset = arr.offset;
2131 const int64_t in_null_count = arr.GetNullCount();
2132 DCHECK_GT(in_null_count, 0);
2133 const DataType& type = *arr.type;
2134 const uint8_t* in_valid = arr.buffers[0].data;
2135 const uint8_t* in_values = arr.buffers[1].data;
2136
2137 if (in_null_count < 0.8 * batch.length) {
2138 // The input is not mostly null, we deem it more efficient to
2139 // copy values even underlying null slots instead of the more
2140 // expensive bitmasking using BinaryBitBlockCounter.
2141 BitRunReader bit_reader(out_valid, out_offset, batch.length);
2142 int64_t offset = 0;
2143 while (true) {
2144 const auto run = bit_reader.NextRun();
2145 if (run.length == 0) {
2146 break;
2147 }
2148 if (!run.set) {
2149 // Copy from input
2150 CopyDataUtils<Type>::CopyData(type, in_values, in_offset + offset, out_values,
2151 out_offset + offset, run.length);
2152 }
2153 offset += run.length;
2154 }
2155 arrow::internal::BitmapOr(out_valid, out_offset, in_valid, in_offset,
2156 batch.length, out_offset, out_valid);
2157 } else {
2158 BinaryBitBlockCounter counter(in_valid, in_offset, out_valid, out_offset,
2159 batch.length);
2160 int64_t offset = 0;
2161 while (offset < batch.length) {
2162 const auto block = counter.NextAndNotWord();
2163 if (block.AllSet()) {
2164 CopyValues<Type>(value, offset, block.length, out_valid, out_values,
2165 out_offset + offset);
2166 } else if (block.popcount) {
2167 for (int64_t j = 0; j < block.length; ++j) {
2168 if (!bit_util::GetBit(out_valid, out_offset + offset + j) &&
2169 bit_util::GetBit(in_valid, in_offset + offset + j)) {

Callers

nothing calls this directly

Calls 11

BitmapOrFunction · 0.85
InitializeNullSlotsFunction · 0.85
is_arrayMethod · 0.80
GetNullCountMethod · 0.80
SetBitsToFunction · 0.50
GetBitFunction · 0.50
OKFunction · 0.50
null_countMethod · 0.45
NextRunMethod · 0.45
AllSetMethod · 0.45
typeMethod · 0.45

Tested by

no test coverage detected