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