1#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum Validity {
15 AllValid,
17 AllInvalid,
19 Mask(Bitmap),
21}
22
23impl Validity {
24 #[must_use]
29 pub fn is_valid(&self, index: usize) -> bool {
30 match self {
31 Self::AllValid => true,
32 Self::AllInvalid => false,
33 Self::Mask(mask) => mask.get(index),
34 }
35 }
36
37 #[must_use]
39 pub fn has_nulls(&self, len: usize) -> bool {
40 match self {
41 Self::AllValid => false,
42 Self::AllInvalid => len > 0,
43 Self::Mask(mask) => mask.count_valid(len) != len,
44 }
45 }
46
47 #[must_use]
49 pub fn count_valid(&self, len: usize) -> usize {
50 match self {
51 Self::AllValid => len,
52 Self::AllInvalid => 0,
53 Self::Mask(mask) => mask.count_valid(len),
54 }
55 }
56
57 #[must_use]
63 pub fn normalize(self, len: usize) -> Self {
64 match self {
65 Self::Mask(ref mask) => {
66 let valid = mask.count_valid(len);
67 if valid == len {
68 Self::AllValid
69 } else if valid == 0 {
70 Self::AllInvalid
71 } else {
72 self
73 }
74 }
75 other => other,
76 }
77 }
78
79 #[must_use]
84 pub fn with_null(self, index: usize, len: usize) -> Self {
85 let mut mask = match self {
86 Self::AllValid => Bitmap::all_valid(len),
87 Self::AllInvalid => return Self::AllInvalid,
88 Self::Mask(mask) => mask,
89 };
90 mask.set(index, false);
91 Self::Mask(mask)
92 }
93
94 pub fn from_iter(len: usize, valid: impl Fn(usize) -> bool) -> Self {
96 let mut mask = Bitmap::all_valid(len);
97 for index in 0..len {
98 if !valid(index) {
99 mask.set(index, false);
100 }
101 }
102 Self::Mask(mask).normalize(len)
103 }
104
105 #[must_use]
108 pub fn and(&self, other: &Self, len: usize) -> Self {
109 match (self, other) {
110 (Self::AllInvalid, _) | (_, Self::AllInvalid) => Self::AllInvalid,
111 (Self::AllValid, Self::AllValid) => Self::AllValid,
112 (Self::AllValid, right) => right.clone().normalize(len),
113 (left, Self::AllValid) => left.clone().normalize(len),
114 (Self::Mask(left), Self::Mask(right)) => {
115 let mut result = left.clone();
116 result.and_with(right);
117 Self::Mask(result).normalize(len)
118 }
119 }
120 }
121}
122
123#[derive(Debug, Clone, PartialEq, Eq)]
129pub struct Bitmap {
130 words: Vec<u64>,
131}
132
133impl Bitmap {
134 #[must_use]
136 pub fn all_valid(len: usize) -> Self {
137 Self { words: vec![u64::MAX; len.div_ceil(64)] }
138 }
139
140 #[must_use]
142 pub fn all_invalid(len: usize) -> Self {
143 Self { words: vec![0; len.div_ceil(64)] }
144 }
145
146 #[must_use]
148 pub fn get(&self, index: usize) -> bool {
149 let word = index / 64;
150 self.words.get(word).is_some_and(|w| w >> (index % 64) & 1 == 1)
151 }
152
153 pub fn set(&mut self, index: usize, valid: bool) {
155 let word = index / 64;
156 if word >= self.words.len() {
157 self.words.resize(word + 1, 0);
158 }
159 let bit = 1u64 << (index % 64);
160 if valid {
161 self.words[word] |= bit;
162 } else {
163 self.words[word] &= !bit;
164 }
165 }
166
167 #[must_use]
169 pub fn count_valid(&self, len: usize) -> usize {
170 let mut count = 0usize;
171 let full_words = len / 64;
172 for word in self.words.iter().take(full_words) {
173 count += word.count_ones() as usize;
174 }
175 let tail = len % 64;
176 if tail > 0 {
177 if let Some(word) = self.words.get(full_words) {
181 let keep = u64::MAX >> (64 - tail);
183 count += (word & keep).count_ones() as usize;
184 }
185 }
186 count
187 }
188
189 pub fn and_with(&mut self, other: &Self) {
191 for (index, word) in self.words.iter_mut().enumerate() {
192 *word &= other.words.get(index).copied().unwrap_or(0);
193 }
194 }
195}
196
197#[cfg(test)]
198mod tests {
199 use super::{Bitmap, Validity};
200
201 #[test]
202 fn the_three_cases_answer_the_same_question_the_same_way() {
203 let mut mask = Bitmap::all_valid(8);
204 assert!(Validity::AllValid.is_valid(3));
205 assert!(!Validity::AllInvalid.is_valid(3));
206 assert!(Validity::Mask(mask.clone()).is_valid(3));
207 mask.set(3, false);
208 assert!(!Validity::Mask(mask).is_valid(3));
209 }
210
211 #[test]
212 fn a_uniform_mask_collapses_to_the_flag_it_should_have_been() {
213 assert_eq!(Validity::Mask(Bitmap::all_valid(64)).normalize(64), Validity::AllValid);
216 assert_eq!(Validity::Mask(Bitmap::all_invalid(64)).normalize(64), Validity::AllInvalid);
217 let mut mask = Bitmap::all_valid(64);
218 mask.set(7, false);
219 assert!(matches!(Validity::Mask(mask).normalize(64), Validity::Mask(_)));
220 }
221
222 #[test]
223 fn counting_stops_at_the_length_and_not_at_the_word_boundary() {
224 let mask = Bitmap::all_valid(100);
228 assert_eq!(mask.count_valid(100), 100);
229 assert_eq!(mask.count_valid(65), 65);
230 assert_eq!(mask.count_valid(1), 1);
231 assert_eq!(mask.count_valid(0), 0);
232 }
233
234 #[test]
235 fn setting_a_null_on_an_all_valid_vector_materializes_a_mask() {
236 let validity = Validity::AllValid.with_null(5, 64);
237 assert!(!validity.is_valid(5));
238 assert!(validity.is_valid(4));
239 assert_eq!(validity.count_valid(64), 63);
240 assert!(validity.has_nulls(64));
241 }
242
243 #[test]
244 fn setting_a_null_on_an_all_invalid_vector_changes_nothing() {
245 assert_eq!(Validity::AllInvalid.with_null(5, 64), Validity::AllInvalid);
246 }
247
248 #[test]
249 fn intersection_short_circuits_on_the_flags() {
250 let mut left = Bitmap::all_valid(8);
251 left.set(0, false);
252 let mut right = Bitmap::all_valid(8);
253 right.set(1, false);
254 let both = Validity::Mask(left.clone()).and(&Validity::Mask(right), 8);
255 assert!(!both.is_valid(0));
256 assert!(!both.is_valid(1));
257 assert!(both.is_valid(2));
258 assert_eq!(both.count_valid(8), 6);
259
260 assert_eq!(Validity::AllValid.and(&Validity::AllValid, 8), Validity::AllValid);
261 assert_eq!(Validity::AllInvalid.and(&Validity::Mask(left), 8), Validity::AllInvalid);
262 }
263
264 #[test]
265 fn validity_from_a_predicate_normalizes_itself() {
266 assert_eq!(Validity::from_iter(16, |_| true), Validity::AllValid);
267 assert_eq!(Validity::from_iter(16, |_| false), Validity::AllInvalid);
268 let mixed = Validity::from_iter(16, |i| i % 2 == 0);
269 assert_eq!(mixed.count_valid(16), 8);
270 }
271}