1use 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 {
95 let capacity = buffer.len() * 8;
96 assert!(len <= capacity);
97
98 let bitmap_builder = Some(BooleanBufferBuilder::new_from_buffer(buffer, len));
99 Self {
100 bitmap_builder,
101 len,
102 capacity,
103 }
104 }
105
106 #[inline]
109 pub fn append_n_non_nulls(&mut self, n: usize) {
110 if let Some(buf) = self.bitmap_builder.as_mut() {
111 buf.append_n(n, true)
112 } else {
113 self.len += n;
114 }
115 }
116
117 #[inline]
120 pub fn append_non_null(&mut self) {
121 if let Some(buf) = self.bitmap_builder.as_mut() {
122 buf.append(true)
123 } else {
124 self.len += 1;
125 }
126 }
127
128 #[inline]
131 pub fn append_n_nulls(&mut self, n: usize) {
132 self.materialize_if_needed().append_n(n, false);
133 }
134
135 #[inline]
138 pub fn append_null(&mut self) {
139 self.materialize_if_needed().append(false);
140 }
141
142 #[inline]
144 pub fn append(&mut self, not_null: bool) {
145 if not_null {
146 self.append_non_null()
147 } else {
148 self.append_null()
149 }
150 }
151
152 #[inline]
158 pub fn set_bit(&mut self, index: usize, v: bool) {
159 self.materialize_if_needed().set_bit(index, v);
160 }
161
162 #[inline]
169 pub fn is_valid(&self, index: usize) -> bool {
170 if let Some(ref buf) = self.bitmap_builder {
171 buf.get_bit(index)
172 } else {
173 true
174 }
175 }
176
177 #[inline]
181 pub fn truncate(&mut self, len: usize) {
182 if let Some(buf) = self.bitmap_builder.as_mut() {
183 buf.truncate(len);
184 } else if len <= self.len {
185 self.len = len
186 }
187 }
188
189 pub fn append_slice(&mut self, slice: &[bool]) {
192 if self.bitmap_builder.is_none() && slice.iter().any(|v| !v) {
194 self.materialize_if_needed();
195 }
196 if let Some(buf) = self.bitmap_builder.as_mut() {
197 buf.append_slice(slice)
198 } else {
199 self.len += slice.len();
200 }
201 }
202
203 pub fn append_buffer(&mut self, buffer: &NullBuffer) {
207 if buffer.null_count() > 0 {
208 self.materialize_if_needed();
209 }
210 if let Some(buf) = self.bitmap_builder.as_mut() {
211 buf.append_buffer(buffer.inner())
212 } else {
213 self.len += buffer.len();
214 }
215 }
216
217 pub fn finish(&mut self) -> Option<NullBuffer> {
222 self.len = 0;
223 Some(NullBuffer::new(self.bitmap_builder.take()?.build()))
224 }
225
226 pub fn build(self) -> Option<NullBuffer> {
230 self.bitmap_builder.map(NullBuffer::from)
231 }
232
233 pub fn finish_cloned(&self) -> Option<NullBuffer> {
235 let buffer = self.bitmap_builder.as_ref()?.finish_cloned();
236 Some(NullBuffer::new(buffer))
237 }
238
239 pub fn as_slice(&self) -> Option<&[u8]> {
241 Some(self.bitmap_builder.as_ref()?.as_slice())
242 }
243
244 fn materialize_if_needed(&mut self) -> &mut BooleanBufferBuilder {
245 let (len, capacity) = (self.len, self.capacity);
246 self.bitmap_builder
247 .get_or_insert_with(|| Self::materialize(len, capacity))
248 }
249
250 #[cold]
251 fn materialize(len: usize, capacity: usize) -> BooleanBufferBuilder {
252 let mut b = BooleanBufferBuilder::new(len.max(capacity));
253 b.append_n(len, true);
254 b
255 }
256
257 pub fn as_slice_mut(&mut self) -> Option<&mut [u8]> {
259 self.bitmap_builder.as_mut().map(|b| b.as_slice_mut())
260 }
261
262 pub fn allocated_size(&self) -> usize {
264 self.bitmap_builder
265 .as_ref()
266 .map(|b| b.capacity() / 8)
267 .unwrap_or(0)
268 }
269
270 pub fn len(&self) -> usize {
272 self.bitmap_builder.as_ref().map_or(self.len, |b| b.len())
273 }
274
275 pub fn is_empty(&self) -> bool {
277 self.len() == 0
278 }
279}
280
281#[cfg(test)]
282mod tests {
283 use super::*;
284
285 #[test]
286 fn test_null_buffer_builder() {
287 let mut builder = NullBufferBuilder::new(0);
288 builder.append_null();
289 builder.append_non_null();
290 builder.append_n_nulls(2);
291 builder.append_n_non_nulls(2);
292 assert_eq!(6, builder.len());
293 assert_eq!(64, builder.allocated_size());
294
295 let buf = builder.finish().unwrap();
296 assert_eq!(&[0b110010_u8], buf.validity());
297 }
298
299 #[test]
300 fn test_null_buffer_builder_all_nulls() {
301 let mut builder = NullBufferBuilder::new(0);
302 builder.append_null();
303 builder.append_n_nulls(2);
304 builder.append_slice(&[false, false, false]);
305 assert_eq!(6, builder.len());
306 assert_eq!(64, builder.allocated_size());
307
308 let buf = builder.finish().unwrap();
309 assert_eq!(&[0b0_u8], buf.validity());
310 }
311
312 #[test]
313 fn test_null_buffer_builder_no_null() {
314 let mut builder = NullBufferBuilder::new(0);
315 builder.append_non_null();
316 builder.append_n_non_nulls(2);
317 builder.append_slice(&[true, true, true]);
318 assert_eq!(6, builder.len());
319 assert_eq!(0, builder.allocated_size());
320
321 let buf = builder.finish();
322 assert!(buf.is_none());
323 }
324
325 #[test]
326 fn test_null_buffer_builder_reset() {
327 let mut builder = NullBufferBuilder::new(0);
328 builder.append_slice(&[true, false, true]);
329 builder.finish();
330 assert!(builder.is_empty());
331
332 builder.append_slice(&[true, true, true]);
333 assert!(builder.finish().is_none());
334 assert!(builder.is_empty());
335
336 builder.append_slice(&[true, true, false, true]);
337
338 let buf = builder.finish().unwrap();
339 assert_eq!(&[0b1011_u8], buf.validity());
340 }
341
342 #[test]
343 fn test_null_buffer_builder_is_valid() {
344 let mut builder = NullBufferBuilder::new(0);
345 builder.append_n_non_nulls(6);
346 assert!(builder.is_valid(0));
347
348 builder.append_null();
349 assert!(!builder.is_valid(6));
350
351 builder.append_non_null();
352 assert!(builder.is_valid(7));
353 }
354
355 #[test]
356 fn test_null_buffer_builder_truncate() {
357 let mut builder = NullBufferBuilder::new(10);
358 builder.append_n_non_nulls(16);
359 assert_eq!(builder.as_slice(), None);
360 builder.truncate(20);
361 assert_eq!(builder.as_slice(), None);
362 assert_eq!(builder.len(), 16);
363 assert_eq!(builder.allocated_size(), 0);
364 builder.truncate(14);
365 assert_eq!(builder.as_slice(), None);
366 assert_eq!(builder.len(), 14);
367 builder.append_null();
368 builder.append_non_null();
369 assert_eq!(builder.as_slice().unwrap(), &[0xFF, 0b10111111]);
370 assert_eq!(builder.allocated_size(), 64);
371 }
372
373 #[test]
374 fn test_null_buffer_builder_truncate_never_materialized() {
375 let mut builder = NullBufferBuilder::new(0);
376 assert_eq!(builder.len(), 0);
377 builder.append_n_nulls(2); assert_eq!(builder.len(), 2);
379 builder.truncate(1);
380 assert_eq!(builder.len(), 1);
381 }
382
383 #[test]
384 fn test_append_buffers() {
385 let mut builder = NullBufferBuilder::new(0);
386 let buffer1 = NullBuffer::from(&[true, true]);
387 let buffer2 = NullBuffer::from(&[true, true, false]);
388
389 builder.append_buffer(&buffer1);
390 builder.append_buffer(&buffer2);
391
392 assert_eq!(builder.as_slice().unwrap(), &[0b01111_u8]);
393 }
394
395 #[test]
396 fn test_append_buffers_with_unaligned_length() {
397 let mut builder = NullBufferBuilder::new(0);
398 let buffer = NullBuffer::from(&[true, true, false, true, false]);
399 builder.append_buffer(&buffer);
400 assert_eq!(builder.as_slice().unwrap(), &[0b01011_u8]);
401
402 let buffer = NullBuffer::from(&[false, false, true, true, true, false, false]);
403 builder.append_buffer(&buffer);
404 assert_eq!(builder.as_slice().unwrap(), &[0b10001011_u8, 0b0011_u8]);
405 }
406
407 #[test]
408 fn test_append_empty_buffer() {
409 let mut builder = NullBufferBuilder::new(0);
410 let buffer = NullBuffer::from(&[true, true, false, true]);
411 builder.append_buffer(&buffer);
412 assert_eq!(builder.as_slice().unwrap(), &[0b1011_u8]);
413
414 let buffer = NullBuffer::from(&[]);
415 builder.append_buffer(&buffer);
416
417 assert_eq!(builder.as_slice().unwrap(), &[0b1011_u8]);
418 }
419
420 #[test]
421 fn test_should_not_materialize_when_appending_all_valid_buffers() {
422 let mut builder = NullBufferBuilder::new(0);
423 let buffer = NullBuffer::from(&[true; 10]);
424 builder.append_buffer(&buffer);
425
426 let buffer = NullBuffer::from(&[true; 2]);
427 builder.append_buffer(&buffer);
428
429 assert_eq!(builder.finish(), None);
430 }
431}