vortex_array/builders/
lazy_validity_builder.rs1use arrow_buffer::{BooleanBuffer, BooleanBufferBuilder, NullBuffer};
2use vortex_dtype::Nullability;
3use vortex_dtype::Nullability::{NonNullable, Nullable};
4use vortex_error::{VortexExpect, vortex_panic};
5use vortex_mask::Mask;
6
7use crate::validity::Validity;
8
9pub struct LazyNullBufferBuilder {
12 inner: Option<BooleanBufferBuilder>,
13 len: usize,
14 capacity: usize,
15}
16
17impl LazyNullBufferBuilder {
18 pub fn new(capacity: usize) -> Self {
21 Self {
22 inner: None,
23 len: 0,
24 capacity,
25 }
26 }
27
28 #[inline]
29 pub fn append_n_non_nulls(&mut self, n: usize) {
30 if let Some(buf) = self.inner.as_mut() {
31 buf.append_n(n, true)
32 } else {
33 self.len += n;
34 }
35 }
36
37 #[inline]
38 pub fn append_non_null(&mut self) {
39 if let Some(buf) = self.inner.as_mut() {
40 buf.append(true)
41 } else {
42 self.len += 1;
43 }
44 }
45
46 #[inline]
47 pub fn append_n_nulls(&mut self, n: usize) {
48 self.materialize_if_needed();
49 self.inner
50 .as_mut()
51 .vortex_expect("cannot append null to non-nullable builder")
52 .append_n(n, false);
53 }
54
55 #[inline]
56 pub fn append_null(&mut self) {
57 self.materialize_if_needed();
58 self.inner
59 .as_mut()
60 .vortex_expect("cannot append null to non-nullable builder")
61 .append(false);
62 }
63
64 #[inline]
65 pub fn append(&mut self, not_null: bool) {
66 if not_null {
67 self.append_non_null()
68 } else {
69 self.append_null()
70 }
71 }
72
73 #[inline]
74 pub fn append_buffer(&mut self, bool_buffer: &BooleanBuffer) {
75 self.materialize_if_needed();
76 self.inner
77 .as_mut()
78 .vortex_expect("buffer just materialized")
79 .append_buffer(bool_buffer);
80 }
81
82 pub fn append_validity_mask(&mut self, validity_mask: Mask) {
83 match validity_mask {
84 Mask::AllTrue(len) => self.append_n_non_nulls(len),
85 Mask::AllFalse(len) => self.append_n_nulls(len),
86 Mask::Values(is_valid) => self.append_buffer(is_valid.boolean_buffer()),
87 }
88 }
89
90 pub fn set_bit(&mut self, index: usize, v: bool) {
91 self.materialize_if_needed();
92 self.inner
93 .as_mut()
94 .vortex_expect("buffer just materialized")
95 .set_bit(index, v);
96 }
97
98 pub fn len(&self) -> usize {
99 self.inner.as_ref().map(|i| i.len()).unwrap_or(self.len)
101 }
102
103 pub fn truncate(&mut self, len: usize) {
104 if let Some(b) = self.inner.as_mut() {
105 b.truncate(len)
106 }
107 self.len = len;
108 }
109
110 pub fn reserve(&mut self, n: usize) {
111 self.materialize_if_needed();
112 self.inner
113 .as_mut()
114 .vortex_expect("buffer just materialized")
115 .reserve(n);
116 }
117
118 pub fn finish(&mut self) -> Option<NullBuffer> {
119 self.len = 0;
120 Some(NullBuffer::new(self.inner.take()?.finish()))
121 }
122
123 pub fn finish_with_nullability(&mut self, nullability: Nullability) -> Validity {
124 let nulls = self.finish();
125 match (nullability, nulls) {
126 (NonNullable, None) => Validity::NonNullable,
127 (Nullable, None) => Validity::AllValid,
128 (Nullable, Some(arr)) => Validity::from(arr),
129 _ => vortex_panic!("Invalid nullability/nulls combination"),
130 }
131 }
132
133 pub fn ensure_capacity(&mut self, capacity: usize) {
134 if self.inner.is_none() {
135 self.capacity = capacity;
136 } else {
137 let inner = self
138 .inner
139 .as_mut()
140 .vortex_expect("buffer just materialized");
141 if capacity < inner.capacity() {
142 inner.reserve(capacity - inner.len());
143 }
144 }
145 }
146
147 #[inline]
148 fn materialize_if_needed(&mut self) {
149 if self.inner.is_none() {
150 self.materialize()
151 }
152 }
153
154 #[cold]
156 #[inline(never)]
157 fn materialize(&mut self) {
158 if self.inner.is_none() {
159 let mut b = BooleanBufferBuilder::new(self.len.max(self.capacity));
160 b.append_n(self.len, true);
161 self.inner = Some(b);
162 }
163 }
164}