44use vortex_dtype:: DType ;
55use vortex_error:: vortex_panic;
66use vortex_mask:: Mask ;
7+ use vortex_mask:: MaskMut ;
78
89use crate :: Scalar ;
910use crate :: ScalarOps ;
1011use crate :: VectorMut ;
1112use crate :: VectorMutOps ;
1213use crate :: VectorOps ;
1314use crate :: fixed_size_list:: FixedSizeListVector ;
15+ use crate :: fixed_size_list:: FixedSizeListVectorMut ;
1416
1517/// A scalar value for fixed-size list types.
1618///
@@ -84,9 +86,56 @@ impl ScalarOps for FixedSizeListScalar {
8486 }
8587 }
8688
87- fn repeat ( & self , _n : usize ) -> VectorMut {
88- // TODO(ngates): add "repeat(n)" to the vector ops trait
89- todo ! ( )
89+ fn repeat ( & self , n : usize ) -> VectorMut {
90+ if n == 0 {
91+ // Return an empty vector with the correct structure
92+ let list_size = self . 0 . list_size ( ) ;
93+ let scalar_elements = self . 0 . elements ( ) ;
94+ let elements = scalar_elements. slice ( 0 ..0 ) . into_mut ( ) ;
95+ let validity = MaskMut :: new_true ( 0 ) ;
96+ return unsafe {
97+ VectorMut :: FixedSizeList ( FixedSizeListVectorMut :: new_unchecked (
98+ Box :: new ( elements) ,
99+ list_size,
100+ validity,
101+ ) )
102+ } ;
103+ }
104+
105+ let list_size = self . 0 . list_size ( ) ;
106+
107+ let scalar_elements = self . 0 . elements ( ) ;
108+ let mut elements = scalar_elements. as_ref ( ) . clone ( ) ;
109+ // ensure we don't allocate a vector with the wrong size.
110+ elements. clear ( ) ;
111+ let mut elements = elements. into_mut ( ) ;
112+ elements. reserve ( n * list_size as usize ) ;
113+
114+ if self . is_null ( ) {
115+ elements. append_zeros ( n * list_size as usize ) ;
116+ let validity = MaskMut :: new_false ( n) ;
117+ return unsafe {
118+ VectorMut :: FixedSizeList ( FixedSizeListVectorMut :: new_unchecked (
119+ Box :: new ( elements) ,
120+ list_size,
121+ validity,
122+ ) )
123+ } ;
124+ }
125+
126+ // Repeat the elements n-1 more times (we already have 1 copy)
127+ for _ in 0 ..n {
128+ elements. extend_from_vector ( scalar_elements. as_ref ( ) ) ;
129+ }
130+
131+ // SAFETY: We've repeated the elements n times, so elements.len() == n * list_size
132+ unsafe {
133+ VectorMut :: FixedSizeList ( FixedSizeListVectorMut :: new_unchecked (
134+ Box :: new ( elements) ,
135+ list_size,
136+ MaskMut :: new_true ( n) ,
137+ ) )
138+ }
90139 }
91140}
92141
@@ -95,3 +144,103 @@ impl From<FixedSizeListScalar> for Scalar {
95144 Scalar :: FixedSizeList ( val)
96145 }
97146}
147+
148+ #[ cfg( test) ]
149+ mod tests {
150+ use std:: sync:: Arc ;
151+
152+ use vortex_dtype:: DType ;
153+ use vortex_dtype:: Nullability ;
154+ use vortex_dtype:: PType ;
155+ use vortex_mask:: Mask ;
156+
157+ use super :: * ;
158+ use crate :: Vector ;
159+ use crate :: fixed_size_list:: FixedSizeListVector ;
160+ use crate :: primitive:: PVectorMut ;
161+
162+ #[ test]
163+ fn test_repeat_valid_scalar ( ) {
164+ // Create a FSL with elements [1, 2, 3] (list_size = 3)
165+ let elements: Vector = PVectorMut :: < i32 > :: from_iter ( [ 1 , 2 , 3 ] ) . freeze ( ) . into ( ) ;
166+ let validity = Mask :: new_true ( 1 ) ;
167+ let fsl = FixedSizeListVector :: new ( Arc :: new ( elements) , 3 , validity) ;
168+
169+ let scalar = FixedSizeListScalar :: new ( fsl) ;
170+ assert ! ( scalar. is_valid( ) ) ;
171+
172+ // Repeat 4 times
173+ let repeated = scalar. repeat ( 4 ) . freeze ( ) ;
174+ assert_eq ! ( repeated. len( ) , 4 ) ;
175+
176+ // Check validity - all should be valid
177+ assert_eq ! ( repeated. validity( ) . true_count( ) , 4 ) ;
178+
179+ // Freeze and check the elements
180+ let fsl_vec = repeated. as_fixed_size_list ( ) ;
181+ assert_eq ! ( fsl_vec. len( ) , 4 ) ;
182+ assert_eq ! ( fsl_vec. list_size( ) , 3 ) ;
183+
184+ // Elements should be [1,2,3, 1,2,3, 1,2,3, 1,2,3]
185+ let elements = fsl_vec. elements ( ) ;
186+ assert_eq ! ( elements. len( ) , 12 ) ;
187+ }
188+
189+ #[ test]
190+ fn test_repeat_null_scalar ( ) {
191+ // Create a null FSL scalar
192+ let dtype = DType :: FixedSizeList (
193+ Arc :: new ( DType :: Primitive ( PType :: I32 , Nullability :: NonNullable ) ) ,
194+ 3 ,
195+ Nullability :: Nullable ,
196+ ) ;
197+ let scalar = FixedSizeListScalar :: null ( & dtype) ;
198+ assert ! ( !scalar. is_valid( ) ) ;
199+
200+ // Repeat 3 times
201+ let repeated = scalar. repeat ( 3 ) . freeze ( ) ;
202+ assert_eq ! ( repeated. len( ) , 3 ) ;
203+
204+ // Check validity - all should be null
205+ assert_eq ! ( repeated. validity( ) . true_count( ) , 0 ) ;
206+ }
207+
208+ #[ test]
209+ fn test_repeat_zero ( ) {
210+ // Create a valid FSL scalar
211+ let elements: Vector = PVectorMut :: < i32 > :: from_iter ( [ 1 , 2 ] ) . freeze ( ) . into ( ) ;
212+ let validity = Mask :: new_true ( 1 ) ;
213+ let fsl = FixedSizeListVector :: new ( Arc :: new ( elements) , 2 , validity) ;
214+
215+ let scalar = FixedSizeListScalar :: new ( fsl) ;
216+
217+ // Repeat 0 times - should return empty vector
218+ let repeated = scalar. repeat ( 0 ) ;
219+ assert_eq ! ( repeated. len( ) , 0 ) ;
220+
221+ let frozen = repeated. freeze ( ) ;
222+ let fsl_vec = frozen. as_fixed_size_list ( ) ;
223+ assert_eq ! ( fsl_vec. len( ) , 0 ) ;
224+ assert_eq ! ( fsl_vec. list_size( ) , 2 ) ;
225+ assert_eq ! ( fsl_vec. elements( ) . len( ) , 0 ) ;
226+ }
227+
228+ #[ test]
229+ fn test_repeat_one ( ) {
230+ // Create a FSL with elements [10, 20]
231+ let elements: Vector = PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 ] ) . freeze ( ) . into ( ) ;
232+ let validity = Mask :: new_true ( 1 ) ;
233+ let fsl = FixedSizeListVector :: new ( Arc :: new ( elements) , 2 , validity) ;
234+
235+ let scalar = FixedSizeListScalar :: new ( fsl) ;
236+
237+ // Repeat 1 time - should be same as original
238+ let repeated = scalar. repeat ( 1 ) ;
239+ assert_eq ! ( repeated. len( ) , 1 ) ;
240+
241+ let frozen = repeated. freeze ( ) ;
242+ let fsl_vec = frozen. as_fixed_size_list ( ) ;
243+ assert_eq ! ( fsl_vec. len( ) , 1 ) ;
244+ assert_eq ! ( fsl_vec. elements( ) . len( ) , 2 ) ;
245+ }
246+ }
0 commit comments