• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vortex-data / vortex / 16992684502

15 Aug 2025 02:56PM UTC coverage: 87.875% (+0.2%) from 87.72%
16992684502

Pull #2456

github

web-flow
Merge 2d540e578 into 4a23f65b3
Pull Request #2456: feat: basic BoolBuffer / BoolBufferMut

1275 of 1428 new or added lines in 110 files covered. (89.29%)

334 existing lines in 31 files now uncovered.

57169 of 65057 relevant lines covered (87.88%)

658056.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

73.21
/vortex-array/src/builders/lazy_validity_builder.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3

4
use vortex_buffer::{BitBuffer, BitBufferMut};
5
use vortex_dtype::Nullability;
6
use vortex_dtype::Nullability::{NonNullable, Nullable};
7
use vortex_error::{VortexExpect, vortex_panic};
8
use vortex_mask::Mask;
9

10
use crate::validity::Validity;
11

12
/// This is borrowed from arrow's null buffer builder, however we expose a `append_buffer`
13
/// method to append a boolean buffer directly.
14
pub struct LazyBitBufferBuilder {
15
    inner: Option<BitBufferMut>,
16
    len: usize,
17
    capacity: usize,
18
}
19

20
impl LazyBitBufferBuilder {
21
    /// Creates a new empty builder.
22
    /// `capacity` is the number of bits in the null buffer.
23
    pub fn new(capacity: usize) -> Self {
147,659✔
24
        Self {
147,659✔
25
            inner: None,
147,659✔
26
            len: 0,
147,659✔
27
            capacity,
147,659✔
28
        }
147,659✔
29
    }
147,659✔
30

31
    #[inline]
32
    pub fn append_n_non_nulls(&mut self, n: usize) {
137,434✔
33
        if let Some(buf) = self.inner.as_mut() {
137,434✔
34
            buf.append_n(true, n)
101✔
35
        } else {
137,333✔
36
            self.len += n;
137,333✔
37
        }
137,333✔
38
    }
137,434✔
39

40
    #[inline]
41
    pub fn append_non_null(&mut self) {
3,731,329✔
42
        if let Some(buf) = self.inner.as_mut() {
3,731,329✔
43
            buf.append(true)
2,208✔
44
        } else {
3,729,121✔
45
            self.len += 1;
3,729,121✔
46
        }
3,729,121✔
47
    }
3,731,329✔
48

49
    #[inline]
50
    pub fn append_n_nulls(&mut self, n: usize) {
2,397✔
51
        self.materialize_if_needed();
2,397✔
52
        self.inner
2,397✔
53
            .as_mut()
2,397✔
54
            .vortex_expect("cannot append null to non-nullable builder")
2,397✔
55
            .append_n(false, n);
2,397✔
56
    }
2,397✔
57

58
    #[inline]
59
    pub fn append_null(&mut self) {
156✔
60
        self.materialize_if_needed();
156✔
61
        self.inner
156✔
62
            .as_mut()
156✔
63
            .vortex_expect("cannot append null to non-nullable builder")
156✔
64
            .append(false);
156✔
65
    }
156✔
66

67
    #[inline]
68
    pub fn append(&mut self, not_null: bool) {
46,834✔
69
        if not_null {
46,834✔
70
            self.append_non_null()
46,834✔
71
        } else {
72
            self.append_null()
×
73
        }
74
    }
46,834✔
75

76
    #[inline]
77
    pub fn append_buffer(&mut self, bool_buffer: &BitBuffer) {
11,075✔
78
        self.materialize_if_needed();
11,075✔
79
        self.inner
11,075✔
80
            .as_mut()
11,075✔
81
            .vortex_expect("buffer just materialized")
11,075✔
82
            .append_buffer(bool_buffer);
11,075✔
83
    }
11,075✔
84

85
    pub fn append_validity_mask(&mut self, validity_mask: Mask) {
140,519✔
86
        match validity_mask {
140,519✔
87
            Mask::AllTrue(len) => self.append_n_non_nulls(len),
129,444✔
88
            Mask::AllFalse(len) => self.append_n_nulls(len),
×
89
            Mask::Values(is_valid) => self.append_buffer(is_valid.bit_buffer()),
11,075✔
90
        }
91
    }
140,519✔
92

93
    pub fn set_bit(&mut self, index: usize, v: bool) {
×
94
        self.materialize_if_needed();
×
95
        self.inner
×
96
            .as_mut()
×
97
            .vortex_expect("buffer just materialized")
×
NEW
98
            .set_to(index, v);
×
99
    }
×
100

101
    pub fn len(&self) -> usize {
38,106✔
102
        // self.len is the length of the builder if the inner buffer is not materialized
103
        self.inner.as_ref().map(|i| i.len()).unwrap_or(self.len)
38,106✔
104
    }
38,106✔
105

106
    pub fn truncate(&mut self, len: usize) {
×
107
        if let Some(b) = self.inner.as_mut() {
×
108
            b.truncate(len)
×
109
        }
×
110
        self.len = len;
×
111
    }
×
112

113
    pub fn reserve(&mut self, n: usize) {
×
114
        self.materialize_if_needed();
×
115
        self.inner
×
116
            .as_mut()
×
117
            .vortex_expect("buffer just materialized")
×
118
            .reserve(n);
×
119
    }
×
120

121
    fn finish(&mut self) -> Option<BitBuffer> {
147,556✔
122
        self.len = 0;
147,556✔
123
        self.inner.take().map(|b| b.freeze())
147,556✔
124
    }
147,556✔
125

126
    pub fn finish_with_nullability(&mut self, nullability: Nullability) -> Validity {
147,556✔
127
        let nulls = self.finish();
147,556✔
128

129
        match (nullability, nulls) {
147,556✔
130
            (NonNullable, None) => Validity::NonNullable,
107,558✔
131
            (Nullable, None) => Validity::AllValid,
29,667✔
132
            (Nullable, Some(arr)) => Validity::from(arr),
10,331✔
133
            _ => vortex_panic!("Invalid nullability/nulls combination"),
×
134
        }
135
    }
147,556✔
136

137
    pub fn ensure_capacity(&mut self, capacity: usize) {
14✔
138
        if self.inner.is_none() {
14✔
139
            self.capacity = capacity;
14✔
140
        } else {
14✔
141
            let inner = self
×
142
                .inner
×
143
                .as_mut()
×
144
                .vortex_expect("buffer just materialized");
×
145
            if capacity < inner.capacity() {
×
146
                inner.reserve(capacity - inner.len());
×
147
            }
×
148
        }
149
    }
14✔
150

151
    #[inline]
152
    fn materialize_if_needed(&mut self) {
13,628✔
153
        if self.inner.is_none() {
13,628✔
154
            self.materialize()
10,331✔
155
        }
3,297✔
156
    }
13,628✔
157

158
    // This only happens once per builder
159
    #[cold]
160
    #[inline(never)]
161
    fn materialize(&mut self) {
10,331✔
162
        if self.inner.is_none() {
10,331✔
163
            let mut bit_mut = BitBufferMut::new(self.len.max(self.capacity));
10,331✔
164
            bit_mut.append_n(true, self.len);
10,331✔
165
            self.inner = Some(bit_mut);
10,331✔
166
        }
10,331✔
167
    }
10,331✔
168
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc