| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #pragma once |
|
|
| #include <cstdint> |
| #include <limits> |
| #include <memory> |
| #include <utility> |
| #include <vector> |
|
|
| #include "arrow/array/array_nested.h" |
| #include "arrow/array/builder_base.h" |
| #include "arrow/array/data.h" |
| #include "arrow/buffer.h" |
| #include "arrow/buffer_builder.h" |
| #include "arrow/status.h" |
| #include "arrow/type.h" |
| #include "arrow/util/macros.h" |
| #include "arrow/util/visibility.h" |
|
|
| namespace arrow { |
|
|
| |
| |
| |
|
|
| |
| |
|
|
| template <typename TYPE> |
| class VarLengthListLikeBuilder : public ArrayBuilder { |
| public: |
| using TypeClass = TYPE; |
| using offset_type = typename TypeClass::offset_type; |
|
|
| |
| |
| VarLengthListLikeBuilder(MemoryPool* pool, |
| std::shared_ptr<ArrayBuilder> const& value_builder, |
| const std::shared_ptr<DataType>& type, |
| int64_t alignment = kDefaultBufferAlignment) |
| : ArrayBuilder(pool, alignment), |
| offsets_builder_(pool, alignment), |
| value_builder_(value_builder), |
| value_field_(type->field(0)->WithType(NULLPTR)) {} |
|
|
| VarLengthListLikeBuilder(MemoryPool* pool, |
| std::shared_ptr<ArrayBuilder> const& value_builder, |
| int64_t alignment = kDefaultBufferAlignment) |
| : VarLengthListLikeBuilder(pool, value_builder, |
| std::make_shared<TYPE>(value_builder->type()), |
| alignment) {} |
|
|
| ~VarLengthListLikeBuilder() override = default; |
|
|
| Status Resize(int64_t capacity) override { |
| if (ARROW_PREDICT_FALSE(capacity > maximum_elements())) { |
| return Status::CapacityError(type_name(), |
| " array cannot reserve space for more than ", |
| maximum_elements(), " got ", capacity); |
| } |
| ARROW_RETURN_NOT_OK(CheckCapacity(capacity)); |
|
|
| |
| const int64_t offsets_capacity = |
| is_list_view(TYPE::type_id) ? capacity : capacity + 1; |
| ARROW_RETURN_NOT_OK(offsets_builder_.Resize(offsets_capacity)); |
| return ArrayBuilder::Resize(capacity); |
| } |
|
|
| void Reset() override { |
| ArrayBuilder::Reset(); |
| offsets_builder_.Reset(); |
| value_builder_->Reset(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Status Append(bool is_valid, int64_t list_length) { |
| ARROW_RETURN_NOT_OK(Reserve(1)); |
| assert(is_valid || list_length == 0); |
| UnsafeAppendToBitmap(is_valid); |
| UnsafeAppendDimensions(value_builder_->length(), list_length); |
| return Status::OK(); |
| } |
|
|
| Status AppendNull() final { |
| |
| |
| |
| |
| |
| |
| |
| |
| return Append(false, 0); |
| } |
|
|
| Status AppendNulls(int64_t length) final { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| UnsafeAppendToBitmap(length, false); |
| UnsafeAppendEmptyDimensions(length); |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| |
| Status AppendEmptyValue() final { return Append(true, 0); } |
|
|
| |
| |
| |
| |
| Status AppendEmptyValues(int64_t length) final { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| UnsafeAppendToBitmap(length, true); |
| UnsafeAppendEmptyDimensions(length); |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| virtual Status AppendValues(const offset_type* offsets, const offset_type* sizes, |
| int64_t length, const uint8_t* valid_bytes) = 0; |
|
|
| Status AppendArraySlice(const ArraySpan& array, int64_t offset, |
| int64_t length) override { |
| const offset_type* offsets = array.GetValues<offset_type>(1); |
| [[maybe_unused]] const offset_type* sizes = NULLPTR; |
| if constexpr (is_list_view(TYPE::type_id)) { |
| sizes = array.GetValues<offset_type>(2); |
| } |
| static_assert(internal::may_have_validity_bitmap(TYPE::type_id)); |
| const uint8_t* validity = array.MayHaveNulls() ? array.buffers[0].data : NULLPTR; |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| for (int64_t row = offset; row < offset + length; row++) { |
| const bool is_valid = !validity || bit_util::GetBit(validity, array.offset + row); |
| int64_t size = 0; |
| if (is_valid) { |
| if constexpr (is_list_view(TYPE::type_id)) { |
| size = sizes[row]; |
| } else { |
| size = offsets[row + 1] - offsets[row]; |
| } |
| } |
| UnsafeAppendToBitmap(is_valid); |
| UnsafeAppendDimensions(value_builder_->length(), size); |
| if (is_valid) { |
| ARROW_RETURN_NOT_OK( |
| value_builder_->AppendArraySlice(array.child_data[0], offsets[row], size)); |
| } |
| } |
| return Status::OK(); |
| } |
|
|
| Status ValidateOverflow(int64_t new_elements) const { |
| auto new_length = value_builder_->length() + new_elements; |
| if (ARROW_PREDICT_FALSE(new_length > maximum_elements())) { |
| return Status::CapacityError(type_name(), " array cannot contain more than ", |
| maximum_elements(), " elements, have ", new_elements); |
| } else { |
| return Status::OK(); |
| } |
| } |
|
|
| ArrayBuilder* value_builder() const { return value_builder_.get(); } |
|
|
| |
| static constexpr int64_t maximum_elements() { |
| return std::numeric_limits<offset_type>::max() - 1; |
| } |
|
|
| std::shared_ptr<DataType> type() const override { |
| return std::make_shared<TYPE>(value_field_->WithType(value_builder_->type())); |
| } |
|
|
| private: |
| static constexpr const char* type_name() { |
| if constexpr (is_list_view(TYPE::type_id)) { |
| return "ListView"; |
| } else { |
| return "List"; |
| } |
| } |
|
|
| protected: |
| |
| |
| |
| virtual void UnsafeAppendEmptyDimensions(int64_t num_values) { |
| const int64_t offset = value_builder_->length(); |
| for (int64_t i = 0; i < num_values; ++i) { |
| offsets_builder_.UnsafeAppend(static_cast<offset_type>(offset)); |
| } |
| } |
|
|
| |
| |
| |
| virtual void UnsafeAppendDimensions(int64_t offset, int64_t ARROW_ARG_UNUSED(size)) { |
| offsets_builder_.UnsafeAppend(static_cast<offset_type>(offset)); |
| } |
|
|
| TypedBufferBuilder<offset_type> offsets_builder_; |
| std::shared_ptr<ArrayBuilder> value_builder_; |
| std::shared_ptr<Field> value_field_; |
| }; |
|
|
| |
| |
|
|
| template <typename TYPE> |
| class BaseListBuilder : public VarLengthListLikeBuilder<TYPE> { |
| private: |
| using BASE = VarLengthListLikeBuilder<TYPE>; |
|
|
| public: |
| using TypeClass = TYPE; |
| using offset_type = typename BASE::offset_type; |
|
|
| using BASE::BASE; |
|
|
| using BASE::Append; |
|
|
| ~BaseListBuilder() override = default; |
|
|
| |
| |
| |
| |
| Status Append(bool is_valid = true) { |
| |
| |
| return BASE::Append(is_valid, 0); |
| } |
|
|
| |
| |
| |
| |
| Status AppendValues(const offset_type* offsets, int64_t length, |
| const uint8_t* valid_bytes = NULLPTR) { |
| ARROW_RETURN_NOT_OK(this->Reserve(length)); |
| this->UnsafeAppendToBitmap(valid_bytes, length); |
| this->offsets_builder_.UnsafeAppend(offsets, length); |
| return Status::OK(); |
| } |
|
|
| Status AppendValues(const offset_type* offsets, const offset_type* sizes, |
| int64_t length, const uint8_t* valid_bytes) final { |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifndef NDEBUG |
| if (sizes) { |
| for (int64_t i = 0; i < length - 1; ++i) { |
| if (ARROW_PREDICT_FALSE(offsets[i] != offsets[i + 1] - sizes[i])) { |
| if (!valid_bytes || valid_bytes[i]) { |
| return Status::Invalid( |
| "BaseListBuilder: sizes are inconsistent with offsets provided"); |
| } |
| } |
| } |
| } |
| #endif |
| return AppendValues(offsets, length, valid_bytes); |
| } |
|
|
| Status AppendValues(const offset_type* offsets, const offset_type* sizes, |
| int64_t length) { |
| return AppendValues(offsets, sizes, length, NULLPTR); |
| } |
|
|
| Status AppendNextOffset() { |
| ARROW_RETURN_NOT_OK(this->ValidateOverflow(0)); |
| const int64_t num_values = this->value_builder_->length(); |
| return this->offsets_builder_.Append(static_cast<offset_type>(num_values)); |
| } |
|
|
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override { |
| ARROW_RETURN_NOT_OK(AppendNextOffset()); |
|
|
| |
| std::shared_ptr<Buffer> offsets; |
| std::shared_ptr<Buffer> null_bitmap; |
| ARROW_RETURN_NOT_OK(this->offsets_builder_.Finish(&offsets)); |
| ARROW_RETURN_NOT_OK(this->null_bitmap_builder_.Finish(&null_bitmap)); |
|
|
| if (this->value_builder_->length() == 0) { |
| |
| ARROW_RETURN_NOT_OK(this->value_builder_->Resize(0)); |
| } |
|
|
| std::shared_ptr<ArrayData> items; |
| ARROW_RETURN_NOT_OK(this->value_builder_->FinishInternal(&items)); |
|
|
| *out = ArrayData::Make(this->type(), this->length_, |
| {std::move(null_bitmap), std::move(offsets)}, |
| {std::move(items)}, this->null_count_); |
| this->Reset(); |
| return Status::OK(); |
| } |
| }; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class ARROW_EXPORT ListBuilder : public BaseListBuilder<ListType> { |
| public: |
| using BaseListBuilder::BaseListBuilder; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<ListArray>* out) { return FinishTyped(out); } |
| }; |
|
|
| |
| |
| |
| |
| class ARROW_EXPORT LargeListBuilder : public BaseListBuilder<LargeListType> { |
| public: |
| using BaseListBuilder::BaseListBuilder; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<LargeListArray>* out) { return FinishTyped(out); } |
| }; |
|
|
| |
| |
|
|
| template <typename TYPE> |
| class BaseListViewBuilder : public VarLengthListLikeBuilder<TYPE> { |
| private: |
| using BASE = VarLengthListLikeBuilder<TYPE>; |
|
|
| public: |
| using TypeClass = TYPE; |
| using offset_type = typename BASE::offset_type; |
|
|
| using BASE::BASE; |
|
|
| ~BaseListViewBuilder() override = default; |
|
|
| Status Resize(int64_t capacity) override { |
| ARROW_RETURN_NOT_OK(BASE::Resize(capacity)); |
| return sizes_builder_.Resize(capacity); |
| } |
|
|
| void Reset() override { |
| BASE::Reset(); |
| sizes_builder_.Reset(); |
| } |
|
|
| |
| |
| |
| |
| Status AppendValues(const offset_type* offsets, const offset_type* sizes, |
| int64_t length, const uint8_t* valid_bytes) final { |
| ARROW_RETURN_NOT_OK(this->Reserve(length)); |
| this->UnsafeAppendToBitmap(valid_bytes, length); |
| this->offsets_builder_.UnsafeAppend(offsets, length); |
| this->sizes_builder_.UnsafeAppend(sizes, length); |
| return Status::OK(); |
| } |
|
|
| Status AppendValues(const offset_type* offsets, const offset_type* sizes, |
| int64_t length) { |
| return AppendValues(offsets, sizes, length, NULLPTR); |
| } |
|
|
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override { |
| |
| std::shared_ptr<Buffer> null_bitmap; |
| std::shared_ptr<Buffer> offsets; |
| std::shared_ptr<Buffer> sizes; |
| ARROW_RETURN_NOT_OK(this->null_bitmap_builder_.Finish(&null_bitmap)); |
| ARROW_RETURN_NOT_OK(this->offsets_builder_.Finish(&offsets)); |
| ARROW_RETURN_NOT_OK(this->sizes_builder_.Finish(&sizes)); |
|
|
| if (this->value_builder_->length() == 0) { |
| |
| ARROW_RETURN_NOT_OK(this->value_builder_->Resize(0)); |
| } |
|
|
| std::shared_ptr<ArrayData> items; |
| ARROW_RETURN_NOT_OK(this->value_builder_->FinishInternal(&items)); |
|
|
| *out = ArrayData::Make(this->type(), this->length_, |
| {std::move(null_bitmap), std::move(offsets), std::move(sizes)}, |
| {std::move(items)}, this->null_count_); |
| this->Reset(); |
| return Status::OK(); |
| } |
|
|
| protected: |
| void UnsafeAppendEmptyDimensions(int64_t num_values) override { |
| for (int64_t i = 0; i < num_values; ++i) { |
| this->offsets_builder_.UnsafeAppend(0); |
| } |
| for (int64_t i = 0; i < num_values; ++i) { |
| this->sizes_builder_.UnsafeAppend(0); |
| } |
| } |
|
|
| void UnsafeAppendDimensions(int64_t offset, int64_t size) override { |
| this->offsets_builder_.UnsafeAppend(static_cast<offset_type>(offset)); |
| this->sizes_builder_.UnsafeAppend(static_cast<offset_type>(size)); |
| } |
|
|
| private: |
| TypedBufferBuilder<offset_type> sizes_builder_; |
| }; |
|
|
| class ARROW_EXPORT ListViewBuilder final : public BaseListViewBuilder<ListViewType> { |
| public: |
| using BaseListViewBuilder::BaseListViewBuilder; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<ListViewArray>* out) { return FinishTyped(out); } |
| }; |
|
|
| class ARROW_EXPORT LargeListViewBuilder final |
| : public BaseListViewBuilder<LargeListViewType> { |
| public: |
| using BaseListViewBuilder::BaseListViewBuilder; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<LargeListViewArray>* out) { return FinishTyped(out); } |
| }; |
|
|
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| class ARROW_EXPORT MapBuilder : public ArrayBuilder { |
| public: |
| |
| |
| MapBuilder(MemoryPool* pool, const std::shared_ptr<ArrayBuilder>& key_builder, |
| const std::shared_ptr<ArrayBuilder>& item_builder, |
| const std::shared_ptr<DataType>& type); |
|
|
| |
| |
| MapBuilder(MemoryPool* pool, const std::shared_ptr<ArrayBuilder>& key_builder, |
| const std::shared_ptr<ArrayBuilder>& item_builder, bool keys_sorted = false); |
|
|
| MapBuilder(MemoryPool* pool, const std::shared_ptr<ArrayBuilder>& item_builder, |
| const std::shared_ptr<DataType>& type); |
|
|
| Status Resize(int64_t capacity) override; |
| void Reset() override; |
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<MapArray>* out) { return FinishTyped(out); } |
|
|
| |
| |
| |
| |
| Status AppendValues(const int32_t* offsets, int64_t length, |
| const uint8_t* valid_bytes = NULLPTR); |
|
|
| |
| |
| |
| |
| Status Append(); |
|
|
| Status AppendNull() final; |
|
|
| Status AppendNulls(int64_t length) final; |
|
|
| Status AppendEmptyValue() final; |
|
|
| Status AppendEmptyValues(int64_t length) final; |
|
|
| Status AppendArraySlice(const ArraySpan& array, int64_t offset, |
| int64_t length) override { |
| const auto* offsets = array.GetValues<int32_t>(1); |
| static_assert(internal::may_have_validity_bitmap(MapType::type_id)); |
| const uint8_t* validity = array.MayHaveNulls() ? array.buffers[0].data : NULLPTR; |
| for (int64_t row = offset; row < offset + length; row++) { |
| const bool is_valid = !validity || bit_util::GetBit(validity, array.offset + row); |
| if (is_valid) { |
| ARROW_RETURN_NOT_OK(Append()); |
| const int64_t slot_length = offsets[row + 1] - offsets[row]; |
| |
| int64_t key_value_offset = array.child_data[0].offset + offsets[row]; |
| ARROW_RETURN_NOT_OK(key_builder_->AppendArraySlice( |
| array.child_data[0].child_data[0], key_value_offset, slot_length)); |
| ARROW_RETURN_NOT_OK(item_builder_->AppendArraySlice( |
| array.child_data[0].child_data[1], key_value_offset, slot_length)); |
| } else { |
| ARROW_RETURN_NOT_OK(AppendNull()); |
| } |
| } |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| |
| ArrayBuilder* key_builder() const { return key_builder_.get(); } |
|
|
| |
| |
| |
| |
| ArrayBuilder* item_builder() const { return item_builder_.get(); } |
|
|
| |
| |
| |
| |
| ArrayBuilder* value_builder() const { return list_builder_->value_builder(); } |
|
|
| std::shared_ptr<DataType> type() const override { |
| |
| |
| return std::make_shared<MapType>( |
| field(entries_name_, |
| struct_({field(key_name_, key_builder_->type(), false), |
| field(item_name_, item_builder_->type(), item_nullable_)}), |
| false), |
| keys_sorted_); |
| } |
|
|
| Status ValidateOverflow(int64_t new_elements) { |
| return list_builder_->ValidateOverflow(new_elements); |
| } |
|
|
| protected: |
| inline Status AdjustStructBuilderLength(); |
|
|
| protected: |
| bool keys_sorted_ = false; |
| bool item_nullable_ = false; |
| std::string entries_name_; |
| std::string key_name_; |
| std::string item_name_; |
| std::shared_ptr<ListBuilder> list_builder_; |
| std::shared_ptr<ArrayBuilder> key_builder_; |
| std::shared_ptr<ArrayBuilder> item_builder_; |
| }; |
|
|
| |
| |
|
|
| |
| |
| class ARROW_EXPORT FixedSizeListBuilder : public ArrayBuilder { |
| public: |
| using TypeClass = FixedSizeListType; |
|
|
| |
| |
| FixedSizeListBuilder(MemoryPool* pool, |
| std::shared_ptr<ArrayBuilder> const& value_builder, |
| int32_t list_size); |
|
|
| |
| |
| FixedSizeListBuilder(MemoryPool* pool, |
| std::shared_ptr<ArrayBuilder> const& value_builder, |
| const std::shared_ptr<DataType>& type); |
|
|
| Status Resize(int64_t capacity) override; |
| void Reset() override; |
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<FixedSizeListArray>* out) { return FinishTyped(out); } |
|
|
| |
| |
| |
| |
| Status Append(); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| Status AppendValues(int64_t length, const uint8_t* valid_bytes = NULLPTR); |
|
|
| |
| |
| |
| |
| Status AppendNull() final; |
|
|
| |
| |
| |
| |
| Status AppendNulls(int64_t length) final; |
|
|
| Status ValidateOverflow(int64_t new_elements); |
|
|
| Status AppendEmptyValue() final; |
|
|
| Status AppendEmptyValues(int64_t length) final; |
|
|
| Status AppendArraySlice(const ArraySpan& array, int64_t offset, int64_t length) final { |
| const uint8_t* validity = array.MayHaveNulls() ? array.buffers[0].data : NULLPTR; |
| for (int64_t row = offset; row < offset + length; row++) { |
| if (!validity || bit_util::GetBit(validity, array.offset + row)) { |
| ARROW_RETURN_NOT_OK(value_builder_->AppendArraySlice( |
| array.child_data[0], list_size_ * (array.offset + row), list_size_)); |
| ARROW_RETURN_NOT_OK(Append()); |
| } else { |
| ARROW_RETURN_NOT_OK(AppendNull()); |
| } |
| } |
| return Status::OK(); |
| } |
|
|
| ArrayBuilder* value_builder() const { return value_builder_.get(); } |
|
|
| std::shared_ptr<DataType> type() const override { |
| return fixed_size_list(value_field_->WithType(value_builder_->type()), list_size_); |
| } |
|
|
| |
| static constexpr int64_t maximum_elements() { |
| return std::numeric_limits<FixedSizeListType::offset_type>::max() - 1; |
| } |
|
|
| protected: |
| std::shared_ptr<Field> value_field_; |
| const int32_t list_size_; |
| std::shared_ptr<ArrayBuilder> value_builder_; |
| }; |
|
|
| |
| |
|
|
| |
| |
| |
| |
| |
| class ARROW_EXPORT StructBuilder : public ArrayBuilder { |
| public: |
| |
| StructBuilder(const std::shared_ptr<DataType>& type, MemoryPool* pool, |
| std::vector<std::shared_ptr<ArrayBuilder>> field_builders); |
|
|
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<StructArray>* out) { return FinishTyped(out); } |
|
|
| |
| |
| |
| |
| Status AppendValues(int64_t length, const uint8_t* valid_bytes) { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| UnsafeAppendToBitmap(valid_bytes, length); |
| return Status::OK(); |
| } |
|
|
| |
| |
| Status Append(bool is_valid = true) { |
| ARROW_RETURN_NOT_OK(Reserve(1)); |
| UnsafeAppendToBitmap(is_valid); |
| return Status::OK(); |
| } |
|
|
| |
| |
| Status AppendNull() final { |
| for (const auto& field : children_) { |
| ARROW_RETURN_NOT_OK(field->AppendEmptyValue()); |
| } |
| return Append(false); |
| } |
|
|
| |
| |
| Status AppendNulls(int64_t length) final { |
| for (const auto& field : children_) { |
| ARROW_RETURN_NOT_OK(field->AppendEmptyValues(length)); |
| } |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| UnsafeAppendToBitmap(length, false); |
| return Status::OK(); |
| } |
|
|
| Status AppendEmptyValue() final { |
| for (const auto& field : children_) { |
| ARROW_RETURN_NOT_OK(field->AppendEmptyValue()); |
| } |
| return Append(true); |
| } |
|
|
| Status AppendEmptyValues(int64_t length) final { |
| for (const auto& field : children_) { |
| ARROW_RETURN_NOT_OK(field->AppendEmptyValues(length)); |
| } |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| UnsafeAppendToBitmap(length, true); |
| return Status::OK(); |
| } |
|
|
| Status AppendArraySlice(const ArraySpan& array, int64_t offset, |
| int64_t length) override { |
| for (int i = 0; static_cast<size_t>(i) < children_.size(); i++) { |
| ARROW_RETURN_NOT_OK(children_[i]->AppendArraySlice(array.child_data[i], |
| array.offset + offset, length)); |
| } |
| const uint8_t* validity = array.MayHaveNulls() ? array.buffers[0].data : NULLPTR; |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| UnsafeAppendToBitmap(validity, array.offset + offset, length); |
| return Status::OK(); |
| } |
|
|
| void Reset() override; |
|
|
| ArrayBuilder* field_builder(int i) const { return children_[i].get(); } |
|
|
| int num_fields() const { return static_cast<int>(children_.size()); } |
|
|
| std::shared_ptr<DataType> type() const override; |
|
|
| private: |
| std::shared_ptr<DataType> type_; |
| }; |
|
|
| |
|
|
| } |
|
|