arrow_buffer/builder/
null.rs1use crate::{BooleanBufferBuilder, MutableBuffer, NullBuffer};
19
20#[derive(Debug)]
50pub struct NullBufferBuilder {
51 bitmap_builder: Option<BooleanBufferBuilder>,
55 len: usize,
59 capacity: usize,
61}
62
63impl NullBufferBuilder {
64 pub fn new(capacity: usize) -> Self {
70 Self {
71 bitmap_builder: None,
72 len: 0,
73 capacity,
74 }
75 }
76
77 pub fn new_with_len(len: usize) -> Self {
79 Self {
80 bitmap_builder: None,
81 len,
82 capacity: len,
83 }
84 }
85
86 pub fn new_from_buffer(buffer: MutableBuffer, len: usize) -> Self {
88 let capacity = buffer.len() * 8;
89 assert!(len <= capacity);
90
91 let bitmap_builder = Some(BooleanBufferBuilder::new_from_buffer(buffer, len));
92 Self {
93 bitmap_builder,
94 len,
95 capacity,
96 }
97 }
98
99 #[inline]
102 pub fn append_n_non_nulls(&mut self, n: usize) {
103 if let Some(buf) = self.bitmap_builder.as_mut() {
104 buf.append_n(n, true)
105 } else {
106 self.len += n;
107 }
108 }
109
110 #[inline]
113 pub fn append_non_null(&mut self) {
114 if let Some(buf) = self.bitmap_builder.as_mut() {
115 buf.append(true)
116 } else {
117 self.len += 1;
118 }
119 }
120
121 #[inline]
124 pub fn append_n_nulls(&mut self, n: usize) {
125 self.materialize_if_needed();
126 self.bitmap_builder.as_mut().unwrap().append_n(n, false);
127 }
128
129 #[inline]
132 pub fn append_null(&mut self) {
133 self.materialize_if_needed();
134 self.bitmap_builder.as_mut().unwrap().append(false);
135 }
136
137 #[inline]
139 pub fn append(&mut self, not_null: bool) {
140 if not_null {
141 self.append_non_null()
142 } else {
143 self.append_null()
144 }
145 }
146
147 #[inline]
149 pub fn is_valid(&self, index: usize) -> bool {
150 if let Some(ref buf) = self.bitmap_builder {
151 buf.get_bit(index)
152 } else {
153 true
154 }
155 }
156
157 #[inline]
161 pub fn truncate(&mut self, len: usize) {
162 if let Some(buf) = self.bitmap_builder.as_mut() {
163 buf.truncate(len);
164 } else if len <= self.len {
165 self.len = len
166 }
167 }
168
169 pub fn append_slice(&mut self, slice: &[bool]) {
172 if slice.iter().any(|v| !v) {
173 self.materialize_if_needed()
174 }
175 if let Some(buf) = self.bitmap_builder.as_mut() {
176 buf.append_slice(slice)
177 } else {
178 self.len += slice.len();
179 }
180 }
181
182 pub fn finish(&mut self) -> Option<NullBuffer> {
185 self.len = 0;
186 Some(NullBuffer::new(self.bitmap_builder.take()?.finish()))
187 }
188
189 pub fn finish_cloned(&self) -> Option<NullBuffer> {
191 let buffer = self.bitmap_builder.as_ref()?.finish_cloned();
192 Some(NullBuffer::new(buffer))
193 }
194
195 pub fn as_slice(&self) -> Option<&[u8]> {
197 Some(self.bitmap_builder.as_ref()?.as_slice())
198 }
199
200 fn materialize_if_needed(&mut self) {
201 if self.bitmap_builder.is_none() {
202 self.materialize()
203 }
204 }
205
206 #[cold]
207 fn materialize(&mut self) {
208 if self.bitmap_builder.is_none() {
209 let mut b = BooleanBufferBuilder::new(self.len.max(self.capacity));
210 b.append_n(self.len, true);
211 self.bitmap_builder = Some(b);
212 }
213 }
214
215 pub fn as_slice_mut(&mut self) -> Option<&mut [u8]> {
217 self.bitmap_builder.as_mut().map(|b| b.as_slice_mut())
218 }
219
220 pub fn allocated_size(&self) -> usize {
222 self.bitmap_builder
223 .as_ref()
224 .map(|b| b.capacity() / 8)
225 .unwrap_or(0)
226 }
227}
228
229impl NullBufferBuilder {
230 pub fn len(&self) -> usize {
232 self.bitmap_builder.as_ref().map_or(self.len, |b| b.len())
233 }
234
235 pub fn is_empty(&self) -> bool {
237 self.len() == 0
238 }
239}
240
241#[cfg(test)]
242mod tests {
243 use super::*;
244
245 #[test]
246 fn test_null_buffer_builder() {
247 let mut builder = NullBufferBuilder::new(0);
248 builder.append_null();
249 builder.append_non_null();
250 builder.append_n_nulls(2);
251 builder.append_n_non_nulls(2);
252 assert_eq!(6, builder.len());
253 assert_eq!(64, builder.allocated_size());
254
255 let buf = builder.finish().unwrap();
256 assert_eq!(&[0b110010_u8], buf.validity());
257 }
258
259 #[test]
260 fn test_null_buffer_builder_all_nulls() {
261 let mut builder = NullBufferBuilder::new(0);
262 builder.append_null();
263 builder.append_n_nulls(2);
264 builder.append_slice(&[false, false, false]);
265 assert_eq!(6, builder.len());
266 assert_eq!(64, builder.allocated_size());
267
268 let buf = builder.finish().unwrap();
269 assert_eq!(&[0b0_u8], buf.validity());
270 }
271
272 #[test]
273 fn test_null_buffer_builder_no_null() {
274 let mut builder = NullBufferBuilder::new(0);
275 builder.append_non_null();
276 builder.append_n_non_nulls(2);
277 builder.append_slice(&[true, true, true]);
278 assert_eq!(6, builder.len());
279 assert_eq!(0, builder.allocated_size());
280
281 let buf = builder.finish();
282 assert!(buf.is_none());
283 }
284
285 #[test]
286 fn test_null_buffer_builder_reset() {
287 let mut builder = NullBufferBuilder::new(0);
288 builder.append_slice(&[true, false, true]);
289 builder.finish();
290 assert!(builder.is_empty());
291
292 builder.append_slice(&[true, true, true]);
293 assert!(builder.finish().is_none());
294 assert!(builder.is_empty());
295
296 builder.append_slice(&[true, true, false, true]);
297
298 let buf = builder.finish().unwrap();
299 assert_eq!(&[0b1011_u8], buf.validity());
300 }
301
302 #[test]
303 fn test_null_buffer_builder_is_valid() {
304 let mut builder = NullBufferBuilder::new(0);
305 builder.append_n_non_nulls(6);
306 assert!(builder.is_valid(0));
307
308 builder.append_null();
309 assert!(!builder.is_valid(6));
310
311 builder.append_non_null();
312 assert!(builder.is_valid(7));
313 }
314
315 #[test]
316 fn test_null_buffer_builder_truncate() {
317 let mut builder = NullBufferBuilder::new(10);
318 builder.append_n_non_nulls(16);
319 assert_eq!(builder.as_slice(), None);
320 builder.truncate(20);
321 assert_eq!(builder.as_slice(), None);
322 assert_eq!(builder.len(), 16);
323 assert_eq!(builder.allocated_size(), 0);
324 builder.truncate(14);
325 assert_eq!(builder.as_slice(), None);
326 assert_eq!(builder.len(), 14);
327 builder.append_null();
328 builder.append_non_null();
329 assert_eq!(builder.as_slice().unwrap(), &[0xFF, 0b10111111]);
330 assert_eq!(builder.allocated_size(), 64);
331 }
332
333 #[test]
334 fn test_null_buffer_builder_truncate_never_materialized() {
335 let mut builder = NullBufferBuilder::new(0);
336 assert_eq!(builder.len(), 0);
337 builder.append_n_nulls(2); assert_eq!(builder.len(), 2);
339 builder.truncate(1);
340 assert_eq!(builder.len(), 1);
341 }
342}