reifydb_type/value/container/
uuid.rs

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