vortex_vector/primitive/
generic_mut.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4//! Definition and implementation of [`PVectorMut<T>`].
5
6use vortex_buffer::BufferMut;
7use vortex_dtype::NativePType;
8use vortex_error::VortexExpect;
9use vortex_error::VortexResult;
10use vortex_error::vortex_ensure;
11use vortex_mask::MaskMut;
12
13use crate::VectorMutOps;
14use crate::VectorOps;
15use crate::primitive::PScalar;
16use crate::primitive::PVector;
17
18/// A mutable vector of generic primitive values.
19///
20/// `T` is expected to be bound by [`NativePType`], which templates an internal [`BufferMut<T>`]
21/// that stores the elements of the vector.
22#[derive(Debug, Clone)]
23pub struct PVectorMut<T> {
24    /// The mutable buffer representing the vector elements.
25    pub(super) elements: BufferMut<T>,
26    /// The validity mask (where `true` represents an element is **not** null).
27    pub(super) validity: MaskMut,
28}
29
30impl<T> PVectorMut<T> {
31    /// Creates a new [`PVectorMut<T>`] from the given elements buffer and validity mask.
32    ///
33    /// # Panics
34    ///
35    /// Panics if the length of the validity mask does not match the length of the elements buffer.
36    pub fn new(elements: BufferMut<T>, validity: MaskMut) -> Self {
37        Self::try_new(elements, validity).vortex_expect("Failed to create `PVectorMut`")
38    }
39
40    /// Tries to create a new [`PVectorMut<T>`] from the given elements buffer and validity mask.
41    ///
42    /// # Errors
43    ///
44    /// Returns an error if the length of the validity mask does not match the length of the
45    /// elements buffer.
46    pub fn try_new(elements: BufferMut<T>, validity: MaskMut) -> VortexResult<Self> {
47        vortex_ensure!(
48            validity.len() == elements.len(),
49            "`PVectorMut` validity mask must have the same length as elements"
50        );
51
52        Ok(Self { elements, validity })
53    }
54
55    /// Creates a new [`PVectorMut<T>`] from the given elements buffer and validity mask without
56    /// validation.
57    ///
58    /// # Safety
59    ///
60    /// The caller must ensure that the validity mask has the same length as the elements buffer.
61    ///
62    /// Ideally, they are taken from `into_parts`, mutated in a way that doesn't re-allocate, and
63    /// then passed back to this function.
64    pub unsafe fn new_unchecked(elements: BufferMut<T>, validity: MaskMut) -> Self {
65        if cfg!(debug_assertions) {
66            Self::new(elements, validity)
67        } else {
68            Self { elements, validity }
69        }
70    }
71
72    /// Create a new mutable primitive vector with the given capacity.
73    pub fn with_capacity(capacity: usize) -> Self {
74        Self {
75            elements: BufferMut::with_capacity(capacity),
76            validity: MaskMut::with_capacity(capacity),
77        }
78    }
79
80    /// Set the length of the vector.
81    ///
82    /// # Safety
83    ///
84    /// - `new_len` must be less than or equal to [`capacity()`].
85    /// - The elements at `old_len..new_len` must be initialized.
86    ///
87    /// [`capacity()`]: Self::capacity
88    pub unsafe fn set_len(&mut self, new_len: usize) {
89        debug_assert!(new_len < self.elements.capacity());
90        debug_assert!(new_len < self.validity.capacity());
91        unsafe { self.elements.set_len(new_len) };
92        unsafe { self.validity.set_len(new_len) };
93    }
94
95    /// Returns a mutable reference to the elements buffer.
96    ///
97    /// # Safety
98    ///
99    /// The caller must ensure that any mutations to the elements do not violate the
100    /// invariants of the vector (e.g., the length must remain consistent with the elements buffer).
101    pub unsafe fn elements_mut(&mut self) -> &mut BufferMut<T> {
102        &mut self.elements
103    }
104
105    /// Returns a mutable reference to the validity mask.
106    ///
107    /// # Safety
108    ///
109    /// The caller must ensure that any mutations to the validity mask do not violate the
110    /// invariants of the vector (e.g., the length must remain consistent with the elements buffer).
111    pub unsafe fn validity_mut(&mut self) -> &mut MaskMut {
112        &mut self.validity
113    }
114
115    /// Decomposes the primitive vector into its constituent parts (buffer and validity).
116    pub fn into_parts(self) -> (BufferMut<T>, MaskMut) {
117        (self.elements, self.validity)
118    }
119
120    /// Append n values to the vector.
121    pub fn append_values(&mut self, value: T, n: usize)
122    where
123        T: Copy,
124    {
125        self.elements.push_n(value, n);
126        self.validity.append_n(true, n);
127    }
128}
129
130impl<T: NativePType> VectorMutOps for PVectorMut<T> {
131    type Immutable = PVector<T>;
132
133    fn len(&self) -> usize {
134        self.elements.len()
135    }
136
137    fn validity(&self) -> &MaskMut {
138        &self.validity
139    }
140
141    fn capacity(&self) -> usize {
142        self.elements.capacity()
143    }
144
145    fn reserve(&mut self, additional: usize) {
146        self.elements.reserve(additional);
147        self.validity.reserve(additional);
148    }
149
150    fn clear(&mut self) {
151        self.elements.clear();
152        self.validity.clear();
153    }
154
155    fn truncate(&mut self, len: usize) {
156        self.elements.truncate(len);
157        self.validity.truncate(len);
158    }
159
160    /// Extends the vector by appending elements from another vector.
161    fn extend_from_vector(&mut self, other: &PVector<T>) {
162        self.elements.extend_from_slice(other.elements.as_slice());
163        self.validity.append_mask(other.validity());
164    }
165
166    fn append_nulls(&mut self, n: usize) {
167        self.elements.push_n(T::zero(), n); // Note that the value we push doesn't actually matter.
168        self.validity.append_n(false, n);
169    }
170
171    fn append_zeros(&mut self, n: usize) {
172        self.elements.push_n(T::zero(), n);
173        self.validity.append_n(true, n);
174    }
175
176    fn append_scalars(&mut self, scalar: &PScalar<T>, n: usize) {
177        match scalar.value() {
178            None => {
179                self.append_nulls(n);
180            }
181            Some(v) => {
182                self.append_values(v, n);
183            }
184        }
185    }
186
187    /// Freeze the vector into an immutable one.
188    fn freeze(self) -> PVector<T> {
189        PVector {
190            elements: self.elements.freeze(),
191            validity: self.validity.freeze(),
192        }
193    }
194
195    fn split_off(&mut self, at: usize) -> Self {
196        Self {
197            elements: self.elements.split_off(at),
198            validity: self.validity.split_off(at),
199        }
200    }
201
202    fn unsplit(&mut self, other: Self) {
203        if self.is_empty() {
204            *self = other;
205            return;
206        }
207        self.elements.unsplit(other.elements);
208        self.validity.unsplit(other.validity);
209    }
210}