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