1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file |
3 | // distributed with this work for additional information |
4 | // regarding copyright ownership. The ASF licenses this file |
5 | // to you under the Apache License, Version 2.0 (the |
6 | // "License"); you may not use this file except in compliance |
7 | // with the License. You may obtain a copy of the License at |
8 | // |
9 | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | // |
11 | // Unless required by applicable law or agreed to in writing, |
12 | // software distributed under the License is distributed on an |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | // KIND, either express or implied. See the License for the |
15 | // specific language governing permissions and limitations |
16 | // under the License. |
17 | |
18 | #pragma once |
19 | |
20 | #include <memory> |
21 | #include <vector> |
22 | |
23 | #include "arrow/array/builder_base.h" |
24 | #include "arrow/buffer-builder.h" |
25 | |
26 | namespace arrow { |
27 | |
28 | // ---------------------------------------------------------------------- |
29 | // List builder |
30 | |
31 | /// \class ListBuilder |
32 | /// \brief Builder class for variable-length list array value types |
33 | /// |
34 | /// To use this class, you must append values to the child array builder and use |
35 | /// the Append function to delimit each distinct list value (once the values |
36 | /// have been appended to the child array) or use the bulk API to append |
37 | /// a sequence of offests and null values. |
38 | /// |
39 | /// A note on types. Per arrow/type.h all types in the c++ implementation are |
40 | /// logical so even though this class always builds list array, this can |
41 | /// represent multiple different logical types. If no logical type is provided |
42 | /// at construction time, the class defaults to List<T> where t is taken from the |
43 | /// value_builder/values that the object is constructed with. |
44 | class ARROW_EXPORT ListBuilder : public ArrayBuilder { |
45 | public: |
46 | /// Use this constructor to incrementally build the value array along with offsets and |
47 | /// null bitmap. |
48 | ListBuilder(MemoryPool* pool, std::shared_ptr<ArrayBuilder> const& value_builder, |
49 | const std::shared_ptr<DataType>& type = NULLPTR); |
50 | |
51 | Status Resize(int64_t capacity) override; |
52 | void Reset() override; |
53 | Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
54 | |
55 | /// \brief Vector append |
56 | /// |
57 | /// If passed, valid_bytes is of equal length to values, and any zero byte |
58 | /// will be considered as a null for that slot |
59 | Status AppendValues(const int32_t* offsets, int64_t length, |
60 | const uint8_t* valid_bytes = NULLPTR); |
61 | |
62 | /// \brief Start a new variable-length list slot |
63 | /// |
64 | /// This function should be called before beginning to append elements to the |
65 | /// value builder |
66 | Status Append(bool is_valid = true); |
67 | |
68 | Status AppendNull() { return Append(false); } |
69 | |
70 | ArrayBuilder* value_builder() const; |
71 | |
72 | protected: |
73 | TypedBufferBuilder<int32_t> offsets_builder_; |
74 | std::shared_ptr<ArrayBuilder> value_builder_; |
75 | std::shared_ptr<Array> values_; |
76 | |
77 | Status AppendNextOffset(); |
78 | }; |
79 | |
80 | // ---------------------------------------------------------------------- |
81 | // Struct |
82 | |
83 | // --------------------------------------------------------------------------------- |
84 | // StructArray builder |
85 | /// Append, Resize and Reserve methods are acting on StructBuilder. |
86 | /// Please make sure all these methods of all child-builders' are consistently |
87 | /// called to maintain data-structure consistency. |
88 | class ARROW_EXPORT StructBuilder : public ArrayBuilder { |
89 | public: |
90 | StructBuilder(const std::shared_ptr<DataType>& type, MemoryPool* pool, |
91 | std::vector<std::shared_ptr<ArrayBuilder>>&& field_builders); |
92 | |
93 | Status FinishInternal(std::shared_ptr<ArrayData>* out) override; |
94 | |
95 | /// Null bitmap is of equal length to every child field, and any zero byte |
96 | /// will be considered as a null for that field, but users must using app- |
97 | /// end methods or advance methods of the child builders' independently to |
98 | /// insert data. |
99 | Status AppendValues(int64_t length, const uint8_t* valid_bytes) { |
100 | ARROW_RETURN_NOT_OK(Reserve(length)); |
101 | UnsafeAppendToBitmap(valid_bytes, length); |
102 | return Status::OK(); |
103 | } |
104 | |
105 | /// Append an element to the Struct. All child-builders' Append method must |
106 | /// be called independently to maintain data-structure consistency. |
107 | Status Append(bool is_valid = true) { |
108 | ARROW_RETURN_NOT_OK(Reserve(1)); |
109 | UnsafeAppendToBitmap(is_valid); |
110 | return Status::OK(); |
111 | } |
112 | |
113 | Status AppendNull() { return Append(false); } |
114 | |
115 | void Reset() override; |
116 | |
117 | ArrayBuilder* field_builder(int i) const { return children_[i].get(); } |
118 | |
119 | int num_fields() const { return static_cast<int>(children_.size()); } |
120 | }; |
121 | |
122 | } // namespace arrow |
123 | |