1use crate::{LengthTracker, RowConverter, Rows, SortField, fixed, null_sentinel};
19use arrow_array::{
20 Array, ArrayRef, FixedSizeListArray, GenericListArray, GenericListViewArray, MapArray,
21 OffsetSizeTrait, StructArray, new_null_array,
22};
23use arrow_buffer::{
24 ArrowNativeType, BooleanBuffer, MutableBuffer, NullBuffer, OffsetBuffer, ScalarBuffer,
25};
26use arrow_schema::{ArrowError, DataType, Fields, SortOptions};
27use std::{ops::Range, sync::Arc};
28
29pub(crate) trait GenericListArrayOrMap: Array {
30 type Offset: OffsetSizeTrait;
31
32 fn offsets(&self) -> &[Self::Offset];
33
34 unsafe fn from_parts_unchecked(
35 data_type: DataType,
36 offsets: Vec<Self::Offset>,
37 children: Vec<ArrayRef>,
38 null_buffer: Option<NullBuffer>,
39 ) -> Self
40 where
41 Self: Sized;
42}
43
44impl<O: OffsetSizeTrait> GenericListArrayOrMap for GenericListArray<O> {
45 type Offset = O;
46
47 fn offsets(&self) -> &[Self::Offset] {
48 self.value_offsets()
49 }
50
51 unsafe fn from_parts_unchecked(
52 data_type: DataType,
53 offsets: Vec<Self::Offset>,
54 children: Vec<ArrayRef>,
55 null_buffer: Option<NullBuffer>,
56 ) -> Self
57 where
58 Self: Sized,
59 {
60 let field = match data_type {
61 DataType::List(inner_field) | DataType::LargeList(inner_field) => inner_field,
62 _ => unreachable!(),
63 };
64
65 let child = children
66 .into_iter()
67 .next()
68 .expect("List arrays must have exactly one child array");
69
70 let offset_buffer = unsafe { OffsetBuffer::new_unchecked(ScalarBuffer::from(offsets)) };
73 GenericListArray::<Self::Offset>::new(field, offset_buffer, child, null_buffer)
74 }
75}
76
77impl GenericListArrayOrMap for MapArray {
78 type Offset = i32;
79
80 fn offsets(&self) -> &[Self::Offset] {
81 self.value_offsets()
82 }
83
84 unsafe fn from_parts_unchecked(
85 data_type: DataType,
86 offsets: Vec<Self::Offset>,
87 children: Vec<ArrayRef>,
88 null_buffer: Option<NullBuffer>,
89 ) -> Self
90 where
91 Self: Sized,
92 {
93 let DataType::Map(entries_field, ordered) = data_type else {
94 unreachable!("data type must be Map for MapArray");
95 };
96
97 assert_eq!(
98 children.len(),
99 2,
100 "Map arrays must have exactly two child arrays for keys and values"
101 );
102
103 let DataType::Struct(fields) = entries_field.data_type() else {
104 unreachable!("Map entry type must be Struct");
105 };
106
107 let entries = StructArray::new(
108 fields.clone(),
109 children,
110 None,
112 );
113
114 let offset_buffer = unsafe { OffsetBuffer::new_unchecked(ScalarBuffer::from(offsets)) };
117
118 MapArray::new(entries_field, offset_buffer, entries, null_buffer, ordered)
119 }
120}
121
122pub(crate) fn compute_lengths<L: GenericListArrayOrMap>(
123 lengths: &mut [usize],
124 rows: &Rows,
125 array: &L,
126) {
127 let shift = array.offsets()[0].as_usize();
128
129 lengths
130 .iter_mut()
131 .zip(array.offsets().windows(2))
132 .enumerate()
133 .for_each(|(idx, (length, offsets))| {
134 let start = offsets[0].as_usize() - shift;
135 let end = offsets[1].as_usize() - shift;
136 let range = array.is_valid(idx).then_some(start..end);
137 *length += list_like_element_encoded_len(rows, range);
138 });
139}
140
141pub(crate) fn encode<L: GenericListArrayOrMap>(
145 data: &mut [u8],
146 offsets: &mut [usize],
147 rows: &Rows,
148 opts: SortOptions,
149 array: &L,
150) {
151 let shift = array.offsets()[0].as_usize();
152
153 offsets
154 .iter_mut()
155 .skip(1)
156 .zip(array.offsets().windows(2))
157 .enumerate()
158 .for_each(|(idx, (offset, offsets))| {
159 let start = offsets[0].as_usize() - shift;
160 let end = offsets[1].as_usize() - shift;
161 let range = array.is_valid(idx).then_some(start..end);
162 let out = &mut data[*offset..];
163 *offset += encode_one(out, rows, range, opts)
164 });
165}
166
167#[inline]
168fn encode_one(
169 out: &mut [u8],
170 rows: &Rows,
171 range: Option<Range<usize>>,
172 opts: SortOptions,
173) -> usize {
174 match range {
175 None => super::variable::encode_null(out, opts),
176 Some(range) if range.start == range.end => super::variable::encode_empty(out, opts),
177 Some(range) => {
178 let mut offset = 0;
179 for i in range {
180 let row = rows.row(i);
181 offset += super::variable::encode_one(&mut out[offset..], Some(row.data), opts);
182 }
183 offset += super::variable::encode_empty(&mut out[offset..], opts);
184 offset
185 }
186 }
187}
188
189pub(crate) unsafe fn decode<ListLikeImpl: GenericListArrayOrMap>(
195 converter: &RowConverter,
196 rows: &mut [&[u8]],
197 field: &SortField,
198 validate_utf8: bool,
199) -> Result<ListLikeImpl, ArrowError> {
200 let opts = field.options;
201
202 let mut values_bytes = 0;
203
204 let mut offset = 0;
205 let mut offsets = Vec::with_capacity(rows.len() + 1);
206 offsets.push(ListLikeImpl::Offset::usize_as(0));
207
208 for row in rows.iter_mut() {
209 let mut row_offset = 0;
210 loop {
211 let decoded = super::variable::decode_blocks(&row[row_offset..], opts, |x| {
212 values_bytes += x.len();
213 });
214 if decoded <= 1 {
215 offsets.push(ListLikeImpl::Offset::usize_as(offset));
216 break;
217 }
218 row_offset += decoded;
219 offset += 1;
220 }
221 }
222 ListLikeImpl::Offset::from_usize(offset).expect("overflow");
223
224 let nulls = crate::variable::decode_nulls_sentinel(rows, opts);
225
226 let mut values_offsets = Vec::with_capacity(offset);
227 let mut values_bytes = Vec::with_capacity(values_bytes);
228 for row in rows.iter_mut() {
229 let mut row_offset = 0;
230 loop {
231 let decoded = super::variable::decode_blocks(&row[row_offset..], opts, |x| {
232 values_bytes.extend_from_slice(x)
233 });
234 row_offset += decoded;
235 if decoded <= 1 {
236 break;
237 }
238 values_offsets.push(values_bytes.len());
239 }
240 *row = &row[row_offset..];
241 }
242
243 if opts.descending {
244 values_bytes.iter_mut().for_each(|o| *o = !*o);
245 }
246
247 let mut last_value_offset = 0;
248 let mut child_rows: Vec<_> = values_offsets
249 .into_iter()
250 .map(|offset| {
251 let v = &values_bytes[last_value_offset..offset];
252 last_value_offset = offset;
253 v
254 })
255 .collect();
256
257 let children = unsafe { converter.convert_raw(&mut child_rows, validate_utf8) }?;
258
259 let corrected_type = match &field.data_type {
262 DataType::List(inner_field) => {
263 assert_eq!(children.len(), 1);
264 DataType::List(Arc::new(
265 inner_field
266 .as_ref()
267 .clone()
268 .with_data_type(children[0].data_type().clone()),
269 ))
270 }
271 DataType::LargeList(inner_field) => {
272 assert_eq!(children.len(), 1);
273 DataType::LargeList(Arc::new(
274 inner_field
275 .as_ref()
276 .clone()
277 .with_data_type(children[0].data_type().clone()),
278 ))
279 }
280 DataType::Map(inner_field, ordered) => {
281 let DataType::Struct(entries_field) = inner_field.data_type() else {
282 return Err(ArrowError::InvalidArgumentError(format!(
283 "Expected Map entry type to be Struct, found: {}",
284 inner_field.data_type()
285 )));
286 };
287 assert_eq!(
288 children.len(),
289 2,
290 "Map arrays must have exactly two child arrays for keys and values"
291 );
292 let key_field = entries_field[0]
293 .as_ref()
294 .clone()
295 .with_data_type(children[0].data_type().clone());
296 let value_field = entries_field[1]
297 .as_ref()
298 .clone()
299 .with_data_type(children[1].data_type().clone());
300
301 let entries_fields = Fields::from(vec![key_field, value_field]);
302
303 DataType::Map(
304 Arc::new(
305 inner_field
306 .as_ref()
307 .clone()
308 .with_data_type(DataType::Struct(entries_fields)),
309 ),
310 *ordered,
311 )
312 }
313 _ => unreachable!(),
314 };
315
316 Ok(unsafe { ListLikeImpl::from_parts_unchecked(corrected_type, offsets, children, nulls) })
317}
318
319pub fn compute_lengths_fixed_size_list(
320 tracker: &mut LengthTracker,
321 rows: &Rows,
322 array: &FixedSizeListArray,
323) {
324 let value_length = array.value_length().as_usize();
325 tracker.push_variable((0..array.len()).map(|idx| {
326 match array.is_valid(idx) {
327 true => {
328 1 + ((idx * value_length)..(idx + 1) * value_length)
329 .map(|child_idx| rows.row(child_idx).as_ref().len())
330 .sum::<usize>()
331 }
332 false => 1,
333 }
334 }))
335}
336
337pub fn encode_fixed_size_list(
341 data: &mut [u8],
342 offsets: &mut [usize],
343 rows: &Rows,
344 opts: SortOptions,
345 array: &FixedSizeListArray,
346) {
347 let null_sentinel = null_sentinel(opts);
348 offsets
349 .iter_mut()
350 .skip(1)
351 .enumerate()
352 .for_each(|(idx, offset)| {
353 let value_length = array.value_length().as_usize();
354 match array.is_valid(idx) {
355 true => {
356 data[*offset] = 0x01;
357 *offset += 1;
358 for child_idx in (idx * value_length)..(idx + 1) * value_length {
359 let row = rows.row(child_idx);
360 let end_offset = *offset + row.as_ref().len();
361 data[*offset..end_offset].copy_from_slice(row.as_ref());
362 *offset = end_offset;
363 }
364 }
365 false => {
366 data[*offset] = null_sentinel;
367 *offset += 1;
368 }
369 };
370 })
371}
372
373pub unsafe fn decode_fixed_size_list(
379 converter: &RowConverter,
380 rows: &mut [&[u8]],
381 field: &SortField,
382 validate_utf8: bool,
383 value_length: usize,
384) -> Result<FixedSizeListArray, ArrowError> {
385 let list_type = &field.data_type;
386 let DataType::FixedSizeList(element_field, size) = list_type else {
387 return Err(ArrowError::InvalidArgumentError(format!(
388 "Expected FixedSizeListArray, found: {list_type}",
389 )));
390 };
391
392 let num_rows = rows.len();
393 let nulls = fixed::decode_nulls(rows);
394
395 let null_element_encoded =
396 converter.convert_columns(&[new_null_array(element_field.data_type(), 1)])?;
397 let null_element_encoded = null_element_encoded.row(0);
398 let null_element_slice = null_element_encoded.as_ref();
399
400 let mut child_rows = Vec::new();
401 for row in rows {
402 let valid = row[0] == 1;
403 let mut row_offset = 1;
404 if !valid {
405 for _ in 0..value_length {
406 child_rows.push(null_element_slice);
407 }
408 } else {
409 for _ in 0..value_length {
410 let mut temp_child_rows = vec![&row[row_offset..]];
411 unsafe { converter.convert_raw(&mut temp_child_rows, validate_utf8) }?;
412 let decoded_bytes = row.len() - row_offset - temp_child_rows[0].len();
413 let next_offset = row_offset + decoded_bytes;
414 child_rows.push(&row[row_offset..next_offset]);
415 row_offset = next_offset;
416 }
417 }
418 *row = &row[row_offset..]; }
420
421 let mut children = unsafe { converter.convert_raw(&mut child_rows, validate_utf8) }?;
422 assert_eq!(children.len(), 1);
423
424 let corrected_element_field = Arc::new(
427 element_field
428 .as_ref()
429 .clone()
430 .with_data_type(children[0].data_type().clone()),
431 );
432
433 FixedSizeListArray::try_new_with_length(
434 corrected_element_field,
435 *size,
436 children.pop().unwrap(),
437 nulls,
438 num_rows,
439 )
440}
441
442#[inline]
448fn list_like_element_encoded_len(rows: &Rows, range: Option<Range<usize>>) -> usize {
449 match range {
450 None => 1,
451 Some(range) => {
452 1 + range
453 .map(|i| super::variable::padded_length(Some(rows.row(i).as_ref().len())))
454 .sum::<usize>()
455 }
456 }
457}
458
459pub fn compute_lengths_list_view<O: OffsetSizeTrait>(
463 lengths: &mut [usize],
464 rows: &Rows,
465 array: &GenericListViewArray<O>,
466 shift: usize,
467) {
468 let offsets = array.value_offsets();
469 let sizes = array.value_sizes();
470
471 lengths.iter_mut().enumerate().for_each(|(idx, length)| {
472 let size = sizes[idx].as_usize();
473 let range = array.is_valid(idx).then(|| {
474 let start = if size > 0 {
477 offsets[idx].as_usize() - shift
478 } else {
479 0
480 };
481 start..start + size
482 });
483 *length += list_like_element_encoded_len(rows, range);
484 });
485}
486
487pub fn encode_list_view<O: OffsetSizeTrait>(
491 data: &mut [u8],
492 out_offsets: &mut [usize],
493 rows: &Rows,
494 opts: SortOptions,
495 array: &GenericListViewArray<O>,
496 shift: usize,
497) {
498 let offsets = array.value_offsets();
499 let sizes = array.value_sizes();
500
501 out_offsets
502 .iter_mut()
503 .skip(1)
504 .enumerate()
505 .for_each(|(idx, offset)| {
506 let size = sizes[idx].as_usize();
507 let range = array.is_valid(idx).then(|| {
508 let start = if size > 0 {
511 offsets[idx].as_usize() - shift
512 } else {
513 0
514 };
515 start..start + size
516 });
517 let out = &mut data[*offset..];
518 *offset += encode_one(out, rows, range, opts)
519 });
520}
521
522pub unsafe fn decode_list_view<O: OffsetSizeTrait>(
528 converter: &RowConverter,
529 rows: &mut [&[u8]],
530 field: &SortField,
531 validate_utf8: bool,
532) -> Result<GenericListViewArray<O>, ArrowError> {
533 let opts = field.options;
534
535 let mut values_bytes = 0;
536
537 let mut child_count = 0usize;
538 let mut list_sizes: Vec<O> = Vec::with_capacity(rows.len());
539
540 for row in rows.iter_mut() {
542 let mut row_offset = 0;
543 let mut list_size = 0usize;
544 loop {
545 let decoded = super::variable::decode_blocks(&row[row_offset..], opts, |x| {
546 values_bytes += x.len();
547 });
548 if decoded <= 1 {
549 list_sizes.push(O::usize_as(list_size));
550 break;
551 }
552 row_offset += decoded;
553 child_count += 1;
554 list_size += 1;
555 }
556 }
557 O::from_usize(child_count).expect("overflow");
558
559 let null_sentinel = null_sentinel(opts);
560 let mut null_count = 0;
561 let nulls = MutableBuffer::collect_bool(rows.len(), |x| {
562 let valid = rows[x][0] != null_sentinel;
563 null_count += !valid as usize;
564 valid
565 });
566
567 let mut values_offsets_vec = Vec::with_capacity(child_count);
568 let mut values_bytes = Vec::with_capacity(values_bytes);
569 for row in rows.iter_mut() {
570 let mut row_offset = 0;
571 loop {
572 let decoded = super::variable::decode_blocks(&row[row_offset..], opts, |x| {
573 values_bytes.extend_from_slice(x)
574 });
575 row_offset += decoded;
576 if decoded <= 1 {
577 break;
578 }
579 values_offsets_vec.push(values_bytes.len());
580 }
581 *row = &row[row_offset..];
582 }
583
584 if opts.descending {
585 values_bytes.iter_mut().for_each(|o| *o = !*o);
586 }
587
588 let mut last_value_offset = 0;
589 let mut child_rows: Vec<_> = values_offsets_vec
590 .into_iter()
591 .map(|offset| {
592 let v = &values_bytes[last_value_offset..offset];
593 last_value_offset = offset;
594 v
595 })
596 .collect();
597
598 let child = unsafe { converter.convert_raw(&mut child_rows, validate_utf8) }?;
599 assert_eq!(child.len(), 1);
600
601 let child_data = child[0].to_data();
602
603 let mut list_offsets: Vec<O> = Vec::with_capacity(rows.len());
607 let mut current_offset = O::usize_as(0);
608 for size in &list_sizes {
609 list_offsets.push(current_offset);
610 current_offset += *size;
611 }
612
613 let corrected_inner_field = match &field.data_type {
616 DataType::ListView(inner_field) | DataType::LargeListView(inner_field) => Arc::new(
617 inner_field
618 .as_ref()
619 .clone()
620 .with_data_type(child_data.data_type().clone()),
621 ),
622 _ => unreachable!(),
623 };
624
625 let null_buffer = unsafe {
627 NullBuffer::new_unchecked(BooleanBuffer::new(nulls.into(), 0, rows.len()), null_count)
628 };
629
630 GenericListViewArray::try_new(
631 corrected_inner_field,
632 ScalarBuffer::from(list_offsets),
633 ScalarBuffer::from(list_sizes),
634 child[0].clone(),
635 Some(null_buffer).filter(|n| n.null_count() > 0),
636 )
637}