1use crate::builder::{ArrayBuilder, BooleanBufferBuilder};
6use crate::{Array, ArrayRef, BooleanArray};
7use arrow_buffer::Buffer;
8use arrow_buffer::NullBufferBuilder;
9use arrow_data::ArrayData;
10use arrow_schema::{ArrowError, DataType};
11use std::any::Any;
12use std::sync::Arc;
13
14#[derive(Debug)]
46pub struct BooleanBuilder {
47 values_builder: BooleanBufferBuilder,
48 null_buffer_builder: NullBufferBuilder,
49}
50
51impl Default for BooleanBuilder {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57impl BooleanBuilder {
58 pub fn new() -> Self {
60 Self::with_capacity(1024)
61 }
62
63 pub fn with_capacity(capacity: usize) -> Self {
65 Self {
66 values_builder: BooleanBufferBuilder::new(capacity),
67 null_buffer_builder: NullBufferBuilder::new(capacity),
68 }
69 }
70
71 pub fn capacity(&self) -> usize {
73 self.values_builder.capacity()
74 }
75
76 #[inline]
78 pub fn append_value(&mut self, v: bool) {
79 self.values_builder.append(v);
80 self.null_buffer_builder.append_non_null();
81 }
82
83 #[inline]
85 pub fn append_null(&mut self) {
86 self.null_buffer_builder.append_null();
87 self.values_builder.advance(1);
88 }
89
90 #[inline]
92 pub fn append_nulls(&mut self, n: usize) {
93 self.null_buffer_builder.append_n_nulls(n);
94 self.values_builder.advance(n);
95 }
96
97 #[inline]
99 pub fn append_option(&mut self, v: Option<bool>) {
100 match v {
101 None => self.append_null(),
102 Some(v) => self.append_value(v),
103 }
104 }
105
106 #[inline]
108 pub fn append_slice(&mut self, v: &[bool]) {
109 self.values_builder.append_slice(v);
110 self.null_buffer_builder.append_n_non_nulls(v.len());
111 }
112
113 #[inline]
115 pub fn append_n(&mut self, additional: usize, v: bool) {
116 self.values_builder.append_n(additional, v);
117 self.null_buffer_builder.append_n_non_nulls(additional);
118 }
119
120 #[inline]
124 pub fn append_values(&mut self, values: &[bool], is_valid: &[bool]) -> Result<(), ArrowError> {
125 if values.len() != is_valid.len() {
126 Err(ArrowError::InvalidArgumentError(
127 "Value and validity lengths must be equal".to_string(),
128 ))
129 } else {
130 self.null_buffer_builder.append_slice(is_valid);
131 self.values_builder.append_slice(values);
132 Ok(())
133 }
134 }
135
136 #[inline]
139 pub fn append_array(&mut self, array: &BooleanArray) {
140 self.values_builder.append_buffer(array.values());
141 if let Some(null_buffer) = array.nulls() {
142 self.null_buffer_builder.append_buffer(null_buffer);
143 } else {
144 self.null_buffer_builder.append_n_non_nulls(array.len());
145 }
146 }
147
148 pub fn finish(&mut self) -> BooleanArray {
150 let len = self.len();
151 let null_bit_buffer = self.null_buffer_builder.finish();
152 let builder = ArrayData::builder(DataType::Boolean)
153 .len(len)
154 .add_buffer(self.values_builder.finish().into_inner())
155 .nulls(null_bit_buffer);
156
157 let array_data = unsafe { builder.build_unchecked() };
159 BooleanArray::from(array_data)
160 }
161
162 pub fn finish_cloned(&self) -> BooleanArray {
164 let len = self.len();
165 let nulls = self.null_buffer_builder.finish_cloned();
166 let value_buffer = Buffer::from_slice_ref(self.values_builder.as_slice());
167 let builder = ArrayData::builder(DataType::Boolean)
168 .len(len)
169 .add_buffer(value_buffer)
170 .nulls(nulls);
171
172 let array_data = unsafe { builder.build_unchecked() };
174 BooleanArray::from(array_data)
175 }
176
177 pub fn values_slice(&self) -> &[u8] {
182 self.values_builder.as_slice()
183 }
184
185 pub fn validity_slice(&self) -> Option<&[u8]> {
187 self.null_buffer_builder.as_slice()
188 }
189}
190
191impl ArrayBuilder for BooleanBuilder {
192 fn as_any(&self) -> &dyn Any {
194 self
195 }
196
197 fn as_any_mut(&mut self) -> &mut dyn Any {
199 self
200 }
201
202 fn into_box_any(self: Box<Self>) -> Box<dyn Any> {
204 self
205 }
206
207 fn len(&self) -> usize {
209 self.values_builder.len()
210 }
211
212 fn finish(&mut self) -> ArrayRef {
214 Arc::new(self.finish())
215 }
216
217 fn finish_cloned(&self) -> ArrayRef {
219 Arc::new(self.finish_cloned())
220 }
221}
222
223impl Extend<Option<bool>> for BooleanBuilder {
224 #[inline]
225 fn extend<T: IntoIterator<Item = Option<bool>>>(&mut self, iter: T) {
226 let buffered = iter.into_iter().collect::<Vec<_>>();
227 let array = unsafe {
228 BooleanArray::from_trusted_len_iter(buffered.into_iter())
230 };
231 self.append_array(&array)
232 }
233}
234
235#[cfg(test)]
236mod tests {
237 use super::*;
238 use crate::Array;
239 use arrow_buffer::{BooleanBuffer, NullBuffer};
240
241 #[test]
242 fn test_boolean_array_builder() {
243 let buf = Buffer::from([72_u8, 2_u8]);
245 let mut builder = BooleanArray::builder(10);
246 for i in 0..10 {
247 if i == 3 || i == 6 || i == 9 {
248 builder.append_value(true);
249 } else {
250 builder.append_value(false);
251 }
252 }
253
254 let arr = builder.finish();
255 assert_eq!(&buf, arr.values().inner());
256 assert_eq!(10, arr.len());
257 assert_eq!(0, arr.offset());
258 assert_eq!(0, arr.null_count());
259 for i in 0..10 {
260 assert!(!arr.is_null(i));
261 assert!(arr.is_valid(i));
262 assert_eq!(i == 3 || i == 6 || i == 9, arr.value(i), "failed at {i}")
263 }
264 }
265
266 #[test]
267 fn test_boolean_array_builder_append_slice() {
268 let arr1 = BooleanArray::from(vec![Some(true), Some(false), None, None, Some(false)]);
269
270 let mut builder = BooleanArray::builder(0);
271 builder.append_slice(&[true, false]);
272 builder.append_null();
273 builder.append_null();
274 builder.append_value(false);
275 let arr2 = builder.finish();
276
277 assert_eq!(arr1, arr2);
278 }
279
280 #[test]
281 fn test_boolean_array_builder_append_slice_large() {
282 let arr1 = BooleanArray::from(vec![true; 513]);
283
284 let mut builder = BooleanArray::builder(512);
285 builder.append_slice(&[true; 513]);
286 let arr2 = builder.finish();
287
288 assert_eq!(arr1, arr2);
289 }
290
291 #[test]
292 fn test_boolean_array_builder_no_null() {
293 let mut builder = BooleanArray::builder(0);
294 builder.append_option(Some(true));
295 builder.append_value(false);
296 builder.append_slice(&[true, false, true]);
297 builder
298 .append_values(&[false, false, true], &[true, true, true])
299 .unwrap();
300
301 let array = builder.finish();
302 assert_eq!(0, array.null_count());
303 assert!(array.nulls().is_none());
304 }
305
306 #[test]
307 fn test_boolean_array_builder_finish_cloned() {
308 let mut builder = BooleanArray::builder(16);
309 builder.append_option(Some(true));
310 builder.append_value(false);
311 builder.append_slice(&[true, false, true]);
312 let mut array = builder.finish_cloned();
313 assert_eq!(3, array.true_count());
314 assert_eq!(2, array.false_count());
315
316 builder
317 .append_values(&[false, false, true], &[true, true, true])
318 .unwrap();
319
320 array = builder.finish();
321 assert_eq!(4, array.true_count());
322 assert_eq!(4, array.false_count());
323
324 assert_eq!(0, array.null_count());
325 assert!(array.nulls().is_none());
326 }
327
328 #[test]
329 fn test_extend() {
330 let mut builder = BooleanBuilder::new();
331 builder.extend([false, false, true, false, false].into_iter().map(Some));
332 builder.extend([true, true, false].into_iter().map(Some));
333 let array = builder.finish();
334 let values = array.iter().map(|x| x.unwrap()).collect::<Vec<_>>();
335 assert_eq!(
336 &values,
337 &[false, false, true, false, false, true, true, false]
338 )
339 }
340
341 #[test]
342 fn test_boolean_array_builder_append_n() {
343 let mut builder = BooleanBuilder::new();
344 builder.append_n(3, true);
345 builder.append_n(2, false);
346 let array = builder.finish();
347 assert_eq!(3, array.true_count());
348 assert_eq!(2, array.false_count());
349 assert_eq!(0, array.null_count());
350
351 let values = array.iter().map(|x| x.unwrap()).collect::<Vec<_>>();
352 assert_eq!(&values, &[true, true, true, false, false])
353 }
354
355 #[test]
356 fn test_append_array() {
357 let input = vec![
358 Some(true),
359 None,
360 Some(true),
361 None,
362 Some(false),
363 None,
364 None,
365 None,
366 Some(false),
367 Some(false),
368 Some(false),
369 Some(true),
370 Some(false),
371 ];
372 let arr1 = BooleanArray::from(input[..5].to_vec());
373 let arr2 = BooleanArray::from(input[5..8].to_vec());
374 let arr3 = BooleanArray::from(input[8..].to_vec());
375
376 let mut builder = BooleanBuilder::new();
377 builder.append_array(&arr1);
378 builder.append_array(&arr2);
379 builder.append_array(&arr3);
380 let actual = builder.finish();
381 let expected = BooleanArray::from(input);
382
383 assert_eq!(actual, expected);
384 }
385
386 #[test]
387 fn test_append_array_add_underlying_null_values() {
388 let array = BooleanArray::new(
389 BooleanBuffer::from(vec![true, false, true, false]),
390 Some(NullBuffer::from(&[true, true, false, false])),
391 );
392
393 let mut builder = BooleanBuilder::new();
394 builder.append_array(&array);
395 let actual = builder.finish();
396
397 assert_eq!(actual, array);
398 assert_eq!(actual.values(), array.values())
399 }
400}