1use super::data::GetData;
2use super::Value;
3use crate::descriptor::DataType;
4use std::any::Any;
5use std::sync::Arc;
6
7#[derive(Clone, Debug, PartialEq)]
24pub enum PackedArray {
25 I8(Arc<Vec<i8>>),
26 I16(Arc<Vec<i16>>),
27 I32(Arc<Vec<i32>>),
28 I64(Arc<Vec<i64>>),
29 I128(Arc<Vec<i128>>),
30
31 U8(Arc<Vec<u8>>),
32 U16(Arc<Vec<u16>>),
33 U32(Arc<Vec<u32>>),
34 U64(Arc<Vec<u64>>),
35 U128(Arc<Vec<u128>>),
36
37 F32(Arc<Vec<f32>>),
38 F64(Arc<Vec<f64>>),
39
40 Bool(Arc<Vec<bool>>),
41 Byte(Arc<Vec<u8>>),
44 Char(Arc<Vec<char>>),
45}
46
47fn downcast_vec<T: 'static, U: 'static>(value: Vec<U>) -> Result<Vec<T>, Vec<U>> {
52 let boxed: Box<dyn Any> = Box::new(value);
53 match boxed.downcast::<Vec<T>>() {
54 Ok(value) => Ok(*value),
55 Err(boxed) => Err(*boxed.downcast::<Vec<U>>().unwrap()),
56 }
57}
58
59impl PackedArray {
60 pub fn len(&self) -> usize {
61 match self {
62 PackedArray::I8(a) => a.len(),
63 PackedArray::I16(a) => a.len(),
64 PackedArray::I32(a) => a.len(),
65 PackedArray::I64(a) => a.len(),
66 PackedArray::I128(a) => a.len(),
67 PackedArray::U8(a) => a.len(),
68 PackedArray::U16(a) => a.len(),
69 PackedArray::U32(a) => a.len(),
70 PackedArray::U64(a) => a.len(),
71 PackedArray::U128(a) => a.len(),
72 PackedArray::F32(a) => a.len(),
73 PackedArray::F64(a) => a.len(),
74 PackedArray::Bool(a) => a.len(),
75 PackedArray::Byte(a) => a.len(),
76 PackedArray::Char(a) => a.len(),
77 }
78 }
79
80 pub fn is_empty(&self) -> bool {
81 self.len() == 0
82 }
83
84 pub fn element_datatype(&self) -> DataType {
88 match self {
89 PackedArray::I8(_) => DataType::I8,
90 PackedArray::I16(_) => DataType::I16,
91 PackedArray::I32(_) => DataType::I32,
92 PackedArray::I64(_) => DataType::I64,
93 PackedArray::I128(_) => DataType::I128,
94 PackedArray::U8(_) => DataType::U8,
95 PackedArray::U16(_) => DataType::U16,
96 PackedArray::U32(_) => DataType::U32,
97 PackedArray::U64(_) => DataType::U64,
98 PackedArray::U128(_) => DataType::U128,
99 PackedArray::F32(_) => DataType::F32,
100 PackedArray::F64(_) => DataType::F64,
101 PackedArray::Bool(_) => DataType::Bool,
102 PackedArray::Byte(_) => DataType::Byte,
103 PackedArray::Char(_) => DataType::Char,
104 }
105 }
106
107 pub fn estimated_size(&self) -> usize {
110 match self {
111 PackedArray::I8(a) => a.len() * std::mem::size_of::<i8>(),
112 PackedArray::I16(a) => a.len() * std::mem::size_of::<i16>(),
113 PackedArray::I32(a) => a.len() * std::mem::size_of::<i32>(),
114 PackedArray::I64(a) => a.len() * std::mem::size_of::<i64>(),
115 PackedArray::I128(a) => a.len() * std::mem::size_of::<i128>(),
116 PackedArray::U8(a) => a.len() * std::mem::size_of::<u8>(),
117 PackedArray::U16(a) => a.len() * std::mem::size_of::<u16>(),
118 PackedArray::U32(a) => a.len() * std::mem::size_of::<u32>(),
119 PackedArray::U64(a) => a.len() * std::mem::size_of::<u64>(),
120 PackedArray::U128(a) => a.len() * std::mem::size_of::<u128>(),
121 PackedArray::F32(a) => a.len() * std::mem::size_of::<f32>(),
122 PackedArray::F64(a) => a.len() * std::mem::size_of::<f64>(),
123 PackedArray::Bool(a) => a.len() * std::mem::size_of::<bool>(),
124 PackedArray::Byte(a) => a.len(),
125 PackedArray::Char(a) => a.len() * std::mem::size_of::<char>(),
126 }
127 }
128
129 pub fn into_values(self) -> Vec<Value> {
134 match self {
135 PackedArray::I8(a) => a.iter().copied().map(Value::I8).collect(),
136 PackedArray::I16(a) => a.iter().copied().map(Value::I16).collect(),
137 PackedArray::I32(a) => a.iter().copied().map(Value::I32).collect(),
138 PackedArray::I64(a) => a.iter().copied().map(Value::I64).collect(),
139 PackedArray::I128(a) => a.iter().copied().map(Value::I128).collect(),
140 PackedArray::U8(a) => a.iter().copied().map(Value::U8).collect(),
141 PackedArray::U16(a) => a.iter().copied().map(Value::U16).collect(),
142 PackedArray::U32(a) => a.iter().copied().map(Value::U32).collect(),
143 PackedArray::U64(a) => a.iter().copied().map(Value::U64).collect(),
144 PackedArray::U128(a) => a.iter().copied().map(Value::U128).collect(),
145 PackedArray::F32(a) => a.iter().copied().map(Value::F32).collect(),
146 PackedArray::F64(a) => a.iter().copied().map(Value::F64).collect(),
147 PackedArray::Bool(a) => a.iter().copied().map(Value::Bool).collect(),
148 PackedArray::Byte(a) => a.iter().copied().map(Value::Byte).collect(),
149 PackedArray::Char(a) => a.iter().copied().map(Value::Char).collect(),
150 }
151 }
152
153 pub fn try_from_vec<T: 'static>(value: Vec<T>) -> Result<PackedArray, Vec<T>> {
161 let value = match downcast_vec::<i8, T>(value) {
162 Ok(v) => return Ok(PackedArray::I8(Arc::new(v))),
163 Err(v) => v,
164 };
165 let value = match downcast_vec::<i16, T>(value) {
166 Ok(v) => return Ok(PackedArray::I16(Arc::new(v))),
167 Err(v) => v,
168 };
169 let value = match downcast_vec::<i32, T>(value) {
170 Ok(v) => return Ok(PackedArray::I32(Arc::new(v))),
171 Err(v) => v,
172 };
173 let value = match downcast_vec::<i64, T>(value) {
174 Ok(v) => return Ok(PackedArray::I64(Arc::new(v))),
175 Err(v) => v,
176 };
177 let value = match downcast_vec::<i128, T>(value) {
178 Ok(v) => return Ok(PackedArray::I128(Arc::new(v))),
179 Err(v) => v,
180 };
181 let value = match downcast_vec::<u8, T>(value) {
182 Ok(v) => return Ok(PackedArray::U8(Arc::new(v))),
183 Err(v) => v,
184 };
185 let value = match downcast_vec::<u16, T>(value) {
186 Ok(v) => return Ok(PackedArray::U16(Arc::new(v))),
187 Err(v) => v,
188 };
189 let value = match downcast_vec::<u32, T>(value) {
190 Ok(v) => return Ok(PackedArray::U32(Arc::new(v))),
191 Err(v) => v,
192 };
193 let value = match downcast_vec::<u64, T>(value) {
194 Ok(v) => return Ok(PackedArray::U64(Arc::new(v))),
195 Err(v) => v,
196 };
197 let value = match downcast_vec::<u128, T>(value) {
198 Ok(v) => return Ok(PackedArray::U128(Arc::new(v))),
199 Err(v) => v,
200 };
201 let value = match downcast_vec::<f32, T>(value) {
202 Ok(v) => return Ok(PackedArray::F32(Arc::new(v))),
203 Err(v) => v,
204 };
205 let value = match downcast_vec::<f64, T>(value) {
206 Ok(v) => return Ok(PackedArray::F64(Arc::new(v))),
207 Err(v) => v,
208 };
209 let value = match downcast_vec::<bool, T>(value) {
210 Ok(v) => return Ok(PackedArray::Bool(Arc::new(v))),
211 Err(v) => v,
212 };
213 let value = match downcast_vec::<char, T>(value) {
214 Ok(v) => return Ok(PackedArray::Char(Arc::new(v))),
215 Err(v) => v,
216 };
217 Err(value)
218 }
219
220 pub fn try_into_vec<T: 'static>(self) -> Result<Vec<T>, PackedArray> {
229 fn owned<U: Clone>(arc: Arc<Vec<U>>) -> Vec<U> {
230 Arc::try_unwrap(arc).unwrap_or_else(|arc| (*arc).clone())
231 }
232
233 match self {
234 PackedArray::I8(a) => {
235 downcast_vec::<T, i8>(owned(a)).map_err(|v| PackedArray::I8(Arc::new(v)))
236 }
237 PackedArray::I16(a) => {
238 downcast_vec::<T, i16>(owned(a)).map_err(|v| PackedArray::I16(Arc::new(v)))
239 }
240 PackedArray::I32(a) => {
241 downcast_vec::<T, i32>(owned(a)).map_err(|v| PackedArray::I32(Arc::new(v)))
242 }
243 PackedArray::I64(a) => {
244 downcast_vec::<T, i64>(owned(a)).map_err(|v| PackedArray::I64(Arc::new(v)))
245 }
246 PackedArray::I128(a) => {
247 downcast_vec::<T, i128>(owned(a)).map_err(|v| PackedArray::I128(Arc::new(v)))
248 }
249 PackedArray::U8(a) => {
250 downcast_vec::<T, u8>(owned(a)).map_err(|v| PackedArray::U8(Arc::new(v)))
251 }
252 PackedArray::U16(a) => {
253 downcast_vec::<T, u16>(owned(a)).map_err(|v| PackedArray::U16(Arc::new(v)))
254 }
255 PackedArray::U32(a) => {
256 downcast_vec::<T, u32>(owned(a)).map_err(|v| PackedArray::U32(Arc::new(v)))
257 }
258 PackedArray::U64(a) => {
259 downcast_vec::<T, u64>(owned(a)).map_err(|v| PackedArray::U64(Arc::new(v)))
260 }
261 PackedArray::U128(a) => {
262 downcast_vec::<T, u128>(owned(a)).map_err(|v| PackedArray::U128(Arc::new(v)))
263 }
264 PackedArray::F32(a) => {
265 downcast_vec::<T, f32>(owned(a)).map_err(|v| PackedArray::F32(Arc::new(v)))
266 }
267 PackedArray::F64(a) => {
268 downcast_vec::<T, f64>(owned(a)).map_err(|v| PackedArray::F64(Arc::new(v)))
269 }
270 PackedArray::Bool(a) => {
271 downcast_vec::<T, bool>(owned(a)).map_err(|v| PackedArray::Bool(Arc::new(v)))
272 }
273 PackedArray::Byte(a) => {
274 downcast_vec::<T, u8>(owned(a)).map_err(|v| PackedArray::Byte(Arc::new(v)))
275 }
276 PackedArray::Char(a) => {
277 downcast_vec::<T, char>(owned(a)).map_err(|v| PackedArray::Char(Arc::new(v)))
278 }
279 }
280 }
281}
282
283impl From<PackedArray> for Value {
284 fn from(value: PackedArray) -> Self {
285 Value::Packed(value)
286 }
287}
288
289impl<T> From<Arc<Vec<T>>> for Value
295where
296 PackedArray: From<Arc<Vec<T>>>,
297{
298 fn from(value: Arc<Vec<T>>) -> Self {
299 Value::Packed(PackedArray::from(value))
300 }
301}
302
303impl GetData<PackedArray> for Value {
304 fn try_data(self) -> Result<PackedArray, ()> {
305 match self {
306 Value::Packed(arr) => Ok(arr),
307 _ => Err(()),
308 }
309 }
310}
311
312macro_rules! packed_array_scalar_type {
320 ($variant:ident, $ty:ty) => {
321 impl From<Vec<$ty>> for PackedArray {
322 fn from(value: Vec<$ty>) -> Self {
323 PackedArray::$variant(Arc::new(value))
324 }
325 }
326
327 impl From<Arc<Vec<$ty>>> for PackedArray {
328 fn from(value: Arc<Vec<$ty>>) -> Self {
329 PackedArray::$variant(value)
330 }
331 }
332
333 impl GetData<Arc<Vec<$ty>>> for Value {
334 fn try_data(self) -> Result<Arc<Vec<$ty>>, ()> {
335 match self {
336 Value::Packed(PackedArray::$variant(arr)) => Ok(arr),
337 _ => Err(()),
338 }
339 }
340 }
341 };
342}
343
344packed_array_scalar_type!(I8, i8);
345packed_array_scalar_type!(I16, i16);
346packed_array_scalar_type!(I32, i32);
347packed_array_scalar_type!(I64, i64);
348packed_array_scalar_type!(I128, i128);
349packed_array_scalar_type!(U16, u16);
350packed_array_scalar_type!(U32, u32);
351packed_array_scalar_type!(U64, u64);
352packed_array_scalar_type!(U128, u128);
353packed_array_scalar_type!(F32, f32);
354packed_array_scalar_type!(F64, f64);
355packed_array_scalar_type!(Bool, bool);
356packed_array_scalar_type!(Char, char);
357
358impl From<Vec<u8>> for PackedArray {
359 fn from(value: Vec<u8>) -> Self {
360 PackedArray::U8(Arc::new(value))
361 }
362}
363
364impl From<Arc<Vec<u8>>> for PackedArray {
365 fn from(value: Arc<Vec<u8>>) -> Self {
366 PackedArray::U8(value)
367 }
368}
369
370impl GetData<Arc<Vec<u8>>> for Value {
371 fn try_data(self) -> Result<Arc<Vec<u8>>, ()> {
372 match self {
373 Value::Packed(PackedArray::U8(arr)) => Ok(arr),
374 Value::Packed(PackedArray::Byte(arr)) => Ok(arr),
375 _ => Err(()),
376 }
377 }
378}
379
380#[cfg(test)]
381mod packed_array_tests {
382 use super::*;
383
384 #[test]
385 fn estimated_size_has_no_per_element_value_overhead() {
386 let arr = PackedArray::U8(Arc::new(vec![0u8; 4096]));
387 assert_eq!(arr.estimated_size(), 4096);
388
389 let arr = PackedArray::F64(Arc::new(vec![0f64; 10]));
390 assert_eq!(arr.estimated_size(), 10 * std::mem::size_of::<f64>());
391 }
392
393 #[test]
394 fn value_packed_reports_the_same_datatype_as_value_vec() {
395 let packed = Value::Packed(PackedArray::Byte(Arc::new(vec![1u8, 2, 3])));
396 let boxed = Value::Vec(vec![Value::Byte(1), Value::Byte(2), Value::Byte(3)]);
397 assert_eq!(packed.datatype(), boxed.datatype());
398 }
399
400 #[test]
401 fn value_packed_estimated_size_has_no_per_element_value_overhead() {
402 let base = std::mem::size_of::<Value>();
403 let value = Value::Packed(PackedArray::Byte(Arc::new(vec![0u8; 4096])));
404 assert_eq!(value.estimated_size(), base + 4096);
407 }
408
409 #[test]
410 fn arc_u8_extraction_accepts_both_u8_and_byte_variants() {
411 let as_u8 = Value::Packed(PackedArray::U8(Arc::new(vec![1u8, 2, 3])));
412 let as_byte = Value::Packed(PackedArray::Byte(Arc::new(vec![4u8, 5, 6])));
413
414 let from_u8: Arc<Vec<u8>> = as_u8.try_data().unwrap();
415 let from_byte: Arc<Vec<u8>> = as_byte.try_data().unwrap();
416
417 assert_eq!(&*from_u8, &vec![1, 2, 3]);
418 assert_eq!(&*from_byte, &vec![4, 5, 6]);
419 }
420
421 #[test]
422 fn from_vec_u8_always_produces_u8_not_byte() {
423 let packed: PackedArray = vec![1u8, 2, 3].into();
424 assert!(matches!(packed, PackedArray::U8(_)));
425 }
426
427 #[test]
428 fn mismatched_type_extraction_fails() {
429 let value = Value::Packed(PackedArray::I64(Arc::new(vec![1i64])));
430 let result: Result<Arc<Vec<u8>>, ()> = value.try_data();
431 assert!(result.is_err());
432 }
433
434 #[test]
435 fn into_values_roundtrips_element_by_element() {
436 let packed = PackedArray::Byte(Arc::new(vec![1u8, 2, 3]));
437 assert_eq!(
438 packed.into_values(),
439 vec![Value::Byte(1), Value::Byte(2), Value::Byte(3)]
440 );
441 }
442
443 #[test]
444 fn try_from_vec_packs_a_recognized_primitive_type() {
445 let packed = PackedArray::try_from_vec(vec![1u8, 2, 3]).unwrap();
446 assert!(matches!(packed, PackedArray::U8(_)));
447 }
448
449 #[test]
450 fn try_from_vec_hands_back_the_vec_unchanged_for_a_non_packable_type() {
451 let original = vec!["a".to_string(), "b".to_string()];
452 let result = PackedArray::try_from_vec(original.clone());
453 assert_eq!(result, Err(original));
454 }
455
456 #[test]
457 fn try_into_vec_extracts_without_creating_any_value() {
458 let packed = PackedArray::I64(Arc::new(vec![1i64, 2, 3]));
459 let extracted: Vec<i64> = packed.try_into_vec().unwrap();
460 assert_eq!(extracted, vec![1, 2, 3]);
461 }
462
463 #[test]
464 fn try_into_vec_hands_back_the_packed_array_unchanged_on_mismatch() {
465 let packed = PackedArray::I64(Arc::new(vec![1i64, 2, 3]));
466 let result = packed.clone().try_into_vec::<u8>();
467 assert_eq!(result, Err(packed));
468 }
469
470 #[test]
471 fn arc_vec_converts_directly_into_value_packed() {
472 let arc = Arc::new(vec![1u8, 2, 3]);
473 let value: Value = arc.into();
474 assert!(matches!(value, Value::Packed(PackedArray::U8(_))));
475 }
476
477 #[test]
478 fn try_into_vec_does_not_copy_when_exclusively_owned() {
479 let arc = Arc::new(vec![1u8, 2, 3]);
480 let data_ptr = arc.as_ptr();
481 let packed = PackedArray::U8(arc);
482 let extracted: Vec<u8> = packed.try_into_vec().unwrap();
483 assert_eq!(extracted.as_ptr(), data_ptr);
484 }
485}