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}