@@ -38,17 +38,12 @@ pub struct Inlined {
38
38
}
39
39
40
40
impl 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 {
47
42
let mut inlined = Self {
48
- size : value . len ( ) . try_into ( ) . vortex_unwrap ( ) ,
43
+ size : N . try_into ( ) . vortex_unwrap ( ) ,
49
44
data : [ 0u8 ; BinaryView :: MAX_INLINED_SIZE ] ,
50
45
} ;
51
- inlined. data [ ..value . len ( ) ] . copy_from_slice ( value) ;
46
+ inlined. data [ ..N ] . copy_from_slice ( & value[ .. N ] ) ;
52
47
inlined
53
48
}
54
49
@@ -120,29 +115,82 @@ assert_eq_align!(BinaryView, u128);
120
115
impl BinaryView {
121
116
pub const MAX_INLINED_SIZE : usize = 12 ;
122
117
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
+ } ,
126
175
}
127
176
}
128
177
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]
129
186
pub fn new_inlined ( value : & [ u8 ] ) -> Self {
130
187
assert ! (
131
188
value. len( ) <= Self :: MAX_INLINED_SIZE ,
132
189
"expected inlined value to be <= 12 bytes, was {}" ,
133
190
value. len( )
134
191
) ;
135
192
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 )
146
194
}
147
195
148
196
#[ inline]
@@ -183,12 +231,14 @@ impl BinaryView {
183
231
} else {
184
232
// Referencing views must have their buffer_index adjusted with new offsets
185
233
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
+ }
192
242
}
193
243
}
194
244
}
0 commit comments