Skip to main content

reifydb_type/value/container/
number.rs

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