33
44//! Definition and implementation of [`FixedSizeListVector`].
55
6- use crate :: { FixedSizeListVectorMut , VectorOps } ;
6+ use std:: sync:: Arc ;
7+
8+ use vortex_error:: { VortexExpect , VortexResult , vortex_ensure} ;
9+ use vortex_mask:: Mask ;
10+
11+ use crate :: { FixedSizeListVectorMut , Vector , VectorOps } ;
712
813/// An immutable vector of fixed-size lists.
914///
@@ -13,23 +18,164 @@ use crate::{FixedSizeListVectorMut, VectorOps};
1318///
1419/// See the documentation for [`FixedSizeListVectorMut`] for more information.
1520#[ derive( Debug , Clone ) ]
16- pub struct FixedSizeListVector ;
21+ pub struct FixedSizeListVector {
22+ /// The child vector of elements.
23+ pub ( super ) elements : Arc < Vector > ,
24+
25+ /// The size of every list in the vector.
26+ pub ( super ) list_size : u32 ,
27+
28+ /// The validity mask (where `true` represents a list is **not** null).
29+ ///
30+ /// Note that the `elements` vector will have its own internal validity, denoting if individual
31+ /// list elements are null.
32+ pub ( super ) validity : Mask ,
33+
34+ /// The length of the vector (which is the same as the length of the validity mask).
35+ ///
36+ /// This is stored here as a convenience, as the validity also tracks this information.
37+ pub ( super ) len : usize ,
38+ }
39+
40+ impl FixedSizeListVector {
41+ /// Creates a new [`FixedSizeListVector`] from the given `elements` vector, size of each list,
42+ /// and validity mask.
43+ ///
44+ /// # Panics
45+ ///
46+ /// Panics if the length of the `validity` mask multiplied by the `list_size` is not
47+ /// equal to the length of the `elements` vector.
48+ ///
49+ /// Put another way, the length of the `elements` vector divided by the `list_size` must be
50+ /// equal to the length of the validity, or this function will panic.
51+ pub fn new ( elements : Arc < Vector > , list_size : u32 , validity : Mask ) -> Self {
52+ Self :: try_new ( elements, list_size, validity)
53+ . vortex_expect ( "Failed to create `FixedSizeListVector`" )
54+ }
55+
56+ /// Tries to create a new [`FixedSizeListVector`] from the given `elements` vector, size of each
57+ /// list, and validity mask.
58+ ///
59+ /// # Errors
60+ ///
61+ /// Returns and error if the length of the `validity` mask multiplied by the `list_size` is not
62+ /// equal to the length of the `elements` vector.
63+ ///
64+ /// Put another way, the length of the `elements` vector divided by the `list_size` must be
65+ /// equal to the length of the validity.
66+ pub fn try_new ( elements : Arc < Vector > , list_size : u32 , validity : Mask ) -> VortexResult < Self > {
67+ let len = validity. len ( ) ;
68+ let elements_len = elements. len ( ) ;
69+
70+ if list_size == 0 {
71+ vortex_ensure ! (
72+ elements. is_empty( ) ,
73+ "A degenerate (`list_size == 0`) `FixedSizeListVector` should have no underlying elements" ,
74+ ) ;
75+ } else {
76+ vortex_ensure ! (
77+ list_size as usize * len == elements_len,
78+ "Tried to create a `FixedSizeListVector` of length {len} and list_size {list_size} \
79+ with an child vector of size {elements_len} ({list_size} * {len} != {elements_len})",
80+ ) ;
81+ }
82+
83+ Ok ( Self {
84+ elements,
85+ list_size,
86+ validity,
87+ len,
88+ } )
89+ }
90+
91+ /// Tries to create a new [`FixedSizeListVector`] from the given `elements` vector, size of each
92+ /// list, and validity mask without validation.
93+ ///
94+ /// # Safety
95+ ///
96+ /// The caller must ensure that the length of the `validity` mask multiplied by the `list_size`
97+ /// is exactly equal to the length of the `elements` vector.
98+ pub unsafe fn new_unchecked ( elements : Arc < Vector > , list_size : u32 , validity : Mask ) -> Self {
99+ let len = validity. len ( ) ;
100+
101+ if cfg ! ( debug_assertions) {
102+ Self :: new ( elements, list_size, validity)
103+ } else {
104+ Self {
105+ elements,
106+ list_size,
107+ validity,
108+ len,
109+ }
110+ }
111+ }
112+
113+ /// Decomposes the `FixedSizeListVector` into its constituent parts (child elements, list size,
114+ /// and validity).
115+ pub fn into_parts ( self ) -> ( Arc < Vector > , u32 , Mask ) {
116+ ( self . elements , self . list_size , self . validity )
117+ }
118+
119+ /// Returns the child vector of elements, which represents the contiguous fixed-size lists of
120+ /// the `FixedSizeListVector`.
121+ pub fn elements ( & self ) -> & Arc < Vector > {
122+ & self . elements
123+ }
124+
125+ /// Returns the size of every list in the vector.
126+ pub fn list_size ( & self ) -> u32 {
127+ self . list_size
128+ }
129+ }
17130
18131impl VectorOps for FixedSizeListVector {
19132 type Mutable = FixedSizeListVectorMut ;
20133
21134 fn len ( & self ) -> usize {
22- todo ! ( )
135+ self . len
23136 }
24137
25- fn validity ( & self ) -> & vortex_mask :: Mask {
26- todo ! ( )
138+ fn validity ( & self ) -> & Mask {
139+ & self . validity
27140 }
28141
29142 fn try_into_mut ( self ) -> Result < Self :: Mutable , Self >
30143 where
31144 Self : Sized ,
32145 {
33- todo ! ( )
146+ let len = self . len ;
147+ let list_size = self . list_size ;
148+
149+ let elements = match Arc :: try_unwrap ( self . elements ) {
150+ Ok ( elements) => elements,
151+ Err ( elements) => return Err ( FixedSizeListVector { elements, ..self } ) ,
152+ } ;
153+
154+ let validity = match self . validity . try_into_mut ( ) {
155+ Ok ( validity) => validity,
156+ Err ( validity) => {
157+ return Err ( FixedSizeListVector {
158+ elements : Arc :: new ( elements) ,
159+ list_size,
160+ validity,
161+ len,
162+ } ) ;
163+ }
164+ } ;
165+
166+ match elements. try_into_mut ( ) {
167+ Ok ( mutable_elements) => Ok ( FixedSizeListVectorMut {
168+ elements : Box :: new ( mutable_elements) ,
169+ list_size,
170+ validity,
171+ len,
172+ } ) ,
173+ Err ( elements) => Err ( FixedSizeListVector {
174+ elements : Arc :: new ( elements) ,
175+ list_size,
176+ validity : validity. freeze ( ) ,
177+ len,
178+ } ) ,
179+ }
34180 }
35181}
0 commit comments