1use crate::array::PrimitiveArray;
19use crate::null_sentinel;
20use arrow_array::{ArrowPrimitiveType, BooleanArray, FixedSizeBinaryArray};
21use arrow_buffer::{
22 BooleanBuffer, IntervalDayTime, IntervalMonthDayNano, MutableBuffer, NullBuffer, bit_util, i256,
23};
24use arrow_schema::{DataType, SortOptions};
25use half::f16;
26
27pub trait FromSlice {
28 fn from_slice(slice: &[u8], invert: bool) -> Self;
29}
30
31impl<const N: usize> FromSlice for [u8; N] {
32 #[inline]
33 fn from_slice(slice: &[u8], invert: bool) -> Self {
34 let mut t: Self = slice.try_into().unwrap();
35 if invert {
36 t.iter_mut().for_each(|o| *o = !*o);
37 }
38 t
39 }
40}
41
42pub trait FixedLengthEncoding: Copy {
45 const ENCODED_LEN: usize = 1 + std::mem::size_of::<Self::Encoded>();
46
47 type Encoded: Sized + Copy + FromSlice + AsRef<[u8]> + AsMut<[u8]>;
48
49 fn encode(self) -> Self::Encoded;
50
51 fn decode(encoded: Self::Encoded) -> Self;
52}
53
54impl FixedLengthEncoding for bool {
55 type Encoded = [u8; 1];
56
57 fn encode(self) -> [u8; 1] {
58 [self as u8]
59 }
60
61 fn decode(encoded: Self::Encoded) -> Self {
62 encoded[0] != 0
63 }
64}
65
66macro_rules! encode_signed {
67 ($n:expr, $t:ty) => {
68 impl FixedLengthEncoding for $t {
69 type Encoded = [u8; $n];
70
71 fn encode(self) -> [u8; $n] {
72 let mut b = self.to_be_bytes();
73 b[0] ^= 0x80;
75 b
76 }
77
78 fn decode(mut encoded: Self::Encoded) -> Self {
79 encoded[0] ^= 0x80;
81 Self::from_be_bytes(encoded)
82 }
83 }
84 };
85}
86
87encode_signed!(1, i8);
88encode_signed!(2, i16);
89encode_signed!(4, i32);
90encode_signed!(8, i64);
91encode_signed!(16, i128);
92encode_signed!(32, i256);
93
94macro_rules! encode_unsigned {
95 ($n:expr, $t:ty) => {
96 impl FixedLengthEncoding for $t {
97 type Encoded = [u8; $n];
98
99 fn encode(self) -> [u8; $n] {
100 self.to_be_bytes()
101 }
102
103 fn decode(encoded: Self::Encoded) -> Self {
104 Self::from_be_bytes(encoded)
105 }
106 }
107 };
108}
109
110encode_unsigned!(1, u8);
111encode_unsigned!(2, u16);
112encode_unsigned!(4, u32);
113encode_unsigned!(8, u64);
114
115impl FixedLengthEncoding for f16 {
116 type Encoded = [u8; 2];
117
118 fn encode(self) -> [u8; 2] {
119 let s = self.to_bits() as i16;
121 let val = s ^ (((s >> 15) as u16) >> 1) as i16;
122 val.encode()
123 }
124
125 fn decode(encoded: Self::Encoded) -> Self {
126 let bits = i16::decode(encoded);
127 let val = bits ^ (((bits >> 15) as u16) >> 1) as i16;
128 Self::from_bits(val as u16)
129 }
130}
131
132impl FixedLengthEncoding for f32 {
133 type Encoded = [u8; 4];
134
135 fn encode(self) -> [u8; 4] {
136 let s = self.to_bits() as i32;
138 let val = s ^ (((s >> 31) as u32) >> 1) as i32;
139 val.encode()
140 }
141
142 fn decode(encoded: Self::Encoded) -> Self {
143 let bits = i32::decode(encoded);
144 let val = bits ^ (((bits >> 31) as u32) >> 1) as i32;
145 Self::from_bits(val as u32)
146 }
147}
148
149impl FixedLengthEncoding for f64 {
150 type Encoded = [u8; 8];
151
152 fn encode(self) -> [u8; 8] {
153 let s = self.to_bits() as i64;
155 let val = s ^ (((s >> 63) as u64) >> 1) as i64;
156 val.encode()
157 }
158
159 fn decode(encoded: Self::Encoded) -> Self {
160 let bits = i64::decode(encoded);
161 let val = bits ^ (((bits >> 63) as u64) >> 1) as i64;
162 Self::from_bits(val as u64)
163 }
164}
165
166impl FixedLengthEncoding for IntervalDayTime {
167 type Encoded = [u8; 8];
168
169 fn encode(self) -> Self::Encoded {
170 let mut out = [0_u8; 8];
171 out[..4].copy_from_slice(&self.days.encode());
172 out[4..].copy_from_slice(&self.milliseconds.encode());
173 out
174 }
175
176 fn decode(encoded: Self::Encoded) -> Self {
177 Self {
178 days: i32::decode(encoded[..4].try_into().unwrap()),
179 milliseconds: i32::decode(encoded[4..].try_into().unwrap()),
180 }
181 }
182}
183
184impl FixedLengthEncoding for IntervalMonthDayNano {
185 type Encoded = [u8; 16];
186
187 fn encode(self) -> Self::Encoded {
188 let mut out = [0_u8; 16];
189 out[..4].copy_from_slice(&self.months.encode());
190 out[4..8].copy_from_slice(&self.days.encode());
191 out[8..].copy_from_slice(&self.nanoseconds.encode());
192 out
193 }
194
195 fn decode(encoded: Self::Encoded) -> Self {
196 Self {
197 months: i32::decode(encoded[..4].try_into().unwrap()),
198 days: i32::decode(encoded[4..8].try_into().unwrap()),
199 nanoseconds: i64::decode(encoded[8..].try_into().unwrap()),
200 }
201 }
202}
203
204pub const fn encoded_len<T>(_col: &PrimitiveArray<T>) -> usize
206where
207 T: ArrowPrimitiveType,
208 T::Native: FixedLengthEncoding,
209{
210 T::Native::ENCODED_LEN
211}
212
213pub fn encode<T: FixedLengthEncoding>(
218 data: &mut [u8],
219 offsets: &mut [usize],
220 values: &[T],
221 nulls: &NullBuffer,
222 opts: SortOptions,
223) {
224 let null_sentinel = null_sentinel(opts);
225 for (value_idx, is_valid) in nulls.iter().enumerate() {
226 let offset = &mut offsets[value_idx + 1];
227 let end_offset = *offset + T::ENCODED_LEN;
228 if is_valid {
229 let to_write = &mut data[*offset..end_offset];
230 to_write[0] = 1;
231 let mut encoded = values[value_idx].encode();
232 if opts.descending {
233 encoded.as_mut().iter_mut().for_each(|v| *v = !*v)
235 }
236 to_write[1..].copy_from_slice(encoded.as_ref())
237 } else {
238 data[*offset] = null_sentinel;
239 }
240 *offset = end_offset;
241 }
242}
243
244pub fn encode_not_null<T: FixedLengthEncoding>(
247 data: &mut [u8],
248 offsets: &mut [usize],
249 values: &[T],
250 opts: SortOptions,
251) {
252 for (value_idx, val) in values.iter().enumerate() {
253 let offset = &mut offsets[value_idx + 1];
254 let end_offset = *offset + T::ENCODED_LEN;
255
256 let to_write = &mut data[*offset..end_offset];
257 to_write[0] = 1;
258 let mut encoded = val.encode();
259 if opts.descending {
260 encoded.as_mut().iter_mut().for_each(|v| *v = !*v)
262 }
263 to_write[1..].copy_from_slice(encoded.as_ref());
264
265 *offset = end_offset;
266 }
267}
268
269pub fn encode_boolean(
274 data: &mut [u8],
275 offsets: &mut [usize],
276 values: &BooleanBuffer,
277 nulls: &NullBuffer,
278 opts: SortOptions,
279) {
280 let null_sentinel = null_sentinel(opts);
281 for (idx, is_valid) in nulls.iter().enumerate() {
282 let offset = &mut offsets[idx + 1];
283 let end_offset = *offset + bool::ENCODED_LEN;
284 if is_valid {
285 let to_write = &mut data[*offset..end_offset];
286 to_write[0] = 1;
287 let mut encoded = values.value(idx).encode();
288 if opts.descending {
289 encoded.as_mut().iter_mut().for_each(|v| *v = !*v)
291 }
292 to_write[1..].copy_from_slice(encoded.as_ref())
293 } else {
294 data[*offset] = null_sentinel;
295 }
296 *offset = end_offset;
297 }
298}
299
300pub fn encode_boolean_not_null(
303 data: &mut [u8],
304 offsets: &mut [usize],
305 values: &BooleanBuffer,
306 opts: SortOptions,
307) {
308 for (value_idx, val) in values.iter().enumerate() {
309 let offset = &mut offsets[value_idx + 1];
310 let end_offset = *offset + bool::ENCODED_LEN;
311
312 let to_write = &mut data[*offset..end_offset];
313 to_write[0] = 1;
314 let mut encoded = val.encode();
315 if opts.descending {
316 encoded.as_mut().iter_mut().for_each(|v| *v = !*v)
318 }
319 to_write[1..].copy_from_slice(encoded.as_ref());
320
321 *offset = end_offset;
322 }
323}
324
325pub fn encode_fixed_size_binary(
326 data: &mut [u8],
327 offsets: &mut [usize],
328 array: &FixedSizeBinaryArray,
329 opts: SortOptions,
330) {
331 let len = array.value_length() as usize;
332 let null_sentinel = null_sentinel(opts);
333 for (offset, maybe_val) in offsets.iter_mut().skip(1).zip(array.iter()) {
334 let end_offset = *offset + len + 1;
335 if let Some(val) = maybe_val {
336 let to_write = &mut data[*offset..end_offset];
337 to_write[0] = 1;
338 to_write[1..].copy_from_slice(&val[..len]);
339 if opts.descending {
340 to_write[1..1 + len].iter_mut().for_each(|v| *v = !*v)
342 }
343 } else {
344 data[*offset] = null_sentinel;
345 }
346 *offset = end_offset;
347 }
348}
349
350#[inline]
352fn split_off<'a>(src: &mut &'a [u8], len: usize) -> &'a [u8] {
353 let v = &src[..len];
354 *src = &src[len..];
355 v
356}
357
358pub fn decode_bool(rows: &mut [&[u8]], options: SortOptions) -> BooleanArray {
360 let true_val = match options.descending {
361 true => !1,
362 false => 1,
363 };
364
365 let len = rows.len();
366
367 let mut nulls = MutableBuffer::new(bit_util::ceil(len, 64) * 8);
368 let mut values = MutableBuffer::new(bit_util::ceil(len, 64) * 8);
369
370 let chunks = len / 64;
371 let remainder = len % 64;
372 for chunk in 0..chunks {
373 let mut null_packed = 0;
374 let mut values_packed = 0;
375
376 for bit_idx in 0..64 {
377 let i = split_off(&mut rows[bit_idx + chunk * 64], 2);
378 let (null, value) = (i[0] == 1, i[1] == true_val);
379 null_packed |= (null as u64) << bit_idx;
380 values_packed |= (value as u64) << bit_idx;
381 }
382
383 nulls.push(null_packed);
384 values.push(values_packed);
385 }
386
387 if remainder != 0 {
388 let mut null_packed = 0;
389 let mut values_packed = 0;
390
391 for bit_idx in 0..remainder {
392 let i = split_off(&mut rows[bit_idx + chunks * 64], 2);
393 let (null, value) = (i[0] == 1, i[1] == true_val);
394 null_packed |= (null as u64) << bit_idx;
395 values_packed |= (value as u64) << bit_idx;
396 }
397
398 nulls.push(null_packed);
399 values.push(values_packed);
400 }
401
402 let nulls = NullBuffer::new(BooleanBuffer::new(nulls.into(), 0, len));
403 let nulls = (nulls.null_count() > 0).then_some(nulls);
404
405 BooleanArray::new(BooleanBuffer::new(values.into(), 0, len), nulls)
406}
407
408pub fn decode_nulls(rows: &[&[u8]]) -> Option<NullBuffer> {
412 let nulls = BooleanBuffer::collect_bool(rows.len(), |idx| rows[idx][0] == 1);
413 let nulls = NullBuffer::new(nulls);
414 (nulls.null_count() > 0).then_some(nulls)
415}
416
417pub fn decode_primitive<T: ArrowPrimitiveType>(
419 rows: &mut [&[u8]],
420 data_type: DataType,
421 options: SortOptions,
422) -> PrimitiveArray<T>
423where
424 T::Native: FixedLengthEncoding,
425{
426 assert!(PrimitiveArray::<T>::is_compatible(&data_type));
427
428 let nulls = decode_nulls(rows);
429 let values = rows
430 .iter_mut()
431 .map(|row| {
432 let i = split_off(row, T::Native::ENCODED_LEN);
433 let value = <T::Native as FixedLengthEncoding>::Encoded::from_slice(
434 &i[1..],
435 options.descending,
436 );
437 T::Native::decode(value)
438 })
439 .collect::<Vec<_>>();
440
441 PrimitiveArray::new(values.into(), nulls).with_data_type(data_type)
442}
443
444pub fn decode_fixed_size_binary(
449 rows: &mut [&[u8]],
450 size: i32,
451 options: SortOptions,
452) -> FixedSizeBinaryArray {
453 if size < 0 {
454 panic!("cannot decode FixedSizeBinary({size})");
455 }
456 let num_rows = rows.len();
457 let mut values = MutableBuffer::new(size as usize * num_rows);
458 let nulls = decode_nulls(rows);
459
460 let encoded_len = size as usize + 1;
461
462 for row in rows {
463 let i = split_off(row, encoded_len);
464 values.extend_from_slice(&i[1..]);
465 }
466
467 if options.descending {
468 for v in values.as_slice_mut() {
469 *v = !*v;
470 }
471 }
472
473 FixedSizeBinaryArray::try_new_with_len(size, values.into(), nulls, num_rows).unwrap()
475}