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 #include "arrow/array/builder_base.h"
19
20 #include <algorithm>
21 #include <cstddef>
22 #include <cstdint>
23 #include <cstring>
24 #include <utility>
25 #include <vector>
26
27 #include "arrow/array.h"
28 #include "arrow/buffer.h"
29 #include "arrow/status.h"
30 #include "arrow/type.h"
31 #include "arrow/type_traits.h"
32 #include "arrow/util/bit_util.h"
33 #include "arrow/util/int_util.h"
34 #include "arrow/util/logging.h"
35
36 namespace arrow {
37
TrimBuffer(const int64_t bytes_filled,ResizableBuffer * buffer)38 Status ArrayBuilder::TrimBuffer(const int64_t bytes_filled, ResizableBuffer* buffer) {
39 if (buffer) {
40 if (bytes_filled < buffer->size()) {
41 // Trim buffer
42 RETURN_NOT_OK(buffer->Resize(bytes_filled));
43 }
44 // zero the padding
45 buffer->ZeroPadding();
46 } else {
47 // Null buffers are allowed in place of 0-byte buffers
48 DCHECK_EQ(bytes_filled, 0);
49 }
50 return Status::OK();
51 }
52
AppendToBitmap(bool is_valid)53 Status ArrayBuilder::AppendToBitmap(bool is_valid) {
54 RETURN_NOT_OK(Reserve(1));
55 UnsafeAppendToBitmap(is_valid);
56 return Status::OK();
57 }
58
AppendToBitmap(const uint8_t * valid_bytes,int64_t length)59 Status ArrayBuilder::AppendToBitmap(const uint8_t* valid_bytes, int64_t length) {
60 RETURN_NOT_OK(Reserve(length));
61 UnsafeAppendToBitmap(valid_bytes, length);
62 return Status::OK();
63 }
64
AppendToBitmap(int64_t num_bits,bool value)65 Status ArrayBuilder::AppendToBitmap(int64_t num_bits, bool value) {
66 RETURN_NOT_OK(Reserve(num_bits));
67 UnsafeAppendToBitmap(num_bits, value);
68 return Status::OK();
69 }
70
Resize(int64_t capacity)71 Status ArrayBuilder::Resize(int64_t capacity) {
72 RETURN_NOT_OK(CheckCapacity(capacity));
73 capacity_ = capacity;
74 return null_bitmap_builder_.Resize(capacity);
75 }
76
Advance(int64_t elements)77 Status ArrayBuilder::Advance(int64_t elements) {
78 if (length_ + elements > capacity_) {
79 return Status::Invalid("Builder must be expanded");
80 }
81 length_ += elements;
82 return null_bitmap_builder_.Advance(elements);
83 }
84
Finish(std::shared_ptr<Array> * out)85 Status ArrayBuilder::Finish(std::shared_ptr<Array>* out) {
86 std::shared_ptr<ArrayData> internal_data;
87 RETURN_NOT_OK(FinishInternal(&internal_data));
88 *out = MakeArray(internal_data);
89 return Status::OK();
90 }
91
Reset()92 void ArrayBuilder::Reset() {
93 capacity_ = length_ = null_count_ = 0;
94 null_bitmap_builder_.Reset();
95 }
96
SetNotNull(int64_t length)97 Status ArrayBuilder::SetNotNull(int64_t length) {
98 RETURN_NOT_OK(Reserve(length));
99 UnsafeSetNotNull(length);
100 return Status::OK();
101 }
102
UnsafeAppendToBitmap(const std::vector<bool> & is_valid)103 void ArrayBuilder::UnsafeAppendToBitmap(const std::vector<bool>& is_valid) {
104 for (bool element_valid : is_valid) {
105 UnsafeAppendToBitmap(element_valid);
106 }
107 }
108
UnsafeSetNotNull(int64_t length)109 void ArrayBuilder::UnsafeSetNotNull(int64_t length) {
110 length_ += length;
111 null_bitmap_builder_.UnsafeAppend(length, true);
112 }
113
UnsafeSetNull(int64_t length)114 void ArrayBuilder::UnsafeSetNull(int64_t length) {
115 length_ += length;
116 null_count_ += length;
117 null_bitmap_builder_.UnsafeAppend(length, false);
118 }
119
120 } // namespace arrow
121