| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #pragma once |
|
|
| #include <algorithm> |
| #include <memory> |
| #include <vector> |
|
|
| #include "arrow/array/builder_base.h" |
| #include "arrow/array/data.h" |
| #include "arrow/result.h" |
| #include "arrow/type.h" |
| #include "arrow/type_traits.h" |
|
|
| namespace arrow { |
|
|
| class ARROW_EXPORT NullBuilder : public ArrayBuilder { |
| public: |
| explicit NullBuilder(MemoryPool* pool = default_memory_pool(), |
| int64_t ARROW_ARG_UNUSED(alignment) = kDefaultBufferAlignment) |
| : ArrayBuilder(pool) {} |
|
|
| explicit NullBuilder(const std::shared_ptr<DataType>& ARROW_ARG_UNUSED(type), |
| MemoryPool* pool = default_memory_pool(), |
| int64_t alignment = kDefaultBufferAlignment) |
| : NullBuilder(pool, alignment) {} |
|
|
| |
| Status AppendNulls(int64_t length) final { |
| if (length < 0) return Status::Invalid("length must be positive"); |
| null_count_ += length; |
| length_ += length; |
| return Status::OK(); |
| } |
|
|
| |
| Status AppendNull() final { return AppendNulls(1); } |
|
|
| Status AppendEmptyValues(int64_t length) final { return AppendNulls(length); } |
|
|
| Status AppendEmptyValue() final { return AppendEmptyValues(1); } |
|
|
| Status Append(std::nullptr_t) { return AppendNull(); } |
|
|
| Status AppendArraySlice(const ArraySpan&, int64_t, int64_t length) override { |
| return AppendNulls(length); |
| } |
|
|
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| std::shared_ptr<DataType> type() const override { return null(); } |
|
|
| Status Finish(std::shared_ptr<NullArray>* out) { return FinishTyped(out); } |
| }; |
|
|
| |
| |
| |
|
|
| |
| template <typename T> |
| class NumericBuilder |
| : public ArrayBuilder, |
| public internal::ArrayBuilderExtraOps<NumericBuilder<T>, typename T::c_type> { |
| public: |
| using TypeClass = T; |
| using value_type = typename T::c_type; |
| using ArrayType = typename TypeTraits<T>::ArrayType; |
|
|
| template <typename T1 = T> |
| explicit NumericBuilder( |
| enable_if_parameter_free<T1, MemoryPool*> pool = default_memory_pool(), |
| int64_t alignment = kDefaultBufferAlignment) |
| : ArrayBuilder(pool, alignment), |
| type_(TypeTraits<T>::type_singleton()), |
| data_builder_(pool, alignment) {} |
|
|
| NumericBuilder(const std::shared_ptr<DataType>& type, MemoryPool* pool, |
| int64_t alignment = kDefaultBufferAlignment) |
| : ArrayBuilder(pool, alignment), type_(type), data_builder_(pool, alignment) {} |
|
|
| |
| Status Append(const value_type val) { |
| ARROW_RETURN_NOT_OK(ArrayBuilder::Reserve(1)); |
| UnsafeAppend(val); |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| Status AppendNulls(int64_t length) final { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(length, value_type{}); |
| UnsafeSetNull(length); |
| return Status::OK(); |
| } |
|
|
| |
| Status AppendNull() final { |
| ARROW_RETURN_NOT_OK(Reserve(1)); |
| data_builder_.UnsafeAppend(value_type{}); |
| UnsafeAppendToBitmap(false); |
| return Status::OK(); |
| } |
|
|
| |
| Status AppendEmptyValue() final { |
| ARROW_RETURN_NOT_OK(Reserve(1)); |
| data_builder_.UnsafeAppend(value_type{}); |
| UnsafeAppendToBitmap(true); |
| return Status::OK(); |
| } |
|
|
| |
| Status AppendEmptyValues(int64_t length) final { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(length, value_type{}); |
| UnsafeSetNotNull(length); |
| return Status::OK(); |
| } |
|
|
| value_type GetValue(int64_t index) const { return data_builder_.data()[index]; } |
|
|
| void Reset() override { |
| data_builder_.Reset(); |
| ArrayBuilder::Reset(); |
| } |
|
|
| Status Resize(int64_t capacity) override { |
| ARROW_RETURN_NOT_OK(CheckCapacity(capacity)); |
| capacity = std::max(capacity, kMinBuilderCapacity); |
| ARROW_RETURN_NOT_OK(data_builder_.Resize(capacity)); |
| return ArrayBuilder::Resize(capacity); |
| } |
|
|
| value_type operator[](int64_t index) const { return GetValue(index); } |
|
|
| value_type& operator[](int64_t index) { |
| return reinterpret_cast<value_type*>(data_builder_.mutable_data())[index]; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| Status AppendValues(const value_type* values, int64_t length, |
| const uint8_t* valid_bytes = NULLPTR) { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(values, length); |
| |
| ArrayBuilder::UnsafeAppendToBitmap(valid_bytes, length); |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| Status AppendValues(const value_type* values, int64_t length, const uint8_t* bitmap, |
| int64_t bitmap_offset) { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(values, length); |
| |
| ArrayBuilder::UnsafeAppendToBitmap(bitmap, bitmap_offset, length); |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| Status AppendValues(const value_type* values, int64_t length, |
| const std::vector<bool>& is_valid) { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(values, length); |
| |
| ArrayBuilder::UnsafeAppendToBitmap(is_valid); |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| |
| |
| Status AppendValues(const std::vector<value_type>& values, |
| const std::vector<bool>& is_valid) { |
| if (values.empty()) { |
| return Status::OK(); |
| } |
| return AppendValues(values.data(), static_cast<int64_t>(values.size()), is_valid); |
| } |
|
|
| |
| |
| |
| Status AppendValues(const std::vector<value_type>& values) { |
| if (values.empty()) { |
| return Status::OK(); |
| } |
| return AppendValues(values.data(), static_cast<int64_t>(values.size())); |
| } |
|
|
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override { |
| ARROW_ASSIGN_OR_RAISE(auto null_bitmap, |
| null_bitmap_builder_.FinishWithLength(length_)); |
| ARROW_ASSIGN_OR_RAISE(auto data, data_builder_.FinishWithLength(length_)); |
| *out = ArrayData::Make(type(), length_, {null_bitmap, data}, null_count_); |
| capacity_ = length_ = null_count_ = 0; |
| return Status::OK(); |
| } |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<ArrayType>* out) { return FinishTyped(out); } |
|
|
| |
| |
| |
| |
| template <typename ValuesIter> |
| Status AppendValues(ValuesIter values_begin, ValuesIter values_end) { |
| int64_t length = static_cast<int64_t>(std::distance(values_begin, values_end)); |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(values_begin, values_end); |
| |
| UnsafeSetNotNull(length); |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| template <typename ValuesIter, typename ValidIter> |
| enable_if_t<!std::is_pointer<ValidIter>::value, Status> AppendValues( |
| ValuesIter values_begin, ValuesIter values_end, ValidIter valid_begin) { |
| static_assert(!internal::is_null_pointer<ValidIter>::value, |
| "Don't pass a NULLPTR directly as valid_begin, use the 2-argument " |
| "version instead"); |
| int64_t length = static_cast<int64_t>(std::distance(values_begin, values_end)); |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(values_begin, values_end); |
| null_bitmap_builder_.UnsafeAppend<true>( |
| length, [&valid_begin]() -> bool { return *valid_begin++; }); |
| length_ = null_bitmap_builder_.length(); |
| null_count_ = null_bitmap_builder_.false_count(); |
| return Status::OK(); |
| } |
|
|
| |
| template <typename ValuesIter, typename ValidIter> |
| enable_if_t<std::is_pointer<ValidIter>::value, Status> AppendValues( |
| ValuesIter values_begin, ValuesIter values_end, ValidIter valid_begin) { |
| int64_t length = static_cast<int64_t>(std::distance(values_begin, values_end)); |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(values_begin, values_end); |
| |
| if (valid_begin == NULLPTR) { |
| UnsafeSetNotNull(length); |
| } else { |
| null_bitmap_builder_.UnsafeAppend<true>( |
| length, [&valid_begin]() -> bool { return *valid_begin++; }); |
| length_ = null_bitmap_builder_.length(); |
| null_count_ = null_bitmap_builder_.false_count(); |
| } |
|
|
| return Status::OK(); |
| } |
|
|
| Status AppendArraySlice(const ArraySpan& array, int64_t offset, |
| int64_t length) override { |
| return AppendValues(array.GetValues<value_type>(1) + offset, length, |
| array.GetValues<uint8_t>(0, 0), array.offset + offset); |
| } |
|
|
| |
| |
| |
| |
| |
| void UnsafeAppend(const value_type val) { |
| ArrayBuilder::UnsafeAppendToBitmap(true); |
| data_builder_.UnsafeAppend(val); |
| } |
|
|
| void UnsafeAppendNull() { |
| ArrayBuilder::UnsafeAppendToBitmap(false); |
| data_builder_.UnsafeAppend(value_type{}); |
| } |
|
|
| std::shared_ptr<DataType> type() const override { return type_; } |
|
|
| protected: |
| std::shared_ptr<DataType> type_; |
| TypedBufferBuilder<value_type> data_builder_; |
| }; |
|
|
| |
|
|
| using UInt8Builder = NumericBuilder<UInt8Type>; |
| using UInt16Builder = NumericBuilder<UInt16Type>; |
| using UInt32Builder = NumericBuilder<UInt32Type>; |
| using UInt64Builder = NumericBuilder<UInt64Type>; |
|
|
| using Int8Builder = NumericBuilder<Int8Type>; |
| using Int16Builder = NumericBuilder<Int16Type>; |
| using Int32Builder = NumericBuilder<Int32Type>; |
| using Int64Builder = NumericBuilder<Int64Type>; |
|
|
| using HalfFloatBuilder = NumericBuilder<HalfFloatType>; |
| using FloatBuilder = NumericBuilder<FloatType>; |
| using DoubleBuilder = NumericBuilder<DoubleType>; |
|
|
| |
|
|
| |
| |
| |
|
|
| using Date32Builder = NumericBuilder<Date32Type>; |
| using Date64Builder = NumericBuilder<Date64Type>; |
| using Time32Builder = NumericBuilder<Time32Type>; |
| using Time64Builder = NumericBuilder<Time64Type>; |
| using TimestampBuilder = NumericBuilder<TimestampType>; |
| using MonthIntervalBuilder = NumericBuilder<MonthIntervalType>; |
| using DurationBuilder = NumericBuilder<DurationType>; |
|
|
| |
|
|
| class ARROW_EXPORT BooleanBuilder |
| : public ArrayBuilder, |
| public internal::ArrayBuilderExtraOps<BooleanBuilder, bool> { |
| public: |
| using TypeClass = BooleanType; |
| using value_type = bool; |
|
|
| explicit BooleanBuilder(MemoryPool* pool = default_memory_pool(), |
| int64_t alignment = kDefaultBufferAlignment); |
|
|
| BooleanBuilder(const std::shared_ptr<DataType>& type, |
| MemoryPool* pool = default_memory_pool(), |
| int64_t alignment = kDefaultBufferAlignment); |
|
|
| |
| Status AppendNulls(int64_t length) final { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(length, false); |
| UnsafeSetNull(length); |
| return Status::OK(); |
| } |
|
|
| Status AppendNull() final { |
| ARROW_RETURN_NOT_OK(Reserve(1)); |
| UnsafeAppendNull(); |
| return Status::OK(); |
| } |
|
|
| Status AppendEmptyValue() final { |
| ARROW_RETURN_NOT_OK(Reserve(1)); |
| data_builder_.UnsafeAppend(false); |
| UnsafeSetNotNull(1); |
| return Status::OK(); |
| } |
|
|
| Status AppendEmptyValues(int64_t length) final { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend(length, false); |
| UnsafeSetNotNull(length); |
| return Status::OK(); |
| } |
|
|
| |
| Status Append(const bool val) { |
| ARROW_RETURN_NOT_OK(Reserve(1)); |
| UnsafeAppend(val); |
| return Status::OK(); |
| } |
|
|
| Status Append(const uint8_t val) { return Append(val != 0); } |
|
|
| |
| void UnsafeAppend(const bool val) { |
| data_builder_.UnsafeAppend(val); |
| UnsafeAppendToBitmap(true); |
| } |
|
|
| void UnsafeAppendNull() { |
| data_builder_.UnsafeAppend(false); |
| UnsafeAppendToBitmap(false); |
| } |
|
|
| void UnsafeAppend(const uint8_t val) { UnsafeAppend(val != 0); } |
|
|
| |
| |
| |
| |
| |
| |
| Status AppendValues(const uint8_t* values, int64_t length, |
| const uint8_t* valid_bytes = NULLPTR); |
|
|
| |
| |
| |
| |
| |
| |
| Status AppendValues(const uint8_t* values, int64_t length, const uint8_t* validity, |
| int64_t offset); |
|
|
| |
| |
| |
| |
| |
| |
| Status AppendValues(const uint8_t* values, int64_t length, |
| const std::vector<bool>& is_valid); |
|
|
| |
| |
| |
| |
| |
| Status AppendValues(const std::vector<uint8_t>& values, |
| const std::vector<bool>& is_valid); |
|
|
| |
| |
| |
| Status AppendValues(const std::vector<uint8_t>& values); |
|
|
| |
| |
| |
| |
| |
| Status AppendValues(const std::vector<bool>& values, const std::vector<bool>& is_valid); |
|
|
| |
| |
| |
| Status AppendValues(const std::vector<bool>& values); |
|
|
| |
| |
| |
| |
| |
| template <typename ValuesIter> |
| Status AppendValues(ValuesIter values_begin, ValuesIter values_end) { |
| int64_t length = static_cast<int64_t>(std::distance(values_begin, values_end)); |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend<false>( |
| length, [&values_begin]() -> bool { return *values_begin++; }); |
| |
| UnsafeSetNotNull(length); |
| return Status::OK(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| template <typename ValuesIter, typename ValidIter> |
| enable_if_t<!std::is_pointer<ValidIter>::value, Status> AppendValues( |
| ValuesIter values_begin, ValuesIter values_end, ValidIter valid_begin) { |
| static_assert(!internal::is_null_pointer<ValidIter>::value, |
| "Don't pass a NULLPTR directly as valid_begin, use the 2-argument " |
| "version instead"); |
| int64_t length = static_cast<int64_t>(std::distance(values_begin, values_end)); |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
|
|
| data_builder_.UnsafeAppend<false>( |
| length, [&values_begin]() -> bool { return *values_begin++; }); |
| null_bitmap_builder_.UnsafeAppend<true>( |
| length, [&valid_begin]() -> bool { return *valid_begin++; }); |
| length_ = null_bitmap_builder_.length(); |
| null_count_ = null_bitmap_builder_.false_count(); |
| return Status::OK(); |
| } |
|
|
| |
| template <typename ValuesIter, typename ValidIter> |
| enable_if_t<std::is_pointer<ValidIter>::value, Status> AppendValues( |
| ValuesIter values_begin, ValuesIter values_end, ValidIter valid_begin) { |
| int64_t length = static_cast<int64_t>(std::distance(values_begin, values_end)); |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| data_builder_.UnsafeAppend<false>( |
| length, [&values_begin]() -> bool { return *values_begin++; }); |
|
|
| if (valid_begin == NULLPTR) { |
| UnsafeSetNotNull(length); |
| } else { |
| null_bitmap_builder_.UnsafeAppend<true>( |
| length, [&valid_begin]() -> bool { return *valid_begin++; }); |
| } |
| length_ = null_bitmap_builder_.length(); |
| null_count_ = null_bitmap_builder_.false_count(); |
| return Status::OK(); |
| } |
|
|
| Status AppendValues(int64_t length, bool value); |
|
|
| Status AppendArraySlice(const ArraySpan& array, int64_t offset, |
| int64_t length) override { |
| return AppendValues(array.GetValues<uint8_t>(1, 0), length, |
| array.GetValues<uint8_t>(0, 0), array.offset + offset); |
| } |
|
|
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
|
|
| |
| using ArrayBuilder::Finish; |
| |
|
|
| Status Finish(std::shared_ptr<BooleanArray>* out) { return FinishTyped(out); } |
|
|
| void Reset() override; |
| Status Resize(int64_t capacity) override; |
|
|
| std::shared_ptr<DataType> type() const override { return boolean(); } |
|
|
| protected: |
| TypedBufferBuilder<bool> data_builder_; |
| }; |
|
|
| } |
|
|