| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #pragma once |
|
|
| #include <cstdint> |
| #include <memory> |
| #include <string> |
| #include <vector> |
|
|
| #include "arrow/array/array_nested.h" |
| #include "arrow/array/builder_base.h" |
| #include "arrow/array/data.h" |
| #include "arrow/buffer_builder.h" |
| #include "arrow/memory_pool.h" |
| #include "arrow/status.h" |
| #include "arrow/type.h" |
| #include "arrow/util/visibility.h" |
|
|
| namespace arrow { |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| class ARROW_EXPORT BasicUnionBuilder : public ArrayBuilder { |
| public: |
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<UnionArray>* out) { return FinishTyped(out); } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| int8_t AppendChild(const std::shared_ptr<ArrayBuilder>& new_child, |
| const std::string& field_name = ""); |
|
|
| std::shared_ptr<DataType> type() const override; |
|
|
| int64_t length() const override { return types_builder_.length(); } |
|
|
| protected: |
| BasicUnionBuilder(MemoryPool* pool, int64_t alignment, |
| const std::vector<std::shared_ptr<ArrayBuilder>>& children, |
| const std::shared_ptr<DataType>& type); |
|
|
| int8_t NextTypeId(); |
|
|
| std::vector<std::shared_ptr<Field>> child_fields_; |
| std::vector<int8_t> type_codes_; |
| UnionMode::type mode_; |
|
|
| std::vector<ArrayBuilder*> type_id_to_children_; |
| std::vector<int> type_id_to_child_id_; |
| |
| int8_t dense_type_id_ = 0; |
| TypedBufferBuilder<int8_t> types_builder_; |
| }; |
|
|
| |
| |
| |
| class ARROW_EXPORT DenseUnionBuilder : public BasicUnionBuilder { |
| public: |
| |
| |
| |
| explicit DenseUnionBuilder(MemoryPool* pool, |
| int64_t alignment = kDefaultBufferAlignment) |
| : BasicUnionBuilder(pool, alignment, {}, dense_union(FieldVector{})), |
| offsets_builder_(pool, alignment) {} |
|
|
| |
| |
| DenseUnionBuilder(MemoryPool* pool, |
| const std::vector<std::shared_ptr<ArrayBuilder>>& children, |
| const std::shared_ptr<DataType>& type, |
| int64_t alignment = kDefaultBufferAlignment) |
| : BasicUnionBuilder(pool, alignment, children, type), |
| offsets_builder_(pool, alignment) {} |
|
|
| Status AppendNull() final { |
| const int8_t first_child_code = type_codes_[0]; |
| ArrayBuilder* child_builder = type_id_to_children_[first_child_code]; |
| ARROW_RETURN_NOT_OK(types_builder_.Append(first_child_code)); |
| ARROW_RETURN_NOT_OK( |
| offsets_builder_.Append(static_cast<int32_t>(child_builder->length()))); |
| |
| return child_builder->AppendNull(); |
| } |
|
|
| Status AppendNulls(int64_t length) final { |
| const int8_t first_child_code = type_codes_[0]; |
| ArrayBuilder* child_builder = type_id_to_children_[first_child_code]; |
| ARROW_RETURN_NOT_OK(types_builder_.Append(length, first_child_code)); |
| ARROW_RETURN_NOT_OK( |
| offsets_builder_.Append(length, static_cast<int32_t>(child_builder->length()))); |
| |
| return child_builder->AppendNull(); |
| } |
|
|
| Status AppendEmptyValue() final { |
| const int8_t first_child_code = type_codes_[0]; |
| ArrayBuilder* child_builder = type_id_to_children_[first_child_code]; |
| ARROW_RETURN_NOT_OK(types_builder_.Append(first_child_code)); |
| ARROW_RETURN_NOT_OK( |
| offsets_builder_.Append(static_cast<int32_t>(child_builder->length()))); |
| |
| return child_builder->AppendEmptyValue(); |
| } |
|
|
| Status AppendEmptyValues(int64_t length) final { |
| const int8_t first_child_code = type_codes_[0]; |
| ArrayBuilder* child_builder = type_id_to_children_[first_child_code]; |
| ARROW_RETURN_NOT_OK(types_builder_.Append(length, first_child_code)); |
| ARROW_RETURN_NOT_OK( |
| offsets_builder_.Append(length, static_cast<int32_t>(child_builder->length()))); |
| |
| return child_builder->AppendEmptyValue(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| Status Append(int8_t next_type) { |
| ARROW_RETURN_NOT_OK(types_builder_.Append(next_type)); |
| if (type_id_to_children_[next_type]->length() == kListMaximumElements) { |
| return Status::CapacityError( |
| "a dense UnionArray cannot contain more than 2^31 - 1 elements from a single " |
| "child"); |
| } |
| auto offset = static_cast<int32_t>(type_id_to_children_[next_type]->length()); |
| return offsets_builder_.Append(offset); |
| } |
|
|
| Status AppendArraySlice(const ArraySpan& array, int64_t offset, |
| int64_t length) override; |
|
|
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
|
|
| private: |
| TypedBufferBuilder<int32_t> offsets_builder_; |
| }; |
|
|
| |
| |
| |
| class ARROW_EXPORT SparseUnionBuilder : public BasicUnionBuilder { |
| public: |
| |
| |
| |
| explicit SparseUnionBuilder(MemoryPool* pool, |
| int64_t alignment = kDefaultBufferAlignment) |
| : BasicUnionBuilder(pool, alignment, {}, sparse_union(FieldVector{})) {} |
|
|
| |
| |
| SparseUnionBuilder(MemoryPool* pool, |
| const std::vector<std::shared_ptr<ArrayBuilder>>& children, |
| const std::shared_ptr<DataType>& type, |
| int64_t alignment = kDefaultBufferAlignment) |
| : BasicUnionBuilder(pool, alignment, children, type) {} |
|
|
| |
| |
| |
| Status AppendNull() final { |
| const auto first_child_code = type_codes_[0]; |
| ARROW_RETURN_NOT_OK(types_builder_.Append(first_child_code)); |
| ARROW_RETURN_NOT_OK(type_id_to_children_[first_child_code]->AppendNull()); |
| for (int i = 1; i < static_cast<int>(type_codes_.size()); ++i) { |
| ARROW_RETURN_NOT_OK(type_id_to_children_[type_codes_[i]]->AppendEmptyValue()); |
| } |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| Status AppendNulls(int64_t length) final { |
| const auto first_child_code = type_codes_[0]; |
| ARROW_RETURN_NOT_OK(types_builder_.Append(length, first_child_code)); |
| ARROW_RETURN_NOT_OK(type_id_to_children_[first_child_code]->AppendNulls(length)); |
| for (int i = 1; i < static_cast<int>(type_codes_.size()); ++i) { |
| ARROW_RETURN_NOT_OK( |
| type_id_to_children_[type_codes_[i]]->AppendEmptyValues(length)); |
| } |
| return Status::OK(); |
| } |
|
|
| Status AppendEmptyValue() final { |
| ARROW_RETURN_NOT_OK(types_builder_.Append(type_codes_[0])); |
| for (int8_t code : type_codes_) { |
| ARROW_RETURN_NOT_OK(type_id_to_children_[code]->AppendEmptyValue()); |
| } |
| return Status::OK(); |
| } |
|
|
| Status AppendEmptyValues(int64_t length) final { |
| ARROW_RETURN_NOT_OK(types_builder_.Append(length, type_codes_[0])); |
| for (int8_t code : type_codes_) { |
| ARROW_RETURN_NOT_OK(type_id_to_children_[code]->AppendEmptyValues(length)); |
| } |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| Status Append(int8_t next_type) { return types_builder_.Append(next_type); } |
|
|
| Status AppendArraySlice(const ArraySpan& array, int64_t offset, |
| int64_t length) override; |
| }; |
|
|
| |
|
|
| } |
|
|