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
26namespace 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.
44class 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.
88class 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