@@ -137,7 +137,7 @@ impl ListViewArray {
137137 sizes : ArrayRef ,
138138 validity : Validity ,
139139 ) -> VortexResult < Self > {
140- Self :: validate ( & elements, & offsets, & sizes, & validity, false ) ?;
140+ Self :: validate ( & elements, & offsets, & sizes, & validity) ?;
141141
142142 Ok ( Self {
143143 dtype : DType :: List ( Arc :: new ( elements. dtype ( ) . clone ( ) ) , validity. nullability ( ) ) ,
@@ -152,10 +152,8 @@ impl ListViewArray {
152152
153153 /// Creates a new [`ListViewArray`] without validation.
154154 ///
155- /// Note that this constructor is slightly different from [`new()`] and [`try_new()`] in that it
156- /// also takes an `is_zctl` flag. This is an optimization flag that allows conversion to a
157- /// [`ListArray`] more efficient. The caller must ensure that the flag is correct when passing
158- /// it to this unsafe constructor.
155+ /// This unsafe function does not check the validity of the data. Prefer calling [`new()`] or
156+ /// [`try_new()`] over this function, as they will check the validity of the data.
159157 ///
160158 /// [`ListArray`]: crate::arrays::ListArray
161159 /// [`new()`]: Self::new
@@ -171,17 +169,14 @@ impl ListViewArray {
171169 /// - For each `i`, `offsets[i] + sizes[i]` must not overflow and must be `<= elements.len()`
172170 /// (even if the corresponding view is defined as null by the validity array).
173171 /// - If validity is an array, its length must equal `offsets.len()`.
174- /// - If the `is_zctl` flag is true, then the [`ListViewArray`] is zero-copyable to a
175- /// [`ListArray`].
176172 pub unsafe fn new_unchecked (
177173 elements : ArrayRef ,
178174 offsets : ArrayRef ,
179175 sizes : ArrayRef ,
180176 validity : Validity ,
181- is_zctl : bool ,
182177 ) -> Self {
183178 if cfg ! ( debug_assertions) {
184- Self :: validate ( & elements, & offsets, & sizes, & validity, is_zctl )
179+ Self :: validate ( & elements, & offsets, & sizes, & validity)
185180 . vortex_expect ( "Failed to crate `ListViewArray`" ) ;
186181 }
187182
@@ -191,7 +186,7 @@ impl ListViewArray {
191186 offsets,
192187 sizes,
193188 validity,
194- is_zero_copy_to_list : is_zctl ,
189+ is_zero_copy_to_list : false ,
195190 stats_set : Default :: default ( ) ,
196191 }
197192 }
@@ -202,7 +197,6 @@ impl ListViewArray {
202197 offsets : & dyn Array ,
203198 sizes : & dyn Array ,
204199 validity : & Validity ,
205- is_zctl : bool ,
206200 ) -> VortexResult < ( ) > {
207201 // Check that offsets and sizes are integer arrays and non-nullable.
208202 vortex_ensure ! (
@@ -265,12 +259,63 @@ impl ListViewArray {
265259 } )
266260 } ) ;
267261
268- // Validate the zero-copy to `ListArray` flag.
269- if is_zctl {
270- validate_zctl ( elements, offsets_primitive, sizes_primitive) ?;
262+ Ok ( ( ) )
263+ }
264+
265+ /// Sets whether this [`ListViewArray`] is zero-copyable to a [`ListArray`].
266+ ///
267+ /// This is an optimization flag that enables more efficient conversion to [`ListArray`] without
268+ /// needing to copy or reorganize the data.
269+ ///
270+ /// [`ListArray`]: crate::arrays::ListArray
271+ ///
272+ /// # Safety
273+ ///
274+ /// When setting `is_zctl` to `true`, the caller must ensure that the [`ListViewArray`] is
275+ /// actually zero-copyable to a [`ListArray`]. This means:
276+ ///
277+ /// - Offsets must be sorted (but not strictly sorted, zero-length lists are allowed).
278+ /// - No gaps in elements between first and last referenced elements.
279+ /// - No overlapping list views (each element referenced at most once).
280+ ///
281+ /// Note that leading and trailing unreferenced elements **ARE** allowed.
282+ pub unsafe fn with_zero_copy_to_list ( mut self , is_zctl : bool ) -> Self {
283+ if cfg ! ( debug_assertions) && is_zctl {
284+ validate_zctl (
285+ & self . elements ,
286+ self . offsets . to_primitive ( ) ,
287+ self . sizes . to_primitive ( ) ,
288+ )
289+ . vortex_expect ( "Failed to validate zero-copy to list flag" ) ;
271290 }
291+ self . is_zero_copy_to_list = is_zctl;
292+ self
293+ }
272294
273- Ok ( ( ) )
295+ /// Verifies that the `ListViewArray` is zero-copyable to a [`ListArray`].
296+ ///
297+ /// This will run an expensive validation of the `ListViewArray`'s components. It will check the
298+ /// following things:
299+ ///
300+ /// - Offsets must be sorted (but not strictly sorted, zero-length lists are allowed).
301+ /// - No gaps in elements between first and last referenced elements.
302+ /// - No overlapping list views (each element referenced at most once).
303+ ///
304+ /// Note that leading and trailing unreferenced elements **ARE** allowed.
305+ ///
306+ /// This method should really only be called if the caller knows that the `ListViewArray` will
307+ /// be converted into a [`ListArray`] in the future, and the caller wants to set the
308+ /// optimization flag to `true` with the unsafe [`with_zero_copy_to_list`] method.
309+ ///
310+ /// [`ListArray`]: crate::arrays::ListArray
311+ /// [`with_zero_copy_to_list`]: Self::with_zero_copy_to_list
312+ pub fn verify_is_zero_copy_to_list ( & self ) -> bool {
313+ validate_zctl (
314+ & self . elements ,
315+ self . offsets . to_primitive ( ) ,
316+ self . sizes . to_primitive ( ) ,
317+ )
318+ . is_ok ( )
274319 }
275320
276321 /// Returns the offset at the given index.
0 commit comments