arrow_buffer/builder/
null.rs1use crate::{BooleanBufferBuilder, MutableBuffer, NullBuffer};
19
20#[derive(Debug)]
53pub struct NullBufferBuilder {
54 bitmap_builder: Option<BooleanBufferBuilder>,
58 len: usize,
62 capacity: usize,
64}
65
66impl NullBufferBuilder {
67 pub fn new(capacity: usize) -> Self {
73 Self {
74 bitmap_builder: None,
75 len: 0,
76 capacity,
77 }
78 }
79
80 pub fn new_with_len(len: usize) -> Self {
82 Self {
83 bitmap_builder: None,
84 len,
85 capacity: len,
86 }
87 }
88
89 pub fn new_from_buffer(buffer: MutableBuffer, len: usize) -> Self {
91 let capacity = buffer.len() * 8;
92 assert!(len <= capacity);
93
94 let bitmap_builder = Some(BooleanBufferBuilder::new_from_buffer(buffer, len));
95 Self {
96 bitmap_builder,
97 len,
98 capacity,
99 }
100 }
101
102 #[inline]
105 pub fn append_n_non_nulls(&mut self, n: usize) {
106 if let Some(buf) = self.bitmap_builder.as_mut() {
107 buf.append_n(n, true)
108 } else {
109 self.len += n;
110 }
111 }
112
113 #[inline]
116 pub fn append_non_null(&mut self) {
117 if let Some(buf) = self.bitmap_builder.as_mut() {
118 buf.append(true)
119 } else {
120 self.len += 1;
121 }
122 }
123
124 #[inline]
127 pub fn append_n_nulls(&mut self, n: usize) {
128 self.materialize_if_needed();
129 self.bitmap_builder.as_mut().unwrap().append_n(n, false);
130 }
131
132 #[inline]
135 pub fn append_null(&mut self) {
136 self.materialize_if_needed();
137 self.bitmap_builder.as_mut().unwrap().append(false);
138 }
139
140 #[inline]
142 pub fn append(&mut self, not_null: bool) {
143 if not_null {
144 self.append_non_null()
145 } else {
146 self.append_null()
147 }
148 }
149
150 #[inline]
152 pub fn is_valid(&self, index: usize) -> bool {
153 if let Some(ref buf) = self.bitmap_builder {
154 buf.get_bit(index)
155 } else {
156 true
157 }
158 }
159
160 #[inline]
164 pub fn truncate(&mut self, len: usize) {
165 if let Some(buf) = self.bitmap_builder.as_mut() {
166 buf.truncate(len);
167 } else if len <= self.len {
168 self.len = len
169 }
170 }
171
172 pub fn append_slice(&mut self, slice: &[bool]) {
175 if slice.iter().any(|v| !v) {
176 self.materialize_if_needed()
177 }
178 if let Some(buf) = self.bitmap_builder.as_mut() {
179 buf.append_slice(slice)
180 } else {
181 self.len += slice.len();
182 }
183 }
184
185 pub fn append_buffer(&mut self, buffer: &NullBuffer) {
189 if buffer.null_count() > 0 {
190 self.materialize_if_needed();
191 }
192 if let Some(buf) = self.bitmap_builder.as_mut() {
193 buf.append_buffer(buffer.inner())
194 } else {
195 self.len += buffer.len();
196 }
197 }
198
199 pub fn finish(&mut self) -> Option<NullBuffer> {
204 self.len = 0;
205 Some(NullBuffer::new(self.bitmap_builder.take()?.build()))
206 }
207
208 pub fn build(self) -> Option<NullBuffer> {
212 self.bitmap_builder.map(NullBuffer::from)
213 }
214
215 pub fn finish_cloned(&self) -> Option<NullBuffer> {
217 let buffer = self.bitmap_builder.as_ref()?.finish_cloned();
218 Some(NullBuffer::new(buffer))
219 }
220
221 pub fn as_slice(&self) -> Option<&[u8]> {
223 Some(self.bitmap_builder.as_ref()?.as_slice())
224 }
225
226 fn materialize_if_needed(&mut self) {
227 if self.bitmap_builder.is_none() {
228 self.materialize()
229 }
230 }
231
232 #[cold]
233 fn materialize(&mut self) {
234 if self.bitmap_builder.is_none() {
235 let mut b = BooleanBufferBuilder::new(self.len.max(self.capacity));
236 b.append_n(self.len, true);
237 self.bitmap_builder = Some(b);
238 }
239 }
240
241 pub fn as_slice_mut(&mut self) -> Option<&mut [u8]> {
243 self.bitmap_builder.as_mut().map(|b| b.as_slice_mut())
244 }
245
246 pub fn allocated_size(&self) -> usize {
248 self.bitmap_builder
249 .as_ref()
250 .map(|b| b.capacity() / 8)
251 .unwrap_or(0)
252 }
253
254 pub fn len(&self) -> usize {
256 self.bitmap_builder.as_ref().map_or(self.len, |b| b.len())
257 }
258
259 pub fn is_empty(&self) -> bool {
261 self.len() == 0
262 }
263}
264
265#[cfg(test)]
266mod tests {
267 use super::*;
268
269 #[test]
270 fn test_null_buffer_builder() {
271 let mut builder = NullBufferBuilder::new(0);
272 builder.append_null();
273 builder.append_non_null();
274 builder.append_n_nulls(2);
275 builder.append_n_non_nulls(2);
276 assert_eq!(6, builder.len());
277 assert_eq!(64, builder.allocated_size());
278
279 let buf = builder.finish().unwrap();
280 assert_eq!(&[0b110010_u8], buf.validity());
281 }
282
283 #[test]
284 fn test_null_buffer_builder_all_nulls() {
285 let mut builder = NullBufferBuilder::new(0);
286 builder.append_null();
287 builder.append_n_nulls(2);
288 builder.append_slice(&[false, false, false]);
289 assert_eq!(6, builder.len());
290 assert_eq!(64, builder.allocated_size());
291
292 let buf = builder.finish().unwrap();
293 assert_eq!(&[0b0_u8], buf.validity());
294 }
295
296 #[test]
297 fn test_null_buffer_builder_no_null() {
298 let mut builder = NullBufferBuilder::new(0);
299 builder.append_non_null();
300 builder.append_n_non_nulls(2);
301 builder.append_slice(&[true, true, true]);
302 assert_eq!(6, builder.len());
303 assert_eq!(0, builder.allocated_size());
304
305 let buf = builder.finish();
306 assert!(buf.is_none());
307 }
308
309 #[test]
310 fn test_null_buffer_builder_reset() {
311 let mut builder = NullBufferBuilder::new(0);
312 builder.append_slice(&[true, false, true]);
313 builder.finish();
314 assert!(builder.is_empty());
315
316 builder.append_slice(&[true, true, true]);
317 assert!(builder.finish().is_none());
318 assert!(builder.is_empty());
319
320 builder.append_slice(&[true, true, false, true]);
321
322 let buf = builder.finish().unwrap();
323 assert_eq!(&[0b1011_u8], buf.validity());
324 }
325
326 #[test]
327 fn test_null_buffer_builder_is_valid() {
328 let mut builder = NullBufferBuilder::new(0);
329 builder.append_n_non_nulls(6);
330 assert!(builder.is_valid(0));
331
332 builder.append_null();
333 assert!(!builder.is_valid(6));
334
335 builder.append_non_null();
336 assert!(builder.is_valid(7));
337 }
338
339 #[test]
340 fn test_null_buffer_builder_truncate() {
341 let mut builder = NullBufferBuilder::new(10);
342 builder.append_n_non_nulls(16);
343 assert_eq!(builder.as_slice(), None);
344 builder.truncate(20);
345 assert_eq!(builder.as_slice(), None);
346 assert_eq!(builder.len(), 16);
347 assert_eq!(builder.allocated_size(), 0);
348 builder.truncate(14);
349 assert_eq!(builder.as_slice(), None);
350 assert_eq!(builder.len(), 14);
351 builder.append_null();
352 builder.append_non_null();
353 assert_eq!(builder.as_slice().unwrap(), &[0xFF, 0b10111111]);
354 assert_eq!(builder.allocated_size(), 64);
355 }
356
357 #[test]
358 fn test_null_buffer_builder_truncate_never_materialized() {
359 let mut builder = NullBufferBuilder::new(0);
360 assert_eq!(builder.len(), 0);
361 builder.append_n_nulls(2); assert_eq!(builder.len(), 2);
363 builder.truncate(1);
364 assert_eq!(builder.len(), 1);
365 }
366
367 #[test]
368 fn test_append_buffers() {
369 let mut builder = NullBufferBuilder::new(0);
370 let buffer1 = NullBuffer::from(&[true, true]);
371 let buffer2 = NullBuffer::from(&[true, true, false]);
372
373 builder.append_buffer(&buffer1);
374 builder.append_buffer(&buffer2);
375
376 assert_eq!(builder.as_slice().unwrap(), &[0b01111_u8]);
377 }
378
379 #[test]
380 fn test_append_buffers_with_unaligned_length() {
381 let mut builder = NullBufferBuilder::new(0);
382 let buffer = NullBuffer::from(&[true, true, false, true, false]);
383 builder.append_buffer(&buffer);
384 assert_eq!(builder.as_slice().unwrap(), &[0b01011_u8]);
385
386 let buffer = NullBuffer::from(&[false, false, true, true, true, false, false]);
387 builder.append_buffer(&buffer);
388 assert_eq!(builder.as_slice().unwrap(), &[0b10001011_u8, 0b0011_u8]);
389 }
390
391 #[test]
392 fn test_append_empty_buffer() {
393 let mut builder = NullBufferBuilder::new(0);
394 let buffer = NullBuffer::from(&[true, true, false, true]);
395 builder.append_buffer(&buffer);
396 assert_eq!(builder.as_slice().unwrap(), &[0b1011_u8]);
397
398 let buffer = NullBuffer::from(&[]);
399 builder.append_buffer(&buffer);
400
401 assert_eq!(builder.as_slice().unwrap(), &[0b1011_u8]);
402 }
403
404 #[test]
405 fn test_should_not_materialize_when_appending_all_valid_buffers() {
406 let mut builder = NullBufferBuilder::new(0);
407 let buffer = NullBuffer::from(&[true; 10]);
408 builder.append_buffer(&buffer);
409
410 let buffer = NullBuffer::from(&[true; 2]);
411 builder.append_buffer(&buffer);
412
413 assert_eq!(builder.finish(), None);
414 }
415}