arrow_buffer/builder/
null.rs1use crate::{BooleanBufferBuilder, MutableBuffer, NullBuffer};
19
20#[derive(Debug)]
27pub struct NullBufferBuilder {
28 bitmap_builder: Option<BooleanBufferBuilder>,
29 len: usize,
31 capacity: usize,
32}
33
34impl NullBufferBuilder {
35 pub fn new(capacity: usize) -> Self {
38 Self {
39 bitmap_builder: None,
40 len: 0,
41 capacity,
42 }
43 }
44
45 pub fn new_with_len(len: usize) -> Self {
47 Self {
48 bitmap_builder: None,
49 len,
50 capacity: len,
51 }
52 }
53
54 pub fn new_from_buffer(buffer: MutableBuffer, len: usize) -> Self {
56 let capacity = buffer.len() * 8;
57
58 assert!(len <= capacity);
59
60 let bitmap_builder = Some(BooleanBufferBuilder::new_from_buffer(buffer, len));
61 Self {
62 bitmap_builder,
63 len,
64 capacity,
65 }
66 }
67
68 #[inline]
71 pub fn append_n_non_nulls(&mut self, n: usize) {
72 if let Some(buf) = self.bitmap_builder.as_mut() {
73 buf.append_n(n, true)
74 } else {
75 self.len += n;
76 }
77 }
78
79 #[inline]
82 pub fn append_non_null(&mut self) {
83 if let Some(buf) = self.bitmap_builder.as_mut() {
84 buf.append(true)
85 } else {
86 self.len += 1;
87 }
88 }
89
90 #[inline]
93 pub fn append_n_nulls(&mut self, n: usize) {
94 self.materialize_if_needed();
95 self.bitmap_builder.as_mut().unwrap().append_n(n, false);
96 }
97
98 #[inline]
101 pub fn append_null(&mut self) {
102 self.materialize_if_needed();
103 self.bitmap_builder.as_mut().unwrap().append(false);
104 }
105
106 #[inline]
108 pub fn append(&mut self, not_null: bool) {
109 if not_null {
110 self.append_non_null()
111 } else {
112 self.append_null()
113 }
114 }
115
116 pub fn append_slice(&mut self, slice: &[bool]) {
119 if slice.iter().any(|v| !v) {
120 self.materialize_if_needed()
121 }
122 if let Some(buf) = self.bitmap_builder.as_mut() {
123 buf.append_slice(slice)
124 } else {
125 self.len += slice.len();
126 }
127 }
128
129 pub fn finish(&mut self) -> Option<NullBuffer> {
132 self.len = 0;
133 Some(NullBuffer::new(self.bitmap_builder.take()?.finish()))
134 }
135
136 pub fn finish_cloned(&self) -> Option<NullBuffer> {
138 let buffer = self.bitmap_builder.as_ref()?.finish_cloned();
139 Some(NullBuffer::new(buffer))
140 }
141
142 pub fn as_slice(&self) -> Option<&[u8]> {
144 Some(self.bitmap_builder.as_ref()?.as_slice())
145 }
146
147 fn materialize_if_needed(&mut self) {
148 if self.bitmap_builder.is_none() {
149 self.materialize()
150 }
151 }
152
153 #[cold]
154 fn materialize(&mut self) {
155 if self.bitmap_builder.is_none() {
156 let mut b = BooleanBufferBuilder::new(self.len.max(self.capacity));
157 b.append_n(self.len, true);
158 self.bitmap_builder = Some(b);
159 }
160 }
161
162 pub fn as_slice_mut(&mut self) -> Option<&mut [u8]> {
164 self.bitmap_builder.as_mut().map(|b| b.as_slice_mut())
165 }
166
167 pub fn allocated_size(&self) -> usize {
169 self.bitmap_builder
170 .as_ref()
171 .map(|b| b.capacity())
172 .unwrap_or(0)
173 }
174}
175
176impl NullBufferBuilder {
177 pub fn len(&self) -> usize {
179 self.bitmap_builder.as_ref().map_or(self.len, |b| b.len())
180 }
181
182 pub fn is_empty(&self) -> bool {
184 self.len() == 0
185 }
186}
187
188#[cfg(test)]
189mod tests {
190 use super::*;
191
192 #[test]
193 fn test_null_buffer_builder() {
194 let 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);
199 assert_eq!(6, builder.len());
200
201 let buf = builder.finish().unwrap();
202 assert_eq!(&[0b110010_u8], buf.validity());
203 }
204
205 #[test]
206 fn test_null_buffer_builder_all_nulls() {
207 let mut builder = NullBufferBuilder::new(0);
208 builder.append_null();
209 builder.append_n_nulls(2);
210 builder.append_slice(&[false, false, false]);
211 assert_eq!(6, builder.len());
212
213 let buf = builder.finish().unwrap();
214 assert_eq!(&[0b0_u8], buf.validity());
215 }
216
217 #[test]
218 fn test_null_buffer_builder_no_null() {
219 let mut builder = NullBufferBuilder::new(0);
220 builder.append_non_null();
221 builder.append_n_non_nulls(2);
222 builder.append_slice(&[true, true, true]);
223 assert_eq!(6, builder.len());
224
225 let buf = builder.finish();
226 assert!(buf.is_none());
227 }
228
229 #[test]
230 fn test_null_buffer_builder_reset() {
231 let mut builder = NullBufferBuilder::new(0);
232 builder.append_slice(&[true, false, true]);
233 builder.finish();
234 assert!(builder.is_empty());
235
236 builder.append_slice(&[true, true, true]);
237 assert!(builder.finish().is_none());
238 assert!(builder.is_empty());
239
240 builder.append_slice(&[true, true, false, true]);
241
242 let buf = builder.finish().unwrap();
243 assert_eq!(&[0b1011_u8], buf.validity());
244 }
245}