| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #pragma once |
|
|
| #include <cstdint> |
| #include <cstring> |
| #include <memory> |
| #include <type_traits> |
|
|
| #include "arrow/array/builder_base.h" |
| #include "arrow/buffer.h" |
| #include "arrow/status.h" |
| #include "arrow/type.h" |
| #include "arrow/util/macros.h" |
| #include "arrow/util/visibility.h" |
|
|
| namespace arrow { |
|
|
| |
| |
| |
|
|
| namespace internal { |
|
|
| class ARROW_EXPORT AdaptiveIntBuilderBase : public ArrayBuilder { |
| public: |
| AdaptiveIntBuilderBase(uint8_t start_int_size, MemoryPool* pool, |
| int64_t alignment = kDefaultBufferAlignment); |
|
|
| explicit AdaptiveIntBuilderBase(MemoryPool* pool, |
| int64_t alignment = kDefaultBufferAlignment) |
| : AdaptiveIntBuilderBase(sizeof(uint8_t), pool, alignment) {} |
|
|
| |
| |
| Status AppendNulls(int64_t length) final { |
| ARROW_RETURN_NOT_OK(CommitPendingData()); |
| if (ARROW_PREDICT_TRUE(length > 0)) { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| memset(data_->mutable_data() + length_ * int_size_, 0, int_size_ * length); |
| UnsafeSetNull(length); |
| } |
| return Status::OK(); |
| } |
|
|
| Status AppendNull() final { |
| pending_data_[pending_pos_] = 0; |
| pending_valid_[pending_pos_] = 0; |
| pending_has_nulls_ = true; |
| ++pending_pos_; |
| ++length_; |
| ++null_count_; |
|
|
| if (ARROW_PREDICT_FALSE(pending_pos_ >= pending_size_)) { |
| return CommitPendingData(); |
| } |
| return Status::OK(); |
| } |
|
|
| Status AppendEmptyValues(int64_t length) final { |
| ARROW_RETURN_NOT_OK(CommitPendingData()); |
| if (ARROW_PREDICT_TRUE(length > 0)) { |
| ARROW_RETURN_NOT_OK(Reserve(length)); |
| memset(data_->mutable_data() + length_ * int_size_, 0, int_size_ * length); |
| UnsafeSetNotNull(length); |
| } |
| return Status::OK(); |
| } |
|
|
| Status AppendEmptyValue() final { |
| pending_data_[pending_pos_] = 0; |
| pending_valid_[pending_pos_] = 1; |
| ++pending_pos_; |
| ++length_; |
|
|
| if (ARROW_PREDICT_FALSE(pending_pos_ >= pending_size_)) { |
| return CommitPendingData(); |
| } |
| return Status::OK(); |
| } |
|
|
| void Reset() override; |
| Status Resize(int64_t capacity) override; |
|
|
| protected: |
| Status AppendInternal(const uint64_t val) { |
| pending_data_[pending_pos_] = val; |
| pending_valid_[pending_pos_] = 1; |
| ++pending_pos_; |
| ++length_; |
|
|
| if (ARROW_PREDICT_FALSE(pending_pos_ >= pending_size_)) { |
| return CommitPendingData(); |
| } |
| return Status::OK(); |
| } |
|
|
| virtual Status CommitPendingData() = 0; |
|
|
| template <typename new_type, typename old_type> |
| typename std::enable_if<sizeof(old_type) >= sizeof(new_type), Status>::type |
| ExpandIntSizeInternal(); |
| template <typename new_type, typename old_type> |
| typename std::enable_if<(sizeof(old_type) < sizeof(new_type)), Status>::type |
| ExpandIntSizeInternal(); |
|
|
| std::shared_ptr<ResizableBuffer> data_; |
| uint8_t* raw_data_ = NULLPTR; |
|
|
| const uint8_t start_int_size_; |
| uint8_t int_size_; |
|
|
| static constexpr int32_t pending_size_ = 1024; |
| uint8_t pending_valid_[pending_size_]; |
| uint64_t pending_data_[pending_size_]; |
| int32_t pending_pos_ = 0; |
| bool pending_has_nulls_ = false; |
| }; |
|
|
| } |
|
|
| class ARROW_EXPORT AdaptiveUIntBuilder : public internal::AdaptiveIntBuilderBase { |
| public: |
| explicit AdaptiveUIntBuilder(uint8_t start_int_size, |
| MemoryPool* pool = default_memory_pool()); |
|
|
| explicit AdaptiveUIntBuilder(MemoryPool* pool = default_memory_pool()) |
| : AdaptiveUIntBuilder(sizeof(uint8_t), pool) {} |
|
|
| using internal::AdaptiveIntBuilderBase::Reset; |
|
|
| |
| Status Append(const uint64_t val) { return AppendInternal(val); } |
|
|
| |
| |
| |
| |
| |
| |
| Status AppendValues(const uint64_t* values, int64_t length, |
| const uint8_t* valid_bytes = NULLPTR); |
|
|
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
|
|
| std::shared_ptr<DataType> type() const override; |
|
|
| protected: |
| Status CommitPendingData() override; |
| Status ExpandIntSize(uint8_t new_int_size); |
|
|
| Status AppendValuesInternal(const uint64_t* values, int64_t length, |
| const uint8_t* valid_bytes); |
|
|
| template <typename new_type> |
| Status ExpandIntSizeN(); |
| }; |
|
|
| class ARROW_EXPORT AdaptiveIntBuilder : public internal::AdaptiveIntBuilderBase { |
| public: |
| explicit AdaptiveIntBuilder(uint8_t start_int_size, |
| MemoryPool* pool = default_memory_pool(), |
| int64_t alignment = kDefaultBufferAlignment); |
|
|
| explicit AdaptiveIntBuilder(MemoryPool* pool = default_memory_pool(), |
| int64_t alignment = kDefaultBufferAlignment) |
| : AdaptiveIntBuilder(sizeof(uint8_t), pool, alignment) {} |
|
|
| using internal::AdaptiveIntBuilderBase::Reset; |
|
|
| |
| Status Append(const int64_t val) { return AppendInternal(static_cast<uint64_t>(val)); } |
|
|
| |
| |
| |
| |
| |
| |
| Status AppendValues(const int64_t* values, int64_t length, |
| const uint8_t* valid_bytes = NULLPTR); |
|
|
| Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
|
|
| std::shared_ptr<DataType> type() const override; |
|
|
| protected: |
| Status CommitPendingData() override; |
| Status ExpandIntSize(uint8_t new_int_size); |
|
|
| Status AppendValuesInternal(const int64_t* values, int64_t length, |
| const uint8_t* valid_bytes); |
|
|
| template <typename new_type> |
| Status ExpandIntSizeN(); |
| }; |
|
|
| |
|
|
| } |
|
|