zarr_datafusion/reader/
coord.rs1use arrow::array::{ArrayRef, DictionaryArray, Float32Array, Float64Array, Int16Array, Int64Array};
7use arrow::datatypes::Int16Type;
8use std::sync::Arc;
9
10#[derive(Debug)]
12pub enum CoordValues {
13 Int64(Vec<i64>),
14 Float32(Vec<f32>),
15 Float64(Vec<f64>),
16}
17
18impl CoordValues {
19 pub fn len(&self) -> usize {
20 match self {
21 CoordValues::Int64(v) => v.len(),
22 CoordValues::Float32(v) => v.len(),
23 CoordValues::Float64(v) => v.len(),
24 }
25 }
26
27 #[allow(dead_code)]
28 pub fn is_empty(&self) -> bool {
29 self.len() == 0
30 }
31}
32
33pub fn create_coord_dictionary_typed(
35 values: &CoordValues,
36 coord_idx: usize,
37 coord_sizes: &[usize],
38 total_rows: usize,
39) -> ArrayRef {
40 let keys = build_coord_keys(values.len(), coord_idx, coord_sizes, total_rows);
41 let keys_array = Int16Array::from(keys);
42
43 match values {
44 CoordValues::Int64(vals) => {
45 let values_array = Int64Array::from(vals.clone());
46 Arc::new(DictionaryArray::<Int16Type>::new(
47 keys_array,
48 Arc::new(values_array),
49 ))
50 }
51 CoordValues::Float32(vals) => {
52 let values_array = Float32Array::from(vals.clone());
53 Arc::new(DictionaryArray::<Int16Type>::new(
54 keys_array,
55 Arc::new(values_array),
56 ))
57 }
58 CoordValues::Float64(vals) => {
59 let values_array = Float64Array::from(vals.clone());
60 Arc::new(DictionaryArray::<Int16Type>::new(
61 keys_array,
62 Arc::new(values_array),
63 ))
64 }
65 }
66}
67
68pub fn build_coord_keys(
81 num_values: usize,
82 coord_idx: usize,
83 coord_sizes: &[usize],
84 total_rows: usize,
85) -> Vec<i16> {
86 let mut keys: Vec<i16> = Vec::with_capacity(total_rows);
87
88 let inner_size: usize = coord_sizes[coord_idx + 1..].iter().product();
90 let inner_size = if inner_size == 0 { 1 } else { inner_size };
91
92 let outer_count: usize = coord_sizes[..coord_idx].iter().product();
94 let outer_count = if outer_count == 0 { 1 } else { outer_count };
95
96 for _ in 0..outer_count {
97 for i in 0..num_values {
98 for _ in 0..inner_size {
99 keys.push(i as i16);
100 }
101 }
102 }
103
104 keys
105}
106
107pub fn calculate_limited_subset(shape: &[u64], limit: usize) -> Vec<std::ops::Range<u64>> {
113 let limit = limit as u64;
114 let mut ranges = Vec::with_capacity(shape.len());
115
116 for (i, &dim_size) in shape.iter().enumerate().rev() {
118 if i == shape.len() - 1 {
119 let take = limit.min(dim_size);
121 ranges.push(0..take);
122 } else {
123 let inner_size: u64 = shape[i + 1..].iter().product();
125 let slices_needed = limit.div_ceil(inner_size);
126 let take = slices_needed.min(dim_size);
127 ranges.push(0..take);
128 }
129 }
130
131 ranges.reverse();
132 ranges
133}
134
135pub fn calculate_coord_limits(coord_sizes: &[usize], limit: usize) -> Vec<usize> {
143 let mut limits = Vec::with_capacity(coord_sizes.len());
144 let n = coord_sizes.len();
145
146 for i in 0..n {
147 let inner_size: usize = coord_sizes[i + 1..].iter().product();
149 let inner_size = if inner_size == 0 { 1 } else { inner_size };
150
151 let needed = limit.div_ceil(inner_size);
153 let take = needed.min(coord_sizes[i]);
154 limits.push(take);
155 }
156
157 limits
158}