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

Function FlattenListViewArray

cpp/src/arrow/array/array_nested.cc:268–353  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

266
267template <typename ListViewArrayT, bool HasNulls>
268Result<std::shared_ptr<Array>> FlattenListViewArray(const ListViewArrayT& list_view_array,
269 MemoryPool* memory_pool) {
270 using offset_type = typename ListViewArrayT::offset_type;
271 const int64_t list_view_array_offset = list_view_array.offset();
272 const int64_t list_view_array_length = list_view_array.length();
273 std::shared_ptr<arrow::Array> value_array = list_view_array.values();
274
275 if (list_view_array_length == 0) {
276 return SliceArrayWithOffsets(*value_array, 0, 0);
277 }
278
279 // If the list array is *all* nulls, then just return an empty array.
280 if constexpr (HasNulls) {
281 if (list_view_array.null_count() == list_view_array.length()) {
282 return MakeEmptyArray(value_array->type(), memory_pool);
283 }
284 }
285
286 const auto* validity = list_view_array.data()->template GetValues<uint8_t>(0, 0);
287 const auto* offsets = list_view_array.data()->template GetValues<offset_type>(1);
288 const auto* sizes = list_view_array.data()->template GetValues<offset_type>(2);
289
290 auto is_null_or_empty = [&](int64_t i) {
291 if (HasNulls && !bit_util::GetBit(validity, list_view_array_offset + i)) {
292 return true;
293 }
294 return sizes[i] == 0;
295 };
296
297 // Index of the first valid, non-empty list-view.
298 int64_t first_i = 0;
299 for (; first_i < list_view_array_length; first_i++) {
300 if (!is_null_or_empty(first_i)) {
301 break;
302 }
303 }
304 // If all list-views are empty, return an empty array.
305 if (first_i == list_view_array_length) {
306 return MakeEmptyArray(value_array->type(), memory_pool);
307 }
308
309 std::vector<std::shared_ptr<Array>> slices;
310 {
311 int64_t i = first_i;
312 auto begin_offset = offsets[i];
313 auto end_offset = offsets[i] + sizes[i];
314 i += 1;
315 // Inductive invariant: slices and the always non-empty values slice
316 // [begin_offset, end_offset) contains all the maximally contiguous slices of the
317 // values array that are covered by all the list-views before list-view i.
318 for (; i < list_view_array_length; i++) {
319 if (is_null_or_empty(i)) {
320 // The invariant is preserved by simply preserving the current set of slices.
321 } else {
322 if (offsets[i] == end_offset) {
323 end_offset += sizes[i];
324 // The invariant is preserved because since the non-empty list-view i
325 // starts at end_offset, the current range can be extended to end at

Callers

nothing calls this directly

Calls 12

SliceArrayWithOffsetsFunction · 0.85
ConcatenateFunction · 0.85
push_backMethod · 0.80
MakeEmptyArrayFunction · 0.70
GetBitFunction · 0.50
offsetMethod · 0.45
lengthMethod · 0.45
valuesMethod · 0.45
null_countMethod · 0.45
typeMethod · 0.45
dataMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected