reifydb_type/value/container/
number.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the MIT, see license.md file
3
4use std::{
5	any::TypeId,
6	fmt::Debug,
7	mem::{forget, transmute_copy},
8	ops::Deref,
9};
10
11use serde::{Deserialize, Serialize};
12
13use crate::{
14	BitVec, CowVec, Decimal, Int, IsNumber, OrderedF32, OrderedF64, Uint, Value,
15	Value::{Int1, Int2, Int4, Int8, Int16, Uint1, Uint2, Uint4, Uint8, Uint16, Undefined},
16};
17
18#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
19pub struct NumberContainer<T>
20where
21	T: IsNumber,
22{
23	data: CowVec<T>,
24	bitvec: BitVec,
25}
26
27impl<T> Deref for NumberContainer<T>
28where
29	T: IsNumber,
30{
31	type Target = [T];
32
33	fn deref(&self) -> &Self::Target {
34		self.data.as_slice()
35	}
36}
37
38impl<T> NumberContainer<T>
39where
40	T: IsNumber + Clone + Debug + Default,
41{
42	pub fn new(data: Vec<T>, bitvec: BitVec) -> Self {
43		debug_assert_eq!(data.len(), bitvec.len());
44		Self {
45			data: CowVec::new(data),
46			bitvec,
47		}
48	}
49
50	pub fn with_capacity(capacity: usize) -> Self {
51		Self {
52			data: CowVec::with_capacity(capacity),
53			bitvec: BitVec::with_capacity(capacity),
54		}
55	}
56
57	pub fn from_vec(data: Vec<T>) -> Self {
58		let len = data.len();
59		Self {
60			data: CowVec::new(data),
61			bitvec: BitVec::repeat(len, true),
62		}
63	}
64
65	pub fn len(&self) -> usize {
66		debug_assert_eq!(self.data.len(), self.bitvec.len());
67		self.data.len()
68	}
69
70	pub fn capacity(&self) -> usize {
71		debug_assert!(self.data.capacity() >= self.bitvec.capacity());
72		self.data.capacity().min(self.bitvec.capacity())
73	}
74
75	pub fn is_empty(&self) -> bool {
76		self.data.is_empty()
77	}
78
79	pub fn push(&mut self, value: T) {
80		self.data.push(value);
81		self.bitvec.push(true);
82	}
83
84	pub fn push_undefined(&mut self) {
85		self.data.push(T::default());
86		self.bitvec.push(false);
87	}
88
89	pub fn get(&self, index: usize) -> Option<&T> {
90		if index < self.len() && self.is_defined(index) {
91			self.data.get(index)
92		} else {
93			None
94		}
95	}
96
97	pub fn bitvec(&self) -> &BitVec {
98		&self.bitvec
99	}
100
101	pub fn bitvec_mut(&mut self) -> &mut BitVec {
102		&mut self.bitvec
103	}
104
105	pub fn is_defined(&self, idx: usize) -> bool {
106		idx < self.len() && self.bitvec.get(idx)
107	}
108
109	pub fn is_fully_defined(&self) -> bool {
110		self.bitvec.count_ones() == self.len()
111	}
112
113	pub fn data(&self) -> &CowVec<T> {
114		&self.data
115	}
116
117	pub fn data_mut(&mut self) -> &mut CowVec<T> {
118		&mut self.data
119	}
120
121	pub fn as_string(&self, index: usize) -> String {
122		if index < self.len() && self.is_defined(index) {
123			self.data[index].to_string()
124		} else {
125			"Undefined".to_string()
126		}
127	}
128
129	pub fn get_value(&self, index: usize) -> Value
130	where
131		T: 'static,
132	{
133		if index < self.len() && self.is_defined(index) {
134			let value = self.data[index].clone();
135
136			if TypeId::of::<T>() == TypeId::of::<f32>() {
137				let f_val = unsafe { transmute_copy::<T, f32>(&value) };
138				OrderedF32::try_from(f_val).map(Value::Float4).unwrap_or(Undefined)
139			} else if TypeId::of::<T>() == TypeId::of::<f64>() {
140				let f_val = unsafe { transmute_copy::<T, f64>(&value) };
141				OrderedF64::try_from(f_val).map(Value::Float8).unwrap_or(Undefined)
142			} else if TypeId::of::<T>() == TypeId::of::<i8>() {
143				let i_val = unsafe { transmute_copy::<T, i8>(&value) };
144				Int1(i_val)
145			} else if TypeId::of::<T>() == TypeId::of::<i16>() {
146				let i_val = unsafe { transmute_copy::<T, i16>(&value) };
147				Int2(i_val)
148			} else if TypeId::of::<T>() == TypeId::of::<i32>() {
149				let i_val = unsafe { transmute_copy::<T, i32>(&value) };
150				Int4(i_val)
151			} else if TypeId::of::<T>() == TypeId::of::<i64>() {
152				let i_val = unsafe { transmute_copy::<T, i64>(&value) };
153				Int8(i_val)
154			} else if TypeId::of::<T>() == TypeId::of::<i128>() {
155				let i_val = unsafe { transmute_copy::<T, i128>(&value) };
156				Int16(i_val)
157			} else if TypeId::of::<T>() == TypeId::of::<u8>() {
158				let u_val = unsafe { transmute_copy::<T, u8>(&value) };
159				Uint1(u_val)
160			} else if TypeId::of::<T>() == TypeId::of::<u16>() {
161				let u_val = unsafe { transmute_copy::<T, u16>(&value) };
162				Uint2(u_val)
163			} else if TypeId::of::<T>() == TypeId::of::<u32>() {
164				let u_val = unsafe { transmute_copy::<T, u32>(&value) };
165				Uint4(u_val)
166			} else if TypeId::of::<T>() == TypeId::of::<u64>() {
167				let u_val = unsafe { transmute_copy::<T, u64>(&value) };
168				Uint8(u_val)
169			} else if TypeId::of::<T>() == TypeId::of::<u128>() {
170				let u_val = unsafe { transmute_copy::<T, u128>(&value) };
171				Uint16(u_val)
172			} else if TypeId::of::<T>() == TypeId::of::<Decimal>() {
173				let d_val = unsafe { transmute_copy::<T, Decimal>(&value) };
174				forget(value);
175				Value::Decimal(d_val)
176			} else if TypeId::of::<T>() == TypeId::of::<Int>() {
177				let i_val = unsafe { transmute_copy::<T, Int>(&value) };
178				forget(value);
179				Value::Int(i_val)
180			} else if TypeId::of::<T>() == TypeId::of::<Uint>() {
181				let u_val = unsafe { transmute_copy::<T, Uint>(&value) };
182				forget(value);
183				Value::Uint(u_val)
184			} else {
185				Undefined
186			}
187		} else {
188			Undefined
189		}
190	}
191
192	pub fn extend(&mut self, other: &Self) -> crate::Result<()> {
193		self.data.extend(other.data.iter().cloned());
194		self.bitvec.extend(&other.bitvec);
195		Ok(())
196	}
197
198	pub fn extend_from_undefined(&mut self, len: usize) {
199		self.data.extend(std::iter::repeat(T::default()).take(len));
200		self.bitvec.extend(&BitVec::repeat(len, false));
201	}
202
203	pub fn iter(&self) -> impl Iterator<Item = Option<T>> + '_
204	where
205		T: Copy,
206	{
207		self.data.iter().zip(self.bitvec.iter()).map(|(&v, defined)| {
208			if defined {
209				Some(v)
210			} else {
211				None
212			}
213		})
214	}
215
216	pub fn slice(&self, start: usize, end: usize) -> Self {
217		let new_data: Vec<T> = self.data.iter().skip(start).take(end - start).cloned().collect();
218		let new_bitvec: Vec<bool> = self.bitvec.iter().skip(start).take(end - start).collect();
219		Self {
220			data: CowVec::new(new_data),
221			bitvec: BitVec::from_slice(&new_bitvec),
222		}
223	}
224
225	pub fn filter(&mut self, mask: &BitVec) {
226		let mut new_data = Vec::with_capacity(mask.count_ones());
227		let mut new_bitvec = BitVec::with_capacity(mask.count_ones());
228
229		for (i, keep) in mask.iter().enumerate() {
230			if keep && i < self.len() {
231				new_data.push(self.data[i].clone());
232				new_bitvec.push(self.bitvec.get(i));
233			}
234		}
235
236		self.data = CowVec::new(new_data);
237		self.bitvec = new_bitvec;
238	}
239
240	pub fn reorder(&mut self, indices: &[usize]) {
241		let mut new_data = Vec::with_capacity(indices.len());
242		let mut new_bitvec = BitVec::with_capacity(indices.len());
243
244		for &idx in indices {
245			if idx < self.len() {
246				new_data.push(self.data[idx].clone());
247				new_bitvec.push(self.bitvec.get(idx));
248			} else {
249				new_data.push(T::default());
250				new_bitvec.push(false);
251			}
252		}
253
254		self.data = CowVec::new(new_data);
255		self.bitvec = new_bitvec;
256	}
257
258	pub fn push_with_convert<U>(&mut self, value: U, converter: impl FnOnce(U) -> Option<T>) {
259		match converter(value) {
260			Some(v) => {
261				self.data.push(v);
262				self.bitvec.push(true);
263			}
264			None => {
265				self.data.push(T::default());
266				self.bitvec.push(false);
267			}
268		}
269	}
270
271	pub fn take(&self, num: usize) -> Self {
272		Self {
273			data: self.data.take(num),
274			bitvec: self.bitvec.take(num),
275		}
276	}
277}
278
279#[cfg(test)]
280mod tests {
281	use super::*;
282	use crate::BitVec;
283
284	#[test]
285	fn test_new_i32() {
286		let data = vec![1, 2, 3];
287		let bitvec = BitVec::from_slice(&[true, true, true]);
288		let container = NumberContainer::new(data.clone(), bitvec);
289
290		assert_eq!(container.len(), 3);
291		assert_eq!(container.get(0), Some(&1));
292		assert_eq!(container.get(1), Some(&2));
293		assert_eq!(container.get(2), Some(&3));
294	}
295
296	#[test]
297	fn test_from_vec_f64() {
298		let data = vec![1.1, 2.2, 3.3];
299		let container = NumberContainer::from_vec(data);
300
301		assert_eq!(container.len(), 3);
302		assert_eq!(container.get(0), Some(&1.1));
303		assert_eq!(container.get(1), Some(&2.2));
304		assert_eq!(container.get(2), Some(&3.3));
305
306		// All should be defined
307		for i in 0..3 {
308			assert!(container.is_defined(i));
309		}
310	}
311
312	#[test]
313	fn test_with_capacity() {
314		let container: NumberContainer<i32> = NumberContainer::with_capacity(10);
315		assert_eq!(container.len(), 0);
316		assert!(container.is_empty());
317		assert!(container.capacity() >= 10);
318	}
319
320	#[test]
321	fn test_push_i64() {
322		let mut container: NumberContainer<i64> = NumberContainer::with_capacity(3);
323
324		container.push(100);
325		container.push(-200);
326		container.push_undefined();
327
328		assert_eq!(container.len(), 3);
329		assert_eq!(container.get(0), Some(&100));
330		assert_eq!(container.get(1), Some(&-200));
331		assert_eq!(container.get(2), None); // undefined
332
333		assert!(container.is_defined(0));
334		assert!(container.is_defined(1));
335		assert!(!container.is_defined(2));
336	}
337
338	#[test]
339	fn test_extend() {
340		let mut container1 = NumberContainer::from_vec(vec![1i32, 2]);
341		let container2 = NumberContainer::from_vec(vec![3i32, 4]);
342
343		container1.extend(&container2).unwrap();
344
345		assert_eq!(container1.len(), 4);
346		assert_eq!(container1.get(0), Some(&1));
347		assert_eq!(container1.get(1), Some(&2));
348		assert_eq!(container1.get(2), Some(&3));
349		assert_eq!(container1.get(3), Some(&4));
350	}
351
352	#[test]
353	fn test_extend_from_undefined() {
354		let mut container = NumberContainer::from_vec(vec![1i32, 2]);
355		container.extend_from_undefined(2);
356
357		assert_eq!(container.len(), 4);
358		assert_eq!(container.get(0), Some(&1));
359		assert_eq!(container.get(1), Some(&2));
360		assert_eq!(container.get(2), None); // undefined
361		assert_eq!(container.get(3), None); // undefined
362	}
363
364	#[test]
365	fn test_iter_u8() {
366		let data = vec![1u8, 2, 3];
367		let bitvec = BitVec::from_slice(&[true, false, true]); // middle value undefined
368		let container = NumberContainer::new(data, bitvec);
369
370		let collected: Vec<Option<u8>> = container.iter().collect();
371		assert_eq!(collected, vec![Some(1), None, Some(3)]);
372	}
373
374	#[test]
375	fn test_slice() {
376		let container = NumberContainer::from_vec(vec![10i16, 20, 30, 40]);
377		let sliced = container.slice(1, 3);
378
379		assert_eq!(sliced.len(), 2);
380		assert_eq!(sliced.get(0), Some(&20));
381		assert_eq!(sliced.get(1), Some(&30));
382	}
383
384	#[test]
385	fn test_filter() {
386		let mut container = NumberContainer::from_vec(vec![1f32, 2.0, 3.0, 4.0]);
387		let mask = BitVec::from_slice(&[true, false, true, false]);
388
389		container.filter(&mask);
390
391		assert_eq!(container.len(), 2);
392		assert_eq!(container.get(0), Some(&1.0));
393		assert_eq!(container.get(1), Some(&3.0));
394	}
395
396	#[test]
397	fn test_reorder() {
398		let mut container = NumberContainer::from_vec(vec![10i32, 20, 30]);
399		let indices = [2, 0, 1];
400
401		container.reorder(&indices);
402
403		assert_eq!(container.len(), 3);
404		assert_eq!(container.get(0), Some(&30)); // was index 2
405		assert_eq!(container.get(1), Some(&10)); // was index 0
406		assert_eq!(container.get(2), Some(&20)); // was index 1
407	}
408
409	#[test]
410	fn test_push_with_convert() {
411		let mut container: NumberContainer<i32> = NumberContainer::with_capacity(3);
412
413		// Successful conversion
414		container.push_with_convert(42u32, |x| {
415			if x <= i32::MAX as u32 {
416				Some(x as i32)
417			} else {
418				None
419			}
420		});
421
422		// Failed conversion
423		container.push_with_convert(u32::MAX, |x| {
424			if x <= i32::MAX as u32 {
425				Some(x as i32)
426			} else {
427				None
428			}
429		});
430
431		assert_eq!(container.len(), 2);
432		assert_eq!(container.get(0), Some(&42));
433		assert_eq!(container.get(1), None); // conversion failed
434
435		assert!(container.is_defined(0));
436		assert!(!container.is_defined(1));
437	}
438
439	#[test]
440	fn test_data_access() {
441		let mut container = NumberContainer::from_vec(vec![1i32, 2, 3]);
442
443		// Test immutable access
444		assert_eq!(container.data().len(), 3);
445
446		// Test mutable access
447		container.data_mut().push(4);
448		container.bitvec_mut().push(true);
449
450		assert_eq!(container.len(), 4);
451		assert_eq!(container.get(3), Some(&4));
452	}
453}