Skip to content

Commit d7bead6

Browse files
committed
implement operations for FixedSizeList vectors
Adds `VectorOps` implementations for `FixedSizeList` vectors plus other convenient methods. Signed-off-by: Connor Tsui <[email protected]>
1 parent 8ec8fa9 commit d7bead6

File tree

4 files changed

+359
-25
lines changed

4 files changed

+359
-25
lines changed

vortex-vector/src/fixed_size_list/vector.rs

Lines changed: 152 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
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

18131
impl 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

Comments
 (0)