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