reifydb_core/value/container/
bool.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use std::ops::Deref;
5
6use reifydb_type::Value;
7use serde::{Deserialize, Serialize};
8
9use crate::BitVec;
10
11#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
12pub struct BoolContainer {
13	data: BitVec,
14	bitvec: BitVec,
15}
16
17impl BoolContainer {
18	pub fn new(data: Vec<bool>, bitvec: BitVec) -> Self {
19		debug_assert_eq!(data.len(), bitvec.len());
20		Self {
21			data: BitVec::from_slice(&data),
22			bitvec,
23		}
24	}
25
26	pub fn with_capacity(capacity: usize) -> Self {
27		Self {
28			data: BitVec::with_capacity(capacity),
29			bitvec: BitVec::with_capacity(capacity),
30		}
31	}
32
33	pub fn from_vec(data: Vec<bool>) -> Self {
34		let len = data.len();
35		Self {
36			data: BitVec::from_slice(&data),
37			bitvec: BitVec::repeat(len, true),
38		}
39	}
40
41	pub fn len(&self) -> usize {
42		debug_assert_eq!(self.data.len(), self.bitvec.len());
43		self.data.len()
44	}
45
46	pub fn capacity(&self) -> usize {
47		debug_assert!(self.data.capacity() >= self.bitvec.capacity());
48		self.data.capacity().min(self.bitvec.capacity())
49	}
50
51	pub fn is_empty(&self) -> bool {
52		self.data.len() == 0
53	}
54
55	pub fn push(&mut self, value: bool) {
56		self.data.push(value);
57		self.bitvec.push(true);
58	}
59
60	pub fn push_undefined(&mut self) {
61		self.data.push(false);
62		self.bitvec.push(false);
63	}
64
65	pub fn get(&self, index: usize) -> Option<bool> {
66		if index < self.len() && self.is_defined(index) {
67			Some(self.data.get(index))
68		} else {
69			None
70		}
71	}
72
73	pub fn bitvec(&self) -> &BitVec {
74		&self.bitvec
75	}
76
77	pub fn bitvec_mut(&mut self) -> &mut BitVec {
78		&mut self.bitvec
79	}
80
81	pub fn is_defined(&self, idx: usize) -> bool {
82		idx < self.len() && self.bitvec.get(idx)
83	}
84
85	pub fn is_fully_defined(&self) -> bool {
86		self.bitvec.count_ones() == self.len()
87	}
88
89	pub fn data(&self) -> &BitVec {
90		&self.data
91	}
92
93	pub fn data_mut(&mut self) -> &mut BitVec {
94		&mut self.data
95	}
96
97	pub fn as_string(&self, index: usize) -> String {
98		if index < self.len() && self.is_defined(index) {
99			self.data.get(index).to_string()
100		} else {
101			"Undefined".to_string()
102		}
103	}
104
105	pub fn get_value(&self, index: usize) -> Value {
106		if index < self.len() && self.is_defined(index) {
107			Value::Boolean(self.data.get(index))
108		} else {
109			Value::Undefined
110		}
111	}
112
113	pub fn extend(&mut self, other: &Self) -> crate::Result<()> {
114		self.data.extend(&other.data);
115		self.bitvec.extend(&other.bitvec);
116		Ok(())
117	}
118
119	pub fn extend_from_undefined(&mut self, len: usize) {
120		self.data.extend(&BitVec::repeat(len, false));
121		self.bitvec.extend(&BitVec::repeat(len, false));
122	}
123
124	pub fn iter(&self) -> impl Iterator<Item = Option<bool>> + '_ {
125		self.data.iter().zip(self.bitvec.iter()).map(|(v, defined)| {
126			if defined {
127				Some(v)
128			} else {
129				None
130			}
131		})
132	}
133
134	pub fn into_iter(self) -> impl Iterator<Item = Option<bool>> {
135		let data: Vec<bool> = self.data.iter().collect();
136		let bitvec: Vec<bool> = self.bitvec.iter().collect();
137		data.into_iter().zip(bitvec).map(|(v, defined)| {
138			if defined {
139				Some(v)
140			} else {
141				None
142			}
143		})
144	}
145
146	pub fn slice(&self, start: usize, end: usize) -> Self {
147		let new_data: Vec<bool> = self.data.iter().skip(start).take(end - start).collect();
148		let new_bitvec: Vec<bool> = self.bitvec.iter().skip(start).take(end - start).collect();
149		Self {
150			data: BitVec::from_slice(&new_data),
151			bitvec: BitVec::from_slice(&new_bitvec),
152		}
153	}
154
155	pub fn filter(&mut self, mask: &BitVec) {
156		let mut new_data = BitVec::with_capacity(mask.count_ones());
157		let mut new_bitvec = BitVec::with_capacity(mask.count_ones());
158
159		for (i, keep) in mask.iter().enumerate() {
160			if keep && i < self.len() {
161				new_data.push(self.data.get(i));
162				new_bitvec.push(self.bitvec.get(i));
163			}
164		}
165
166		self.data = new_data;
167		self.bitvec = new_bitvec;
168	}
169
170	pub fn reorder(&mut self, indices: &[usize]) {
171		let mut new_data = BitVec::with_capacity(indices.len());
172		let mut new_bitvec = BitVec::with_capacity(indices.len());
173
174		for &idx in indices {
175			if idx < self.len() {
176				new_data.push(self.data.get(idx));
177				new_bitvec.push(self.bitvec.get(idx));
178			} else {
179				new_data.push(false);
180				new_bitvec.push(false);
181			}
182		}
183
184		self.data = new_data;
185		self.bitvec = new_bitvec;
186	}
187
188	pub fn take(&self, num: usize) -> Self {
189		Self {
190			data: self.data.take(num),
191			bitvec: self.bitvec.take(num),
192		}
193	}
194}
195
196impl Deref for BoolContainer {
197	type Target = BitVec;
198
199	fn deref(&self) -> &Self::Target {
200		&self.data
201	}
202}
203
204impl Default for BoolContainer {
205	fn default() -> Self {
206		Self::with_capacity(0)
207	}
208}
209
210#[cfg(test)]
211mod tests {
212	use super::*;
213	use crate::BitVec;
214
215	#[test]
216	fn test_new() {
217		let data = vec![true, false, true];
218		let bitvec = BitVec::from_slice(&[true, true, true]);
219		let container = BoolContainer::new(data.clone(), bitvec);
220
221		assert_eq!(container.len(), 3);
222		assert_eq!(container.get(0), Some(true));
223		assert_eq!(container.get(1), Some(false));
224		assert_eq!(container.get(2), Some(true));
225	}
226
227	#[test]
228	fn test_from_vec() {
229		let data = vec![true, false, true];
230		let container = BoolContainer::from_vec(data);
231
232		assert_eq!(container.len(), 3);
233		assert_eq!(container.get(0), Some(true));
234		assert_eq!(container.get(1), Some(false));
235		assert_eq!(container.get(2), Some(true));
236
237		// All should be defined
238		for i in 0..3 {
239			assert!(container.is_defined(i));
240		}
241	}
242
243	#[test]
244	fn test_with_capacity() {
245		let container = BoolContainer::with_capacity(10);
246		assert_eq!(container.len(), 0);
247		assert!(container.is_empty());
248		assert!(container.capacity() >= 10);
249	}
250
251	#[test]
252	fn test_push() {
253		let mut container = BoolContainer::with_capacity(3);
254
255		container.push(true);
256		container.push(false);
257		container.push_undefined();
258
259		assert_eq!(container.len(), 3);
260		assert_eq!(container.get(0), Some(true));
261		assert_eq!(container.get(1), Some(false));
262		assert_eq!(container.get(2), None); // undefined
263
264		assert!(container.is_defined(0));
265		assert!(container.is_defined(1));
266		assert!(!container.is_defined(2));
267	}
268
269	#[test]
270	fn test_extend() {
271		let mut container1 = BoolContainer::from_vec(vec![true, false]);
272		let container2 = BoolContainer::from_vec(vec![false, true]);
273
274		container1.extend(&container2).unwrap();
275
276		assert_eq!(container1.len(), 4);
277		assert_eq!(container1.get(0), Some(true));
278		assert_eq!(container1.get(1), Some(false));
279		assert_eq!(container1.get(2), Some(false));
280		assert_eq!(container1.get(3), Some(true));
281	}
282
283	#[test]
284	fn test_iter() {
285		let data = vec![true, false, true];
286		let bitvec = BitVec::from_slice(&[true, false, true]); // middle value undefined
287		let container = BoolContainer::new(data, bitvec);
288
289		let collected: Vec<Option<bool>> = container.iter().collect();
290		assert_eq!(collected, vec![Some(true), None, Some(true)]);
291	}
292
293	#[test]
294	fn test_slice() {
295		let container = BoolContainer::from_vec(vec![true, false, true, false]);
296		let sliced = container.slice(1, 3);
297
298		assert_eq!(sliced.len(), 2);
299		assert_eq!(sliced.get(0), Some(false));
300		assert_eq!(sliced.get(1), Some(true));
301	}
302
303	#[test]
304	fn test_filter() {
305		let mut container = BoolContainer::from_vec(vec![true, false, true, false]);
306		let mask = BitVec::from_slice(&[true, false, true, false]);
307
308		container.filter(&mask);
309
310		assert_eq!(container.len(), 2);
311		assert_eq!(container.get(0), Some(true));
312		assert_eq!(container.get(1), Some(true));
313	}
314
315	#[test]
316	fn test_reorder() {
317		let mut container = BoolContainer::from_vec(vec![true, false, true]);
318		let indices = [2, 0, 1];
319
320		container.reorder(&indices);
321
322		assert_eq!(container.len(), 3);
323		assert_eq!(container.get(0), Some(true)); // was index 2
324		assert_eq!(container.get(1), Some(true)); // was index 0
325		assert_eq!(container.get(2), Some(false)); // was index 1
326	}
327
328	#[test]
329	fn test_reorder_with_out_of_bounds() {
330		let mut container = BoolContainer::from_vec(vec![true, false]);
331		let indices = [1, 5, 0]; // index 5 is out of bounds
332
333		container.reorder(&indices);
334
335		assert_eq!(container.len(), 3);
336		assert_eq!(container.get(0), Some(false)); // was index 1
337		assert_eq!(container.get(1), None); // out of bounds -> undefined
338		assert_eq!(container.get(2), Some(true)); // was index 0
339	}
340
341	#[test]
342	fn test_default() {
343		let container = BoolContainer::default();
344		assert_eq!(container.len(), 0);
345		assert!(container.is_empty());
346	}
347}