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,46 @@ 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+ // Get the elements from the scalar's inner length-1 vector and repeat them
108+ // Clone the inner Vector from the Arc
109+ let scalar_elements = self . 0 . elements ( ) ;
110+ let mut elements = scalar_elements. as_ref ( ) . clone ( ) . into_mut ( ) ;
111+ elements. reserve ( ( n - 1 ) * list_size as usize ) ;
112+
113+ // Repeat the elements n-1 more times (we already have 1 copy)
114+ for _ in 1 ..n {
115+ elements. extend_from_vector ( scalar_elements. as_ref ( ) ) ;
116+ }
117+
118+ // Build validity for n lists
119+ let validity = MaskMut :: new ( n, self . is_valid ( ) ) ;
120+
121+ // SAFETY: We've repeated the elements n times, so elements.len() == n * list_size
122+ unsafe {
123+ VectorMut :: FixedSizeList ( FixedSizeListVectorMut :: new_unchecked (
124+ Box :: new ( elements) ,
125+ list_size,
126+ validity,
127+ ) )
128+ }
90129 }
91130}
92131
@@ -95,3 +134,103 @@ impl From<FixedSizeListScalar> for Scalar {
95134 Scalar :: FixedSizeList ( val)
96135 }
97136}
137+
138+ #[ cfg( test) ]
139+ mod tests {
140+ use std:: sync:: Arc ;
141+
142+ use vortex_dtype:: DType ;
143+ use vortex_dtype:: Nullability ;
144+ use vortex_dtype:: PType ;
145+ use vortex_mask:: Mask ;
146+
147+ use super :: * ;
148+ use crate :: Vector ;
149+ use crate :: fixed_size_list:: FixedSizeListVector ;
150+ use crate :: primitive:: PVectorMut ;
151+
152+ #[ test]
153+ fn test_repeat_valid_scalar ( ) {
154+ // Create a FSL with elements [1, 2, 3] (list_size = 3)
155+ let elements: Vector = PVectorMut :: < i32 > :: from_iter ( [ 1 , 2 , 3 ] ) . freeze ( ) . into ( ) ;
156+ let validity = Mask :: new_true ( 1 ) ;
157+ let fsl = FixedSizeListVector :: new ( Arc :: new ( elements) , 3 , validity) ;
158+
159+ let scalar = FixedSizeListScalar :: new ( fsl) ;
160+ assert ! ( scalar. is_valid( ) ) ;
161+
162+ // Repeat 4 times
163+ let repeated = scalar. repeat ( 4 ) . freeze ( ) ;
164+ assert_eq ! ( repeated. len( ) , 4 ) ;
165+
166+ // Check validity - all should be valid
167+ assert_eq ! ( repeated. validity( ) . true_count( ) , 4 ) ;
168+
169+ // Freeze and check the elements
170+ let fsl_vec = repeated. as_fixed_size_list ( ) ;
171+ assert_eq ! ( fsl_vec. len( ) , 4 ) ;
172+ assert_eq ! ( fsl_vec. list_size( ) , 3 ) ;
173+
174+ // Elements should be [1,2,3, 1,2,3, 1,2,3, 1,2,3]
175+ let elements = fsl_vec. elements ( ) ;
176+ assert_eq ! ( elements. len( ) , 12 ) ;
177+ }
178+
179+ #[ test]
180+ fn test_repeat_null_scalar ( ) {
181+ // Create a null FSL scalar
182+ let dtype = DType :: FixedSizeList (
183+ Arc :: new ( DType :: Primitive ( PType :: I32 , Nullability :: NonNullable ) ) ,
184+ 3 ,
185+ Nullability :: Nullable ,
186+ ) ;
187+ let scalar = FixedSizeListScalar :: null ( & dtype) ;
188+ assert ! ( !scalar. is_valid( ) ) ;
189+
190+ // Repeat 3 times
191+ let repeated = scalar. repeat ( 3 ) . freeze ( ) ;
192+ assert_eq ! ( repeated. len( ) , 3 ) ;
193+
194+ // Check validity - all should be null
195+ assert_eq ! ( repeated. validity( ) . true_count( ) , 0 ) ;
196+ }
197+
198+ #[ test]
199+ fn test_repeat_zero ( ) {
200+ // Create a valid FSL scalar
201+ let elements: Vector = PVectorMut :: < i32 > :: from_iter ( [ 1 , 2 ] ) . freeze ( ) . into ( ) ;
202+ let validity = Mask :: new_true ( 1 ) ;
203+ let fsl = FixedSizeListVector :: new ( Arc :: new ( elements) , 2 , validity) ;
204+
205+ let scalar = FixedSizeListScalar :: new ( fsl) ;
206+
207+ // Repeat 0 times - should return empty vector
208+ let repeated = scalar. repeat ( 0 ) ;
209+ assert_eq ! ( repeated. len( ) , 0 ) ;
210+
211+ let frozen = repeated. freeze ( ) ;
212+ let fsl_vec = frozen. as_fixed_size_list ( ) ;
213+ assert_eq ! ( fsl_vec. len( ) , 0 ) ;
214+ assert_eq ! ( fsl_vec. list_size( ) , 2 ) ;
215+ assert_eq ! ( fsl_vec. elements( ) . len( ) , 0 ) ;
216+ }
217+
218+ #[ test]
219+ fn test_repeat_one ( ) {
220+ // Create a FSL with elements [10, 20]
221+ let elements: Vector = PVectorMut :: < i32 > :: from_iter ( [ 10 , 20 ] ) . freeze ( ) . into ( ) ;
222+ let validity = Mask :: new_true ( 1 ) ;
223+ let fsl = FixedSizeListVector :: new ( Arc :: new ( elements) , 2 , validity) ;
224+
225+ let scalar = FixedSizeListScalar :: new ( fsl) ;
226+
227+ // Repeat 1 time - should be same as original
228+ let repeated = scalar. repeat ( 1 ) ;
229+ assert_eq ! ( repeated. len( ) , 1 ) ;
230+
231+ let frozen = repeated. freeze ( ) ;
232+ let fsl_vec = frozen. as_fixed_size_list ( ) ;
233+ assert_eq ! ( fsl_vec. len( ) , 1 ) ;
234+ assert_eq ! ( fsl_vec. elements( ) . len( ) , 2 ) ;
235+ }
236+ }
0 commit comments