@@ -38,17 +38,12 @@ pub struct Inlined {
3838}
3939
4040impl Inlined {
41- pub fn new ( value : & [ u8 ] ) -> Self {
42- assert ! (
43- value. len( ) <= BinaryView :: MAX_INLINED_SIZE ,
44- "Inlined strings must be shorter than 13 characters, {} given" ,
45- value. len( )
46- ) ;
41+ fn new < const N : usize > ( value : & [ u8 ] ) -> Self {
4742 let mut inlined = Self {
48- size : value . len ( ) . try_into ( ) . vortex_unwrap ( ) ,
43+ size : N . try_into ( ) . vortex_unwrap ( ) ,
4944 data : [ 0u8 ; BinaryView :: MAX_INLINED_SIZE ] ,
5045 } ;
51- inlined. data [ ..value . len ( ) ] . copy_from_slice ( value) ;
46+ inlined. data [ ..N ] . copy_from_slice ( & value[ .. N ] ) ;
5247 inlined
5348 }
5449
@@ -120,29 +115,82 @@ assert_eq_align!(BinaryView, u128);
120115impl BinaryView {
121116 pub const MAX_INLINED_SIZE : usize = 12 ;
122117
123- pub fn empty_view ( ) -> Self {
124- Self {
125- inlined : Inlined :: new ( & [ ] ) ,
118+ /// Create a view from a value, block and offset
119+ ///
120+ /// Depending on the length of the provided value either a new inlined
121+ /// or a reference view will be constructed.
122+ ///
123+ /// Adapted from arrow-rs <https://github.com/apache/arrow-rs/blob/f4fde769ab6e1a9b75f890b7f8b47bc22800830b/arrow-array/src/builder/generic_bytes_view_builder.rs#L524>
124+ /// Explicitly enumerating inlined view produces code that avoids calling generic `ptr::copy_non_interleave` that's slower than explicit stores
125+ #[ inline( never) ]
126+ pub fn make_view ( value : & [ u8 ] , block : u32 , offset : u32 ) -> Self {
127+ match value. len ( ) {
128+ 0 => Self {
129+ inlined : Inlined :: new :: < 0 > ( value) ,
130+ } ,
131+ 1 => Self {
132+ inlined : Inlined :: new :: < 1 > ( value) ,
133+ } ,
134+ 2 => Self {
135+ inlined : Inlined :: new :: < 2 > ( value) ,
136+ } ,
137+ 3 => Self {
138+ inlined : Inlined :: new :: < 3 > ( value) ,
139+ } ,
140+ 4 => Self {
141+ inlined : Inlined :: new :: < 4 > ( value) ,
142+ } ,
143+ 5 => Self {
144+ inlined : Inlined :: new :: < 5 > ( value) ,
145+ } ,
146+ 6 => Self {
147+ inlined : Inlined :: new :: < 6 > ( value) ,
148+ } ,
149+ 7 => Self {
150+ inlined : Inlined :: new :: < 7 > ( value) ,
151+ } ,
152+ 8 => Self {
153+ inlined : Inlined :: new :: < 8 > ( value) ,
154+ } ,
155+ 9 => Self {
156+ inlined : Inlined :: new :: < 9 > ( value) ,
157+ } ,
158+ 10 => Self {
159+ inlined : Inlined :: new :: < 10 > ( value) ,
160+ } ,
161+ 11 => Self {
162+ inlined : Inlined :: new :: < 11 > ( value) ,
163+ } ,
164+ 12 => Self {
165+ inlined : Inlined :: new :: < 12 > ( value) ,
166+ } ,
167+ _ => Self {
168+ _ref : Ref :: new (
169+ u32:: try_from ( value. len ( ) ) . vortex_unwrap ( ) ,
170+ value[ 0 ..4 ] . try_into ( ) . vortex_unwrap ( ) ,
171+ block,
172+ offset,
173+ ) ,
174+ } ,
126175 }
127176 }
128177
178+ /// Create a new empty view
179+ #[ inline]
180+ pub fn empty_view ( ) -> Self {
181+ Self :: new_inlined ( & [ ] )
182+ }
183+
184+ /// Create a new inlined binary view
185+ #[ inline]
129186 pub fn new_inlined ( value : & [ u8 ] ) -> Self {
130187 assert ! (
131188 value. len( ) <= Self :: MAX_INLINED_SIZE ,
132189 "expected inlined value to be <= 12 bytes, was {}" ,
133190 value. len( )
134191 ) ;
135192
136- Self {
137- inlined : Inlined :: new ( value) ,
138- }
139- }
140-
141- /// Create a new view over bytes stored in a block.
142- pub fn new_view ( len : u32 , prefix : [ u8 ; 4 ] , block : u32 , offset : u32 ) -> Self {
143- Self {
144- _ref : Ref :: new ( len, prefix, block, offset) ,
145- }
193+ Self :: make_view ( value, 0 , 0 )
146194 }
147195
148196 #[ inline]
@@ -183,12 +231,14 @@ impl BinaryView {
183231 } else {
184232 // Referencing views must have their buffer_index adjusted with new offsets
185233 let view_ref = self . as_view ( ) ;
186- BinaryView :: new_view (
187- self . len ( ) ,
188- * view_ref. prefix ( ) ,
189- offset + view_ref. buffer_index ( ) ,
190- view_ref. offset ( ) ,
191- )
234+ Self {
235+ _ref : Ref :: new (
236+ self . len ( ) ,
237+ * view_ref. prefix ( ) ,
238+ offset + view_ref. buffer_index ( ) ,
239+ view_ref. offset ( ) ,
240+ ) ,
241+ }
192242 }
193243 }
194244}
0 commit comments