11// SPDX-License-Identifier: Apache-2.0
22// SPDX-FileCopyrightText: Copyright the Vortex contributors
33
4+ //! Definition and implementation of [`DVectorMut<D>`].
5+
46use vortex_buffer:: BufferMut ;
5- use vortex_dtype:: { NativeDecimalType , PrecisionScale } ;
6- use vortex_error:: { VortexResult , vortex_bail} ;
7+ use vortex_dtype:: { DecimalDType , NativeDecimalType , PrecisionScale } ;
8+ use vortex_error:: { VortexExpect , VortexResult , vortex_bail} ;
79use vortex_mask:: MaskMut ;
810
911use crate :: { DVector , VectorMutOps , VectorOps } ;
1012
1113/// A specifically typed mutable decimal vector.
1214#[ derive( Debug , Clone ) ]
1315pub struct DVectorMut < D > {
16+ /// The precision and scale of each decimal in the decimal vector.
1417 pub ( super ) ps : PrecisionScale < D > ,
18+ /// The mutable buffer representing the vector decimal elements.
1519 pub ( super ) elements : BufferMut < D > ,
20+ /// The validity mask (where `true` represents an element is **not** null).
1621 pub ( super ) validity : MaskMut ,
1722}
1823
1924impl < D : NativeDecimalType > DVectorMut < D > {
25+ /// Creates a new [`DVectorMut<D>`] from the given [`PrecisionScale`], elements buffer, and
26+ /// validity mask.
27+ ///
28+ /// # Panics
29+ ///
30+ /// Panics if:
31+ ///
32+ /// - The lengths of the `elements` and `validity` do not match.
33+ /// - Any of the elements are out of bounds for the given [`PrecisionScale`].
34+ pub fn new ( ps : PrecisionScale < D > , elements : BufferMut < D > , validity : MaskMut ) -> Self {
35+ Self :: try_new ( ps, elements, validity) . vortex_expect ( "Failed to create `DVector`" )
36+ }
37+
38+ /// Tries to create a new [`DVectorMut<D>`] from the given [`PrecisionScale`], elements buffer,
39+ /// and validity mask.
40+ ///
41+ /// # Errors
42+ ///
43+ /// Returns an error if:
44+ ///
45+ /// - The lengths of the `elements` and `validity` do not match.
46+ /// - Any of the elements are out of bounds for the given [`PrecisionScale`].
47+ pub fn try_new (
48+ ps : PrecisionScale < D > ,
49+ elements : BufferMut < D > ,
50+ validity : MaskMut ,
51+ ) -> VortexResult < Self > {
52+ if elements. len ( ) != validity. len ( ) {
53+ vortex_bail ! (
54+ "Elements length {} does not match validity length {}" ,
55+ elements. len( ) ,
56+ validity. len( )
57+ ) ;
58+ }
59+
60+ // We assert that each element is within bounds for the given precision/scale.
61+ if !elements. iter ( ) . all ( |e| ps. is_valid ( * e) ) {
62+ vortex_bail ! (
63+ "One or more elements are out of bounds for precision {} and scale {}" ,
64+ ps. precision( ) ,
65+ ps. scale( )
66+ ) ;
67+ }
68+
69+ Ok ( Self {
70+ ps,
71+ elements,
72+ validity,
73+ } )
74+ }
75+
76+ /// Creates a new [`DVectorMut<D>`] from the given [`PrecisionScale`], elements buffer, and
77+ /// validity mask, _without_ validation.
78+ ///
79+ /// # Safety
80+ ///
81+ /// The caller must ensure:
82+ ///
83+ /// - The lengths of the elements and validity are equal.
84+ /// - All elements are in bounds for the given [`PrecisionScale`].
85+ pub unsafe fn new_unchecked (
86+ ps : PrecisionScale < D > ,
87+ elements : BufferMut < D > ,
88+ validity : MaskMut ,
89+ ) -> Self {
90+ if cfg ! ( debug_assertions) {
91+ Self :: try_new ( ps, elements, validity) . vortex_expect ( "Failed to create `DVectorMut`" )
92+ } else {
93+ Self {
94+ ps,
95+ elements,
96+ validity,
97+ }
98+ }
99+ }
100+
101+ /// Create a new mutable primitive vector with the given capacity.
102+ pub fn with_capacity ( decimal_dtype : & DecimalDType , capacity : usize ) -> Self {
103+ Self {
104+ ps : PrecisionScale :: try_from ( decimal_dtype)
105+ . vortex_expect ( "TODO(someone): This definitely should not be fallible" ) ,
106+ elements : BufferMut :: with_capacity ( capacity) ,
107+ validity : MaskMut :: with_capacity ( capacity) ,
108+ }
109+ }
110+
111+ /// Decomposes the decimal vector into its constituent parts ([`PrecisionScale`], decimal
112+ /// buffer, and validity).
113+ pub fn into_parts ( self ) -> ( PrecisionScale < D > , BufferMut < D > , MaskMut ) {
114+ ( self . ps , self . elements , self . validity )
115+ }
116+
20117 /// Get the precision/scale of the decimal vector.
21118 pub fn precision_scale ( & self ) -> PrecisionScale < D > {
22119 self . ps
23120 }
24121
25- /// Get a nullable element at the given index.
122+ /// Returns a reference to the underlying elements buffer containing the decimal data.
123+ pub fn elements ( & self ) -> & BufferMut < D > {
124+ & self . elements
125+ }
126+
127+ /// Returns a mutable reference to the underlying elements buffer containing the decimal data.
128+ ///
129+ /// # Safety
130+ ///
131+ /// Modifying the elements buffer directly may violate the precision/scale constraints.
132+ /// The caller must ensure that any modifications maintain these invariants.
133+ pub unsafe fn elements_mut ( & mut self ) -> & mut BufferMut < D > {
134+ & mut self . elements
135+ }
136+
137+ /// Gets a nullable element at the given index, **WITHOUT** bounds checking.
138+ ///
139+ /// If the element at the given index is null, returns `None`. Otherwise, returns `Some(x)`,
140+ /// where `x: D`.
141+ ///
142+ /// Note that this `get` method is different from the standard library [`slice::get`], which
143+ /// returns `None` if the index is out of bounds. This method will panic if the index is out of
144+ /// bounds, and return `None` if the elements is null.
145+ ///
146+ /// # Panics
147+ ///
148+ /// Panics if the index is out of bounds.
26149 pub fn get ( & self , index : usize ) -> Option < & D > {
27150 self . validity . value ( index) . then ( || & self . elements [ index] )
28151 }
@@ -41,16 +164,6 @@ impl<D: NativeDecimalType> DVectorMut<D> {
41164 self . validity . append_n ( true , 1 ) ;
42165 Ok ( ( ) )
43166 }
44-
45- /// Returns a mutable reference to the underlying elements buffer.
46- ///
47- /// # Safety
48- ///
49- /// Modifying the elements buffer directly may violate the precision/scale constraints.
50- /// The caller must ensure that any modifications maintain these invariants.
51- pub unsafe fn elements_mut ( & mut self ) -> & mut [ D ] {
52- & mut self . elements
53- }
54167}
55168
56169impl < D : NativeDecimalType > AsRef < [ D ] > for DVectorMut < D > {
0 commit comments