vortex_array/arrays/chunked/compute/
slice.rs1use std::ops::Range;
5
6use itertools::Itertools;
7use vortex_error::VortexResult;
8
9use crate::ArrayRef;
10use crate::ExecutionCtx;
11use crate::IntoArray;
12use crate::array::ArrayView;
13use crate::arrays::Chunked;
14use crate::arrays::ChunkedArray;
15use crate::arrays::chunked::ChunkedArrayExt;
16use crate::arrays::slice::SliceKernel;
17
18impl SliceKernel for Chunked {
19 fn slice(
20 array: ArrayView<'_, Self>,
21 range: Range<usize>,
22 _ctx: &mut ExecutionCtx,
23 ) -> VortexResult<Option<ArrayRef>> {
24 assert!(
25 !array.is_empty() || (range.start > 0 && range.end > 0),
26 "Empty chunked array can't be sliced from {} to {}",
27 range.start,
28 range.end
29 );
30
31 if array.is_empty() {
32 unsafe {
34 return Ok(Some(
35 ChunkedArray::new_unchecked(vec![], array.dtype().clone()).into_array(),
36 ));
37 }
38 }
39
40 let (offset_chunk, offset_in_first_chunk) = array.find_chunk_idx(range.start)?;
41 let (length_chunk, length_in_last_chunk) = array.find_chunk_idx(range.end)?;
42
43 if length_chunk == offset_chunk {
44 let chunk = array.chunk(offset_chunk);
45 return Ok(Some(
46 chunk.slice(offset_in_first_chunk..length_in_last_chunk)?,
47 ));
48 }
49
50 let mut chunks = (offset_chunk..length_chunk + 1)
51 .map(|i| array.chunk(i).clone())
52 .collect_vec();
53 if let Some(c) = chunks.first_mut() {
54 *c = c.slice(offset_in_first_chunk..c.len())?;
55 }
56
57 if length_in_last_chunk == 0 {
58 chunks.pop();
59 } else if let Some(c) = chunks.last_mut() {
60 *c = c.slice(0..length_in_last_chunk)?;
61 }
62
63 Ok(Some(unsafe {
66 ChunkedArray::new_unchecked(chunks, array.dtype().clone()).into_array()
67 }))
68 }
69}