vortex_vector/vector_ops.rs
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! Definition and implementation of [`VectorOps`] and [`VectorMutOps`] for [`Vector`] and
5//! [`VectorMut`], respectively.
6
7use std::fmt::Debug;
8use std::ops::Bound;
9use std::ops::RangeBounds;
10
11use vortex_mask::Mask;
12use vortex_mask::MaskMut;
13
14use crate::ScalarOps;
15use crate::Vector;
16use crate::VectorMut;
17use crate::private;
18
19/// Common operations for immutable vectors (all the variants of [`Vector`]).
20pub trait VectorOps: private::Sealed + Into<Vector> + Sized {
21 /// The mutable equivalent of this immutable vector.
22 type Mutable: VectorMutOps<Immutable = Self>;
23 /// The scalar type for this vector.
24 type Scalar: ScalarOps;
25
26 /// Returns the number of elements in the vector, also referred to as its "length".
27 fn len(&self) -> usize;
28
29 /// Returns `true` if the vector contains no elements.
30 fn is_empty(&self) -> bool {
31 self.len() == 0
32 }
33
34 /// Returns the validity mask of the vector, where `true` represents a _valid_ element and
35 /// `false` represents a `null` element.
36 ///
37 /// Note that vectors are **always** considered nullable. "Non-nullable" data will simply have a
38 /// [`Mask`] of [`AllTrue(len)`](Mask::AllTrue). It is on the caller to ensure that they do not
39 /// add nullable data to a vector they want to keep as non-nullable.
40 fn validity(&self) -> &Mask;
41
42 /// Masks the validity of the vector with another validity mask.
43 /// The resulting vector's validity is the intersection of the two validity masks.
44 fn mask_validity(&mut self, mask: &Mask);
45
46 /// Returns the null count of the vector.
47 fn null_count(&self) -> usize {
48 self.validity().false_count()
49 }
50
51 /// Return the scalar at the given index.
52 ///
53 /// # Panics
54 ///
55 /// Panics if the index is out of bounds.
56 fn scalar_at(&self, index: usize) -> Self::Scalar;
57
58 /// Slice the vector from `start` to `end` (exclusive).
59 fn slice(&self, range: impl RangeBounds<usize> + Clone + Debug) -> Self;
60
61 /// Clears the vector of data, preserving any existing capacity where possible.
62 fn clear(&mut self);
63
64 /// Tries to convert `self` into a mutable vector (implementing [`VectorMutOps`]).
65 ///
66 /// This method will only succeed if `self` is the only unique strong reference (it effectively
67 /// "owns" the buffer). If this is true, this method will return a mutable vector with the
68 /// contents of `self` **without** any copying of data.
69 ///
70 /// # Errors
71 ///
72 /// If `self` is not unique, this will fail and return `self` back to the caller.
73 fn try_into_mut(self) -> Result<Self::Mutable, Self>;
74
75 /// Converts `self` into a mutable vector (implementing [`VectorMutOps`]).
76 ///
77 /// This method uses "clone-on-write" semantics, meaning it will clone any underlying data that
78 /// has multiple references (preventing mutable access). `into_mut` can be more efficient than
79 /// [`try_into_mut()`] when mutations are infrequent.
80 ///
81 /// The semantics of `into_mut` are somewhat similar to that of [`Arc::make_mut()`], but instead
82 /// of working with references, this works with owned immutable / mutable types.
83 ///
84 /// [`try_into_mut()`]: Self::try_into_mut
85 /// [`Arc::make_mut()`]: std::sync::Arc::make_mut
86 fn into_mut(self) -> Self::Mutable;
87}
88
89/// Common operations for mutable vectors (all the variants of [`VectorMut`]).
90pub trait VectorMutOps: private::Sealed + Into<VectorMut> + Sized {
91 /// The immutable equivalent of this mutable vector.
92 type Immutable: VectorOps<Mutable = Self>;
93
94 /// Returns the number of elements in the vector, also referred to as its "length".
95 fn len(&self) -> usize;
96
97 /// Returns `true` if the vector contains no elements.
98 fn is_empty(&self) -> bool {
99 self.len() == 0
100 }
101
102 /// Returns the validity mask of the vector, where `true` represents a _valid_ element and
103 /// `false` represents a `null` element.
104 ///
105 /// Note that while this returns a [`MaskMut`] (which is typically an owned type), the caller is
106 /// only allowed to inspect it via the shared reference.
107 fn validity(&self) -> &MaskMut;
108
109 /// Returns the total number of elements the vector can hold without reallocating.
110 fn capacity(&self) -> usize;
111
112 /// Reserves capacity for at least `additional` more elements to be inserted in the given
113 /// vector.
114 ///
115 /// The collection may reserve more space to speculatively avoid frequent reallocations. After
116 /// calling `reserve`, the capacity will be greater than or equal to `self.len() + additional`.
117 /// Does nothing if capacity is already sufficient.
118 ///
119 /// Please let us know if you need `reserve_exact` functionality!
120 fn reserve(&mut self, additional: usize);
121
122 /// Clears the buffer, removing all data. Existing capacity is preserved.
123 fn clear(&mut self);
124
125 /// Shortens the buffer, keeping the first len bytes and dropping the rest.
126 ///
127 /// If len is greater than the buffer’s current length, this has no effect.
128 ///
129 /// Existing underlying capacity is preserved.
130 fn truncate(&mut self, len: usize);
131
132 /// Extends the vector by appending elements from another vector.
133 ///
134 /// # Panics
135 ///
136 /// Panics if the `other` vector has the wrong type (for example, a
137 /// [`StructVector`](crate::struct_::StructVector) might have incorrect fields).
138 fn extend_from_vector(&mut self, other: &Self::Immutable);
139
140 /// Appends `n` null elements to the vector.
141 ///
142 /// Implementors should ensure that they correctly append "null" or garbage values to their
143 /// elements in addition to adding nulls to their validity mask.
144 fn append_nulls(&mut self, n: usize);
145
146 /// Appends `n` zero elements to the vector.
147 fn append_zeros(&mut self, n: usize);
148
149 /// Appends `n` scalar values to the vector.
150 ///
151 /// **Warning**: This method has terrible performance. You should prefer to use a typed
152 /// API for building vectors by downcasting into a specific type.
153 fn append_scalars(&mut self, scalar: &<Self::Immutable as VectorOps>::Scalar, n: usize);
154
155 /// Converts `self` into an immutable vector.
156 fn freeze(self) -> Self::Immutable;
157
158 /// Splits the vector into two at the given index.
159 ///
160 /// Afterward, `self` contains elements `[0, at)`, and the returned vector contains elements
161 /// `[at, capacity)`. It's guaranteed that the memory does not move, that is, the address of
162 /// `self` does not change, and the address of the returned slice is at bytes after that.
163 ///
164 /// This is an `O(1)` operation that just increases the reference count and sets a few indices.
165 ///
166 /// # Panics
167 ///
168 /// Panics if we try to split off more than the current capacity of the vector (if
169 /// `at > capacity`).
170 fn split_off(&mut self, at: usize) -> Self;
171
172 /// Absorbs a mutable vector that was previously split off.
173 ///
174 /// If the two vectors were previously contiguous and not mutated in a way that causes
175 /// re-allocation i.e., if other was created by calling [`split_off()`] on this vector, then
176 /// this is an `O(1)` operation (simply decreases a reference count and sets a few indices).
177 ///
178 /// Otherwise, this method falls back to `self.extend_from_vector(other)`.
179 ///
180 /// [`split_off()`]: Self::split_off
181 fn unsplit(&mut self, other: Self);
182}
183
184/// Converts a range bounds into a length, given the total length of the vector.
185pub(crate) fn range_bounds_to_len(bounds: impl RangeBounds<usize> + Debug, len: usize) -> usize {
186 let start = match bounds.start_bound() {
187 Bound::Included(&s) => s,
188 Bound::Excluded(&s) => s + 1,
189 Bound::Unbounded => 0,
190 };
191
192 let end = match bounds.end_bound() {
193 Bound::Included(&e) => e + 1,
194 Bound::Excluded(&e) => e,
195 Bound::Unbounded => len,
196 };
197
198 assert!(
199 start <= end && end <= len,
200 "Range {:?} out of bounds for length {}",
201 bounds,
202 len
203 );
204
205 end - start
206}