@@ -14,6 +14,7 @@ use vortex_error::VortexExpect;
1414use vortex_error:: VortexResult ;
1515use vortex_error:: vortex_bail;
1616use vortex_error:: vortex_ensure;
17+ use vortex_error:: vortex_ensure_eq;
1718use vortex_error:: vortex_err;
1819use vortex_error:: vortex_panic;
1920use vortex_session:: VortexSession ;
@@ -65,28 +66,21 @@ impl ValidityChild<Patched> for Patched {
6566
6667#[ derive( Clone , prost:: Message ) ]
6768pub struct PatchedMetadata {
68- /// Length of the `inner` child.
69- ///
70- /// This may not match the length of the wrapping PatchedArray, if for example
71- /// in a filter or slice it may be sliced to the nearest chunk boundary.
72- #[ prost( uint64, tag = "1" ) ]
73- pub ( crate ) inner_len : u64 ,
74-
7569 /// Offset within the first chunk of `inner` where data begins.
7670 ///
7771 /// This may become nonzero after slicing.
78- #[ prost( uint32, tag = "2 " ) ]
72+ #[ prost( uint32, tag = "1 " ) ]
7973 pub ( crate ) offset : u32 ,
8074
8175 /// Number of patches. This is the length of the `indices` and `values` children.
82- #[ prost( uint32, tag = "3 " ) ]
76+ #[ prost( uint32, tag = "2 " ) ]
8377 pub ( crate ) n_patches : u32 ,
8478
8579 /// Number of lanes the patches get spread over.
8680 ///
8781 /// By default, this is either 16 or 32 depending on the width of the type, but may change
8882 /// in the future, so we save it on write.
89- #[ prost( uint32, tag = "4 " ) ]
83+ #[ prost( uint32, tag = "3 " ) ]
9084 pub ( crate ) n_lanes : u32 ,
9185}
9286
@@ -174,13 +168,25 @@ impl VTable for Patched {
174168 }
175169 }
176170
177- #[ allow( clippy:: cast_possible_truncation) ]
178171 fn metadata ( array : & Self :: Array ) -> VortexResult < Self :: Metadata > {
172+ let n_patches: u32 =
173+ array. indices . len ( ) . try_into ( ) . map_err ( |_| {
174+ vortex_err ! ( "Cannot serialize Patched array with > u32::MAX patches" )
175+ } ) ?;
176+
177+ #[ expect(
178+ clippy:: cast_possible_truncation,
179+ reason = "array offset always < 1024"
180+ ) ]
181+ let offset = array. offset as u32 ;
182+
183+ #[ expect( clippy:: cast_possible_truncation, reason = "n_lanes is always <= 64" ) ]
184+ let n_lanes = array. n_lanes as u32 ;
185+
179186 Ok ( ProstMetadata ( PatchedMetadata {
180- inner_len : array. inner . len ( ) as u64 ,
181- offset : array. offset as u32 ,
182- n_patches : array. indices . len ( ) as u32 ,
183- n_lanes : array. n_lanes as u32 ,
187+ offset,
188+ n_patches,
189+ n_lanes,
184190 } ) )
185191 }
186192
@@ -262,12 +268,6 @@ impl VTable for Patched {
262268 buffers : & [ BufferHandle ] ,
263269 children : & dyn ArrayChildren ,
264270 ) -> VortexResult < PatchedArray > {
265- let inner_len = usize:: try_from ( metadata. inner_len ) . map_err ( |_| {
266- vortex_err ! (
267- "PatchedMetadata inner_len overflows usize: {}" ,
268- metadata. inner_len
269- )
270- } ) ?;
271271 let offset = metadata. offset as usize ;
272272
273273 // n_chunks should correspond to the chunk in the `inner`.
@@ -279,7 +279,7 @@ impl VTable for Patched {
279279 vortex_bail ! ( "invalid buffer count for PatchedArray" ) ;
280280 } ;
281281
282- let inner = children. get ( 0 , dtype, inner_len ) ?;
282+ let inner = children. get ( 0 , dtype, len ) ?;
283283 let indices = children. get ( 1 , PType :: U16 . into ( ) , metadata. n_patches as usize ) ?;
284284 let values = children. get ( 2 , dtype, metadata. n_patches as usize ) ?;
285285
@@ -302,9 +302,29 @@ impl VTable for Patched {
302302 "PatchedArray must have exactly 3 children"
303303 ) ;
304304
305- array. inner = children. remove ( 0 ) ;
306- array. indices = children. remove ( 0 ) ;
307- array. values = children. remove ( 0 ) ;
305+ let inner = children. remove ( 0 ) ;
306+ let indices = children. remove ( 0 ) ;
307+ let values = children. remove ( 0 ) ;
308+
309+ // We only execute these checks on debug builds, since this method is called in a tight
310+ // loop during optimization, and we want to avoid the overhead of repeatedly checking the
311+ // component types.
312+ if cfg ! ( debug_assertions) {
313+ vortex_ensure ! (
314+ array. dtype( ) . eq_with_nullability_superset( inner. dtype( ) ) ,
315+ "inner array DType must match outer array DType"
316+ ) ;
317+
318+ vortex_ensure_eq ! (
319+ indices. dtype( ) ,
320+ & DType :: from( PType :: U16 ) ,
321+ "indices must be u16 type"
322+ ) ;
323+ }
324+
325+ array. inner = inner;
326+ array. indices = indices;
327+ array. values = values;
308328
309329 Ok ( ( ) )
310330 }
0 commit comments