| 61 | /// \pre offsets.null_count() > 0 |
| 62 | template <typename TYPE> |
| 63 | Result<BufferVector> CleanListOffsets(const std::shared_ptr<Buffer>& validity_buffer, |
| 64 | const Array& offsets, MemoryPool* pool) { |
| 65 | using offset_type = typename TYPE::offset_type; |
| 66 | using OffsetArrowType = typename CTypeTraits<offset_type>::ArrowType; |
| 67 | using OffsetArrayType = typename TypeTraits<OffsetArrowType>::ArrayType; |
| 68 | |
| 69 | DCHECK_GT(offsets.null_count(), 0); |
| 70 | const int64_t num_offsets = offsets.length(); |
| 71 | |
| 72 | if (!offsets.IsValid(num_offsets - 1)) { |
| 73 | return Status::Invalid("Last list offset should be non-null"); |
| 74 | } |
| 75 | |
| 76 | ARROW_ASSIGN_OR_RAISE(auto clean_offsets, |
| 77 | AllocateBuffer(num_offsets * sizeof(offset_type), pool)); |
| 78 | |
| 79 | // Copy valid bits, ignoring the final offset (since for a length N list array, |
| 80 | // we have N + 1 offsets) |
| 81 | ARROW_ASSIGN_OR_RAISE( |
| 82 | auto clean_validity_buffer, |
| 83 | CopyBitmap(pool, offsets.null_bitmap()->data(), offsets.offset(), num_offsets - 1)); |
| 84 | |
| 85 | const offset_type* raw_offsets = |
| 86 | checked_cast<const OffsetArrayType&>(offsets).raw_values(); |
| 87 | auto clean_raw_offsets = reinterpret_cast<offset_type*>(clean_offsets->mutable_data()); |
| 88 | |
| 89 | // Must work backwards so we can tell how many values were in the last non-null value |
| 90 | offset_type current_offset = raw_offsets[num_offsets - 1]; |
| 91 | for (int64_t i = num_offsets - 1; i >= 0; --i) { |
| 92 | if (offsets.IsValid(i)) { |
| 93 | current_offset = raw_offsets[i]; |
| 94 | } |
| 95 | clean_raw_offsets[i] = current_offset; |
| 96 | } |
| 97 | |
| 98 | return BufferVector({std::move(clean_validity_buffer), std::move(clean_offsets)}); |
| 99 | } |
| 100 | |
| 101 | template <typename TYPE> |
| 102 | Result<std::shared_ptr<typename TypeTraits<TYPE>::ArrayType>> ListArrayFromArrays( |
nothing calls this directly
no test coverage detected