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.
1718use crate::{BooleanBufferBuilder, MutableBuffer, NullBuffer};
1920/// Builder for creating the null bit buffer.
21///
22/// This builder only materializes the buffer when we append `false`.
23/// If you only append `true`s to the builder, what you get will be
24/// `None` when calling [`finish`](#method.finish).
25/// This optimization is **very** important for the performance.
26#[derive(Debug)]
27pub struct NullBufferBuilder {
28 bitmap_builder: Option<BooleanBufferBuilder>,
29/// Store the length of the buffer before materializing.
30len: usize,
31 capacity: usize,
32}
3334impl NullBufferBuilder {
35/// Creates a new empty builder.
36 /// `capacity` is the number of bits in the null buffer.
37pub fn new(capacity: usize) -> Self {
38Self {
39 bitmap_builder: None,
40 len: 0,
41 capacity,
42 }
43 }
4445/// Creates a new builder with given length.
46pub fn new_with_len(len: usize) -> Self {
47Self {
48 bitmap_builder: None,
49 len,
50 capacity: len,
51 }
52 }
5354/// Creates a new builder from a `MutableBuffer`.
55pub fn new_from_buffer(buffer: MutableBuffer, len: usize) -> Self {
56let capacity = buffer.len() * 8;
5758assert!(len <= capacity);
5960let bitmap_builder = Some(BooleanBufferBuilder::new_from_buffer(buffer, len));
61Self {
62 bitmap_builder,
63 len,
64 capacity,
65 }
66 }
6768/// Appends `n` `true`s into the builder
69 /// to indicate that these `n` items are not nulls.
70#[inline]
71pub fn append_n_non_nulls(&mut self, n: usize) {
72if let Some(buf) = self.bitmap_builder.as_mut() {
73 buf.append_n(n, true)
74 } else {
75self.len += n;
76 }
77 }
7879/// Appends a `true` into the builder
80 /// to indicate that this item is not null.
81#[inline]
82pub fn append_non_null(&mut self) {
83if let Some(buf) = self.bitmap_builder.as_mut() {
84 buf.append(true)
85 } else {
86self.len += 1;
87 }
88 }
8990/// Appends `n` `false`s into the builder
91 /// to indicate that these `n` items are nulls.
92#[inline]
93pub fn append_n_nulls(&mut self, n: usize) {
94self.materialize_if_needed();
95self.bitmap_builder.as_mut().unwrap().append_n(n, false);
96 }
9798/// Appends a `false` into the builder
99 /// to indicate that this item is null.
100#[inline]
101pub fn append_null(&mut self) {
102self.materialize_if_needed();
103self.bitmap_builder.as_mut().unwrap().append(false);
104 }
105106/// Appends a boolean value into the builder.
107#[inline]
108pub fn append(&mut self, not_null: bool) {
109if not_null {
110self.append_non_null()
111 } else {
112self.append_null()
113 }
114 }
115116/// Appends a boolean slice into the builder
117 /// to indicate the validations of these items.
118pub fn append_slice(&mut self, slice: &[bool]) {
119if slice.iter().any(|v| !v) {
120self.materialize_if_needed()
121 }
122if let Some(buf) = self.bitmap_builder.as_mut() {
123 buf.append_slice(slice)
124 } else {
125self.len += slice.len();
126 }
127 }
128129/// Builds the null buffer and resets the builder.
130 /// Returns `None` if the builder only contains `true`s.
131pub fn finish(&mut self) -> Option<NullBuffer> {
132self.len = 0;
133Some(NullBuffer::new(self.bitmap_builder.take()?.finish()))
134 }
135136/// Builds the [NullBuffer] without resetting the builder.
137pub fn finish_cloned(&self) -> Option<NullBuffer> {
138let buffer = self.bitmap_builder.as_ref()?.finish_cloned();
139Some(NullBuffer::new(buffer))
140 }
141142/// Returns the inner bitmap builder as slice
143pub fn as_slice(&self) -> Option<&[u8]> {
144Some(self.bitmap_builder.as_ref()?.as_slice())
145 }
146147fn materialize_if_needed(&mut self) {
148if self.bitmap_builder.is_none() {
149self.materialize()
150 }
151 }
152153#[cold]
154fn materialize(&mut self) {
155if self.bitmap_builder.is_none() {
156let mut b = BooleanBufferBuilder::new(self.len.max(self.capacity));
157 b.append_n(self.len, true);
158self.bitmap_builder = Some(b);
159 }
160 }
161162/// Return a mutable reference to the inner bitmap slice.
163pub fn as_slice_mut(&mut self) -> Option<&mut [u8]> {
164self.bitmap_builder.as_mut().map(|b| b.as_slice_mut())
165 }
166167/// Return the allocated size of this builder, in bytes, useful for memory accounting.
168pub fn allocated_size(&self) -> usize {
169self.bitmap_builder
170 .as_ref()
171 .map(|b| b.capacity())
172 .unwrap_or(0)
173 }
174}
175176impl NullBufferBuilder {
177/// Return the number of bits in the buffer.
178pub fn len(&self) -> usize {
179self.bitmap_builder.as_ref().map_or(self.len, |b| b.len())
180 }
181182/// Check if the builder is empty.
183pub fn is_empty(&self) -> bool {
184self.len() == 0
185}
186}
187188#[cfg(test)]
189mod tests {
190use super::*;
191192#[test]
193fn test_null_buffer_builder() {
194let mut builder = NullBufferBuilder::new(0);
195 builder.append_null();
196 builder.append_non_null();
197 builder.append_n_nulls(2);
198 builder.append_n_non_nulls(2);
199assert_eq!(6, builder.len());
200201let buf = builder.finish().unwrap();
202assert_eq!(&[0b110010_u8], buf.validity());
203 }
204205#[test]
206fn test_null_buffer_builder_all_nulls() {
207let mut builder = NullBufferBuilder::new(0);
208 builder.append_null();
209 builder.append_n_nulls(2);
210 builder.append_slice(&[false, false, false]);
211assert_eq!(6, builder.len());
212213let buf = builder.finish().unwrap();
214assert_eq!(&[0b0_u8], buf.validity());
215 }
216217#[test]
218fn test_null_buffer_builder_no_null() {
219let mut builder = NullBufferBuilder::new(0);
220 builder.append_non_null();
221 builder.append_n_non_nulls(2);
222 builder.append_slice(&[true, true, true]);
223assert_eq!(6, builder.len());
224225let buf = builder.finish();
226assert!(buf.is_none());
227 }
228229#[test]
230fn test_null_buffer_builder_reset() {
231let mut builder = NullBufferBuilder::new(0);
232 builder.append_slice(&[true, false, true]);
233 builder.finish();
234assert!(builder.is_empty());
235236 builder.append_slice(&[true, true, true]);
237assert!(builder.finish().is_none());
238assert!(builder.is_empty());
239240 builder.append_slice(&[true, true, false, true]);
241242let buf = builder.finish().unwrap();
243assert_eq!(&[0b1011_u8], buf.validity());
244 }
245}