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 for (value_idx, is_valid) in nulls.iter().enumerate() {
225 let offset = &mut offsets[value_idx + 1];
226 let end_offset = *offset + T::ENCODED_LEN;
227 if is_valid {
228 let to_write = &mut data[*offset..end_offset];
229 to_write[0] = 1;
230 let mut encoded = values[value_idx].encode();
231 if opts.descending {
232 encoded.as_mut().iter_mut().for_each(|v| *v = !*v)
234 }
235 to_write[1..].copy_from_slice(encoded.as_ref())
236 } else {
237 data[*offset] = null_sentinel(opts);
238 }
239 *offset = end_offset;
240 }
241}
242
243pub fn encode_not_null<T: FixedLengthEncoding>(
246 data: &mut [u8],
247 offsets: &mut [usize],
248 values: &[T],
249 opts: SortOptions,
250) {
251 for (value_idx, val) in values.iter().enumerate() {
252 let offset = &mut offsets[value_idx + 1];
253 let end_offset = *offset + T::ENCODED_LEN;
254
255 let to_write = &mut data[*offset..end_offset];
256 to_write[0] = 1;
257 let mut encoded = val.encode();
258 if opts.descending {
259 encoded.as_mut().iter_mut().for_each(|v| *v = !*v)
261 }
262 to_write[1..].copy_from_slice(encoded.as_ref());
263
264 *offset = end_offset;
265 }
266}
267
268pub fn encode_boolean(
273 data: &mut [u8],
274 offsets: &mut [usize],
275 values: &BooleanBuffer,
276 nulls: &NullBuffer,
277 opts: SortOptions,
278) {
279 for (idx, is_valid) in nulls.iter().enumerate() {
280 let offset = &mut offsets[idx + 1];
281 let end_offset = *offset + bool::ENCODED_LEN;
282 if is_valid {
283 let to_write = &mut data[*offset..end_offset];
284 to_write[0] = 1;
285 let mut encoded = values.value(idx).encode();
286 if opts.descending {
287 encoded.as_mut().iter_mut().for_each(|v| *v = !*v)
289 }
290 to_write[1..].copy_from_slice(encoded.as_ref())
291 } else {
292 data[*offset] = null_sentinel(opts);
293 }
294 *offset = end_offset;
295 }
296}
297
298pub fn encode_boolean_not_null(
301 data: &mut [u8],
302 offsets: &mut [usize],
303 values: &BooleanBuffer,
304 opts: SortOptions,
305) {
306 for (value_idx, val) in values.iter().enumerate() {
307 let offset = &mut offsets[value_idx + 1];
308 let end_offset = *offset + bool::ENCODED_LEN;
309
310 let to_write = &mut data[*offset..end_offset];
311 to_write[0] = 1;
312 let mut encoded = val.encode();
313 if opts.descending {
314 encoded.as_mut().iter_mut().for_each(|v| *v = !*v)
316 }
317 to_write[1..].copy_from_slice(encoded.as_ref());
318
319 *offset = end_offset;
320 }
321}
322
323pub fn encode_fixed_size_binary(
324 data: &mut [u8],
325 offsets: &mut [usize],
326 array: &FixedSizeBinaryArray,
327 opts: SortOptions,
328) {
329 let len = array.value_length() as usize;
330 for (offset, maybe_val) in offsets.iter_mut().skip(1).zip(array.iter()) {
331 let end_offset = *offset + len + 1;
332 if let Some(val) = maybe_val {
333 let to_write = &mut data[*offset..end_offset];
334 to_write[0] = 1;
335 to_write[1..].copy_from_slice(&val[..len]);
336 if opts.descending {
337 to_write[1..1 + len].iter_mut().for_each(|v| *v = !*v)
339 }
340 } else {
341 data[*offset] = null_sentinel(opts);
342 }
343 *offset = end_offset;
344 }
345}
346
347#[inline]
349fn split_off<'a>(src: &mut &'a [u8], len: usize) -> &'a [u8] {
350 let v = &src[..len];
351 *src = &src[len..];
352 v
353}
354
355pub fn decode_bool(rows: &mut [&[u8]], options: SortOptions) -> BooleanArray {
357 let true_val = match options.descending {
358 true => !1,
359 false => 1,
360 };
361
362 let len = rows.len();
363
364 let mut nulls = MutableBuffer::new(bit_util::ceil(len, 64) * 8);
365 let mut values = MutableBuffer::new(bit_util::ceil(len, 64) * 8);
366
367 let chunks = len / 64;
368 let remainder = len % 64;
369 for chunk in 0..chunks {
370 let mut null_packed = 0;
371 let mut values_packed = 0;
372
373 for bit_idx in 0..64 {
374 let i = split_off(&mut rows[bit_idx + chunk * 64], 2);
375 let (null, value) = (i[0] == 1, i[1] == true_val);
376 null_packed |= (null as u64) << bit_idx;
377 values_packed |= (value as u64) << bit_idx;
378 }
379
380 nulls.push(null_packed);
381 values.push(values_packed);
382 }
383
384 if remainder != 0 {
385 let mut null_packed = 0;
386 let mut values_packed = 0;
387
388 for bit_idx in 0..remainder {
389 let i = split_off(&mut rows[bit_idx + chunks * 64], 2);
390 let (null, value) = (i[0] == 1, i[1] == true_val);
391 null_packed |= (null as u64) << bit_idx;
392 values_packed |= (value as u64) << bit_idx;
393 }
394
395 nulls.push(null_packed);
396 values.push(values_packed);
397 }
398
399 let nulls = NullBuffer::new(BooleanBuffer::new(nulls.into(), 0, len));
400 let nulls = (nulls.null_count() > 0).then_some(nulls);
401
402 BooleanArray::new(BooleanBuffer::new(values.into(), 0, len), nulls)
403}
404
405pub fn decode_nulls(rows: &[&[u8]]) -> Option<NullBuffer> {
409 let nulls = BooleanBuffer::collect_bool(rows.len(), |idx| rows[idx][0] == 1);
410 let nulls = NullBuffer::new(nulls);
411 (nulls.null_count() > 0).then_some(nulls)
412}
413
414pub fn decode_primitive<T: ArrowPrimitiveType>(
416 rows: &mut [&[u8]],
417 data_type: DataType,
418 options: SortOptions,
419) -> PrimitiveArray<T>
420where
421 T::Native: FixedLengthEncoding,
422{
423 assert!(PrimitiveArray::<T>::is_compatible(&data_type));
424
425 let nulls = decode_nulls(rows);
426 let values = rows
427 .iter_mut()
428 .map(|row| {
429 let i = split_off(row, T::Native::ENCODED_LEN);
430 let value = <T::Native as FixedLengthEncoding>::Encoded::from_slice(
431 &i[1..],
432 options.descending,
433 );
434 T::Native::decode(value)
435 })
436 .collect::<Vec<_>>();
437
438 PrimitiveArray::new(values.into(), nulls).with_data_type(data_type)
439}
440
441pub fn decode_fixed_size_binary(
446 rows: &mut [&[u8]],
447 size: i32,
448 options: SortOptions,
449) -> FixedSizeBinaryArray {
450 if size < 0 {
451 panic!("cannot decode FixedSizeBinary({size})");
452 }
453 let num_rows = rows.len();
454 let mut values = MutableBuffer::new(size as usize * num_rows);
455 let nulls = decode_nulls(rows);
456
457 let encoded_len = size as usize + 1;
458
459 for row in rows {
460 let i = split_off(row, encoded_len);
461 values.extend_from_slice(&i[1..]);
462 }
463
464 if options.descending {
465 for v in values.as_slice_mut() {
466 *v = !*v;
467 }
468 }
469
470 FixedSizeBinaryArray::try_new_with_len(size, values.into(), nulls, num_rows).unwrap()
472}