reifydb_type/value/container/
bool.rs

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