1use vortex_array::arrays::ConstantArray;
5use vortex_array::vtable::OperationsVTable;
6use vortex_array::{Array, ArrayRef, IntoArray};
7use vortex_scalar::Scalar;
8
9use crate::{RunEndArray, RunEndVTable};
10
11impl OperationsVTable<RunEndVTable> for RunEndVTable {
12 fn slice(array: &RunEndArray, start: usize, stop: usize) -> ArrayRef {
13 let new_length = stop - start;
14
15 let slice_begin = array.find_physical_index(start);
16 let slice_end = array.find_physical_index(stop) + 1;
17
18 if slice_begin + 1 == slice_end {
20 let value = array.values().scalar_at(slice_begin);
21 return ConstantArray::new(value, new_length).into_array();
22 }
23
24 unsafe {
26 RunEndArray::new_unchecked(
27 array.ends().slice(slice_begin, slice_end),
28 array.values().slice(slice_begin, slice_end),
29 start + array.offset(),
30 new_length,
31 )
32 .into_array()
33 }
34 }
35
36 fn scalar_at(array: &RunEndArray, index: usize) -> Scalar {
37 array.values().scalar_at(array.find_physical_index(index))
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use vortex_array::arrays::PrimitiveArray;
44 use vortex_array::{Array, IntoArray, ToCanonical};
45 use vortex_buffer::buffer;
46 use vortex_dtype::{DType, Nullability, PType};
47
48 use crate::RunEndArray;
49
50 #[test]
51 fn slice_array() {
52 let arr = RunEndArray::try_new(
53 buffer![2u32, 5, 10].into_array(),
54 buffer![1i32, 2, 3].into_array(),
55 )
56 .unwrap()
57 .slice(3, 8);
58 assert_eq!(
59 arr.dtype(),
60 &DType::Primitive(PType::I32, Nullability::NonNullable)
61 );
62 assert_eq!(arr.len(), 5);
63
64 assert_eq!(
65 arr.to_primitive().unwrap().as_slice::<i32>(),
66 vec![2, 2, 3, 3, 3]
67 );
68 }
69
70 #[test]
71 fn double_slice() {
72 let arr = RunEndArray::try_new(
73 buffer![2u32, 5, 10].into_array(),
74 buffer![1i32, 2, 3].into_array(),
75 )
76 .unwrap()
77 .slice(3, 8);
78 assert_eq!(arr.len(), 5);
79
80 let doubly_sliced = arr.slice(0, 3);
81
82 assert_eq!(
83 doubly_sliced.to_primitive().unwrap().as_slice::<i32>(),
84 vec![2, 2, 3]
85 );
86 }
87
88 #[test]
89 fn slice_end_inclusive() {
90 let arr = RunEndArray::try_new(
91 buffer![2u32, 5, 10].into_array(),
92 buffer![1i32, 2, 3].into_array(),
93 )
94 .unwrap()
95 .slice(4, 10);
96 assert_eq!(
97 arr.dtype(),
98 &DType::Primitive(PType::I32, Nullability::NonNullable)
99 );
100 assert_eq!(arr.len(), 6);
101
102 assert_eq!(
103 arr.to_primitive().unwrap().as_slice::<i32>(),
104 vec![2, 3, 3, 3, 3, 3]
105 );
106 }
107
108 #[test]
109 fn slice_at_end() {
110 let re_array = RunEndArray::try_new(
111 buffer![7_u64, 10].into_array(),
112 buffer![2_u64, 3].into_array(),
113 )
114 .unwrap();
115
116 assert_eq!(re_array.len(), 10);
117
118 let sliced_array = re_array.slice(re_array.len(), re_array.len());
119 assert!(sliced_array.is_empty());
120 }
121
122 #[test]
123 fn slice_single_end() {
124 let re_array = RunEndArray::try_new(
125 buffer![7_u64, 10].into_array(),
126 buffer![2_u64, 3].into_array(),
127 )
128 .unwrap();
129
130 assert_eq!(re_array.len(), 10);
131
132 let sliced_array = re_array.slice(2, 5);
133
134 assert!(sliced_array.is_constant())
135 }
136
137 #[test]
138 fn ree_scalar_at_end() {
139 let scalar = RunEndArray::encode(
140 PrimitiveArray::from_iter([1, 1, 1, 4, 4, 4, 2, 2, 5, 5, 5, 5]).into_array(),
141 )
142 .unwrap()
143 .scalar_at(11);
144 assert_eq!(scalar, 5.into());
145 }
146}