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

Function PutListViewOffsets

cpp/src/arrow/array/concatenate.cc:273–335  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

271
272template <typename offset_type>
273Result<OffsetBufferOpOutcome> PutListViewOffsets(const ArrayData& input,
274 offset_type* sizes, const Buffer& src,
275 offset_type displacement,
276 offset_type* dst) {
277 if (src.size() == 0) {
278 return OffsetBufferOpOutcome::kOk;
279 }
280 const auto& validity_buffer = input.buffers[0];
281 if (validity_buffer) {
282 // Ensure that it is safe to access all the bits in the validity bitmap of input.
283 RETURN_NOT_OK(internal::CheckSliceParams(/*size=*/8 * validity_buffer->size(),
284 input.offset, input.length, "buffer"));
285 }
286
287 const auto offsets = src.data_as<offset_type>();
288 DCHECK_EQ(static_cast<int64_t>(src.size() / sizeof(offset_type)), input.length);
289
290 auto visit_not_null = [&](int64_t position) {
291 if (sizes[position] > 0) {
292 // NOTE: Concatenate can be called during IPC reads to append delta
293 // dictionaries. Avoid UB on non-validated input by doing the addition in the
294 // unsigned domain. (the result can later be validated using
295 // Array::ValidateFull)
296 const auto displaced_offset = SafeSignedAdd(offsets[position], displacement);
297 // displaced_offset>=0 is guaranteed by RangeOfValuesUsed returning the
298 // smallest offset of valid and non-empty list-views.
299 DCHECK_GE(displaced_offset, 0);
300 dst[position] = displaced_offset;
301 } else {
302 // Do nothing to leave the dst[position] as 0.
303 }
304 };
305
306 const auto* validity = validity_buffer ? validity_buffer->data_as<uint8_t>() : nullptr;
307 internal::OptionalBitBlockCounter bit_counter(validity, input.offset, input.length);
308 int64_t position = 0;
309 while (position < input.length) {
310 internal::BitBlockCount block = bit_counter.NextBlock();
311 if (block.AllSet()) {
312 for (int64_t i = 0; i < block.length; ++i, ++position) {
313 visit_not_null(position);
314 }
315 } else if (block.NoneSet()) {
316 // NOTE: we don't have to do anything for the null entries regarding the
317 // offsets as the buffer is initialized to 0 when it is allocated.
318
319 // Zero-out the sizes of the null entries to ensure these sizes are not
320 // greater than the new values length of the concatenated array.
321 memset(sizes + position, 0, block.length * sizeof(offset_type));
322 position += block.length;
323 } else {
324 for (int64_t i = 0; i < block.length; ++i, ++position) {
325 if (bit_util::GetBit(validity, input.offset + position)) {
326 visit_not_null(position);
327 } else {
328 // Zero-out the size at position.
329 sizes[position] = 0;
330 }

Callers

nothing calls this directly

Calls 7

CheckSliceParamsFunction · 0.85
NextBlockMethod · 0.80
NoneSetMethod · 0.80
SafeSignedAddFunction · 0.50
GetBitFunction · 0.50
sizeMethod · 0.45
AllSetMethod · 0.45

Tested by

no test coverage detected