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]
164 pub fn append_word(&mut self, word: u64, count: usize) {
165 assert!(count <= 64, "count must be less than or equal to 64");
166 if word.trailing_ones() as usize >= count {
167 self.append_n_non_nulls(count);
168 } else {
169 self.materialize_if_needed().append_word(word, count)
170 }
171 }
172
173 #[inline]
179 pub fn set_bit(&mut self, index: usize, v: bool) {
180 self.materialize_if_needed().set_bit(index, v);
181 }
182
183 #[inline]
190 pub fn is_valid(&self, index: usize) -> bool {
191 if let Some(ref buf) = self.bitmap_builder {
192 buf.get_bit(index)
193 } else {
194 true
195 }
196 }
197
198 #[inline]
202 pub fn truncate(&mut self, len: usize) {
203 if let Some(buf) = self.bitmap_builder.as_mut() {
204 buf.truncate(len);
205 } else if len <= self.len {
206 self.len = len
207 }
208 }
209
210 pub fn append_slice(&mut self, slice: &[bool]) {
213 if self.bitmap_builder.is_none() && slice.iter().any(|v| !v) {
215 self.materialize_if_needed();
216 }
217 if let Some(buf) = self.bitmap_builder.as_mut() {
218 buf.append_slice(slice)
219 } else {
220 self.len += slice.len();
221 }
222 }
223
224 pub fn append_buffer(&mut self, buffer: &NullBuffer) {
228 if buffer.null_count() > 0 {
229 self.materialize_if_needed();
230 }
231 if let Some(buf) = self.bitmap_builder.as_mut() {
232 buf.append_buffer(buffer.inner())
233 } else {
234 self.len += buffer.len();
235 }
236 }
237
238 pub fn finish(&mut self) -> Option<NullBuffer> {
243 self.len = 0;
244 Some(NullBuffer::new(self.bitmap_builder.take()?.build()))
245 }
246
247 pub fn build(self) -> Option<NullBuffer> {
251 self.bitmap_builder.map(NullBuffer::from)
252 }
253
254 pub fn finish_cloned(&self) -> Option<NullBuffer> {
256 let buffer = self.bitmap_builder.as_ref()?.finish_cloned();
257 Some(NullBuffer::new(buffer))
258 }
259
260 pub fn as_slice(&self) -> Option<&[u8]> {
262 Some(self.bitmap_builder.as_ref()?.as_slice())
263 }
264
265 fn materialize_if_needed(&mut self) -> &mut BooleanBufferBuilder {
266 let (len, capacity) = (self.len, self.capacity);
267 self.bitmap_builder
268 .get_or_insert_with(|| Self::materialize(len, capacity))
269 }
270
271 #[cold]
272 fn materialize(len: usize, capacity: usize) -> BooleanBufferBuilder {
273 let mut b = BooleanBufferBuilder::new(len.max(capacity));
274 b.append_n(len, true);
275 b
276 }
277
278 pub fn as_slice_mut(&mut self) -> Option<&mut [u8]> {
280 self.bitmap_builder.as_mut().map(|b| b.as_slice_mut())
281 }
282
283 pub fn allocated_size(&self) -> usize {
285 self.bitmap_builder
286 .as_ref()
287 .map(|b| b.capacity() / 8)
288 .unwrap_or(0)
289 }
290
291 pub fn len(&self) -> usize {
293 self.bitmap_builder.as_ref().map_or(self.len, |b| b.len())
294 }
295
296 pub fn is_empty(&self) -> bool {
298 self.len() == 0
299 }
300}
301
302#[cfg(test)]
303mod tests {
304 use super::*;
305
306 #[test]
307 fn test_null_buffer_builder() {
308 let mut builder = NullBufferBuilder::new(0);
309 builder.append_null();
310 builder.append_non_null();
311 builder.append_n_nulls(2);
312 builder.append_n_non_nulls(2);
313 assert_eq!(6, builder.len());
314 assert_eq!(64, builder.allocated_size());
315
316 let buf = builder.finish().unwrap();
317 assert_eq!(&[0b110010_u8], buf.validity());
318 }
319
320 #[test]
321 fn test_null_buffer_builder_all_nulls() {
322 let mut builder = NullBufferBuilder::new(0);
323 builder.append_null();
324 builder.append_n_nulls(2);
325 builder.append_slice(&[false, false, false]);
326 assert_eq!(6, builder.len());
327 assert_eq!(64, builder.allocated_size());
328
329 let buf = builder.finish().unwrap();
330 assert_eq!(&[0b0_u8], buf.validity());
331 }
332
333 #[test]
334 fn test_null_buffer_builder_no_null() {
335 let mut builder = NullBufferBuilder::new(0);
336 builder.append_non_null();
337 builder.append_n_non_nulls(2);
338 builder.append_slice(&[true, true, true]);
339 assert_eq!(6, builder.len());
340 assert_eq!(0, builder.allocated_size());
341
342 let buf = builder.finish();
343 assert!(buf.is_none());
344 }
345
346 #[test]
347 fn test_null_buffer_builder_reset() {
348 let mut builder = NullBufferBuilder::new(0);
349 builder.append_slice(&[true, false, true]);
350 builder.finish();
351 assert!(builder.is_empty());
352
353 builder.append_slice(&[true, true, true]);
354 assert!(builder.finish().is_none());
355 assert!(builder.is_empty());
356
357 builder.append_slice(&[true, true, false, true]);
358
359 let buf = builder.finish().unwrap();
360 assert_eq!(&[0b1011_u8], buf.validity());
361 }
362
363 #[test]
364 fn test_append_word_all_valid() {
365 let mut builder = NullBufferBuilder::new(0);
366 builder.append_word(u64::MAX, 64);
367 builder.append_word(0b0111, 3);
368
369 assert_eq!(builder.len(), 67);
370 assert_eq!(builder.allocated_size(), 0);
371 assert!(builder.finish().is_none());
372 }
373
374 #[test]
375 fn test_append_word_mixed() {
376 let mut builder = NullBufferBuilder::new(0);
377 builder.append_n_non_nulls(3);
378 builder.append_word(0b1100_1010, 6);
379 builder.append_word(0b1111, 4);
380
381 let buffer = builder.finish().unwrap();
382 assert_eq!(&[0b0101_0111, 0b0001_1110], buffer.validity());
383 }
384
385 #[test]
386 #[should_panic(expected = "count must be less than or equal to 64")]
387 fn test_append_word_count_too_large() {
388 let mut builder = NullBufferBuilder::new(0);
389 builder.append_word(u64::MAX, 65);
390 }
391
392 #[test]
393 fn test_null_buffer_builder_is_valid() {
394 let mut builder = NullBufferBuilder::new(0);
395 builder.append_n_non_nulls(6);
396 assert!(builder.is_valid(0));
397
398 builder.append_null();
399 assert!(!builder.is_valid(6));
400
401 builder.append_non_null();
402 assert!(builder.is_valid(7));
403 }
404
405 #[test]
406 fn test_null_buffer_builder_truncate() {
407 let mut builder = NullBufferBuilder::new(10);
408 builder.append_n_non_nulls(16);
409 assert_eq!(builder.as_slice(), None);
410 builder.truncate(20);
411 assert_eq!(builder.as_slice(), None);
412 assert_eq!(builder.len(), 16);
413 assert_eq!(builder.allocated_size(), 0);
414 builder.truncate(14);
415 assert_eq!(builder.as_slice(), None);
416 assert_eq!(builder.len(), 14);
417 builder.append_null();
418 builder.append_non_null();
419 assert_eq!(builder.as_slice().unwrap(), &[0xFF, 0b10111111]);
420 assert_eq!(builder.allocated_size(), 64);
421 }
422
423 #[test]
424 fn test_null_buffer_builder_truncate_never_materialized() {
425 let mut builder = NullBufferBuilder::new(0);
426 assert_eq!(builder.len(), 0);
427 builder.append_n_nulls(2); assert_eq!(builder.len(), 2);
429 builder.truncate(1);
430 assert_eq!(builder.len(), 1);
431 }
432
433 #[test]
434 fn test_append_buffers() {
435 let mut builder = NullBufferBuilder::new(0);
436 let buffer1 = NullBuffer::from(&[true, true]);
437 let buffer2 = NullBuffer::from(&[true, true, false]);
438
439 builder.append_buffer(&buffer1);
440 builder.append_buffer(&buffer2);
441
442 assert_eq!(builder.as_slice().unwrap(), &[0b01111_u8]);
443 }
444
445 #[test]
446 fn test_append_buffers_with_unaligned_length() {
447 let mut builder = NullBufferBuilder::new(0);
448 let buffer = NullBuffer::from(&[true, true, false, true, false]);
449 builder.append_buffer(&buffer);
450 assert_eq!(builder.as_slice().unwrap(), &[0b01011_u8]);
451
452 let buffer = NullBuffer::from(&[false, false, true, true, true, false, false]);
453 builder.append_buffer(&buffer);
454 assert_eq!(builder.as_slice().unwrap(), &[0b10001011_u8, 0b0011_u8]);
455 }
456
457 #[test]
458 fn test_append_empty_buffer() {
459 let mut builder = NullBufferBuilder::new(0);
460 let buffer = NullBuffer::from(&[true, true, false, true]);
461 builder.append_buffer(&buffer);
462 assert_eq!(builder.as_slice().unwrap(), &[0b1011_u8]);
463
464 let buffer = NullBuffer::from(&[]);
465 builder.append_buffer(&buffer);
466
467 assert_eq!(builder.as_slice().unwrap(), &[0b1011_u8]);
468 }
469
470 #[test]
471 fn test_should_not_materialize_when_appending_all_valid_buffers() {
472 let mut builder = NullBufferBuilder::new(0);
473 let buffer = NullBuffer::from(&[true; 10]);
474 builder.append_buffer(&buffer);
475
476 let buffer = NullBuffer::from(&[true; 2]);
477 builder.append_buffer(&buffer);
478
479 assert_eq!(builder.finish(), None);
480 }
481}