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

Function PropagateNullsSpans

cpp/src/arrow/compute/exec.cc:1222–1281  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1220}
1221
1222void PropagateNullsSpans(const ExecSpan& batch, ArraySpan* out) {
1223 if (out->type->id() == Type::NA) {
1224 // Null output type is a no-op (rare when this would happen but we at least
1225 // will test for it)
1226 return;
1227 }
1228
1229 std::vector<const ArraySpan*> arrays_with_nulls;
1230 bool is_all_null = false;
1231 for (const ExecValue& value : batch.values) {
1232 auto null_generalization = NullGeneralization::Get(value);
1233 if (null_generalization == NullGeneralization::ALL_NULL) {
1234 is_all_null = true;
1235 }
1236 if (null_generalization != NullGeneralization::ALL_VALID && value.is_array()) {
1237 arrays_with_nulls.push_back(&value.array);
1238 }
1239 }
1240 uint8_t* out_bitmap = out->buffers[0].data;
1241 if (is_all_null) {
1242 // An all-null value (scalar null or all-null array) gives us a short
1243 // circuit opportunity
1244 // OK, the output should be all null
1245 out->null_count = out->length;
1246 bit_util::SetBitsTo(out_bitmap, out->offset, out->length, false);
1247 return;
1248 }
1249
1250 out->null_count = kUnknownNullCount;
1251 if (arrays_with_nulls.empty()) {
1252 // No arrays with nulls case
1253 out->null_count = 0;
1254 if (out_bitmap != nullptr) {
1255 // An output buffer was allocated, so we fill it with all valid
1256 bit_util::SetBitsTo(out_bitmap, out->offset, out->length, true);
1257 }
1258 } else if (arrays_with_nulls.size() == 1) {
1259 // One array
1260 const ArraySpan& arr = *arrays_with_nulls[0];
1261
1262 // Reuse the null count if it's known
1263 out->null_count = arr.null_count;
1264 CopyBitmap(arr.buffers[0].data, arr.offset, arr.length, out_bitmap, out->offset);
1265 } else {
1266 // More than one array. We use BitmapAnd to intersect their bitmaps
1267 auto Accumulate = [&](const ArraySpan& left, const ArraySpan& right) {
1268 DCHECK(left.buffers[0].data != nullptr);
1269 DCHECK(right.buffers[0].data != nullptr);
1270 BitmapAnd(left.buffers[0].data, left.offset, right.buffers[0].data, right.offset,
1271 out->length, out->offset, out_bitmap);
1272 };
1273 // Seed the output bitmap with the & of the first two bitmaps
1274 Accumulate(*arrays_with_nulls[0], *arrays_with_nulls[1]);
1275
1276 // Accumulate the rest
1277 for (size_t i = 2; i < arrays_with_nulls.size(); ++i) {
1278 Accumulate(*out, *arrays_with_nulls[i]);
1279 }

Callers 2

TEST_FFunction · 0.85
ExecuteSingleSpanMethod · 0.85

Calls 10

BitmapAndFunction · 0.85
AccumulateFunction · 0.85
is_arrayMethod · 0.80
push_backMethod · 0.80
GetFunction · 0.70
SetBitsToFunction · 0.50
CopyBitmapFunction · 0.50
idMethod · 0.45
emptyMethod · 0.45
sizeMethod · 0.45

Tested by 1

TEST_FFunction · 0.68