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