1use std::collections::HashMap;
2
3use arrow_array::cast::AsArray;
4use arrow_array::{Array, ArrayRef, RecordBatch, RecordBatchOptions, UInt64Array};
5use arrow_schema::{ArrowError, DataType};
6use arrow_select::concat::concat as concat_arrays;
7use arrow_select::interleave::interleave;
8use arrow_select::take::take;
9use arrow_select::zip::zip;
10use rayon::prelude::*;
11use runlength::{Rle, RleLike, plan_many};
12
13use crate::batch::{ArrowRleBatch, key_converter, key_rows};
14use crate::error::{Error, Result};
15use crate::kernels::Kernel;
16use crate::rle::{ArrowRle, default_fill};
17
18pub fn concat(rles: &[ArrowRle]) -> Result<ArrowRle> {
21 let Some(first) = rles.first() else {
22 return Ok(ArrowRle::empty(&DataType::Null));
23 };
24 let mut ends = Vec::with_capacity(rles.iter().map(|r| r.num_runs()).sum());
25 let mut offset = 0;
26 for rle in rles {
27 ends.extend(rle.ends().iter().map(|&e| e + offset));
28 offset += rle.len();
29 }
30 let values: Vec<&dyn Array> = rles.iter().map(|r| r.values().as_ref()).collect();
31 let values = if values.len() == 1 {
32 first.values().clone()
33 } else {
34 concat_arrays(&values)?
35 };
36 ArrowRle::try_new(ends, values)?.merge()
37}
38
39pub fn zip_many<F>(rles: &[ArrowRle], fills: &[Option<&dyn Array>], f: F) -> Result<ArrowRle>
46where
47 F: FnOnce(&[ArrayRef]) -> std::result::Result<ArrayRef, ArrowError>,
48{
49 if fills.len() != rles.len() {
50 return Err(runlength::Error::LengthMismatch {
51 what: "fills and sequences",
52 left: fills.len(),
53 right: rles.len(),
54 }
55 .into());
56 }
57 let max = rles.iter().map(|r| r.len()).max().unwrap_or(0);
58 for (rle, fill) in rles.iter().zip(fills) {
59 if rle.len() < max && fill.is_none() {
60 return Err(runlength::Error::UnequalLength {
61 left: rle.len(),
62 right: max,
63 }
64 .into());
65 }
66 }
67 let ends: Vec<&[i64]> = rles.iter().map(|r| r.ends()).collect();
68 let plan = plan_many(&ends);
69 let gathered = rles
70 .iter()
71 .zip(fills)
72 .zip(&plan.idx)
73 .map(|((rle, fill), idx)| crate::rle::gather(rle.values(), idx, *fill))
74 .collect::<Result<Vec<_>>>()?;
75 let values = f(&gathered)?;
76 if values.len() != plan.ends.len() {
77 return Err(Error::WrongLength {
78 expected: plan.ends.len(),
79 actual: values.len(),
80 });
81 }
82 ArrowRle::try_new(plan.ends, values)?.merge()
83}
84
85impl ArrowRle {
86 pub fn shift(&self, distance: i64, fill: &dyn Array) -> Result<ArrowRle> {
90 crate::rle::check_fill(Some(fill), self.data_type())?;
91 let len = self.len();
92 if distance == 0 {
93 return self.clone().merge();
94 }
95 let fill_run = |n: i64| ArrowRle::from_runs(&[n], crate::rle::array_ref(fill));
96 if distance.unsigned_abs() >= len as u64 {
97 return fill_run(len);
98 }
99 if distance > 0 {
100 concat(&[fill_run(distance)?, self.slice(0, len - distance)])
101 } else {
102 concat(&[self.slice(-distance, len), fill_run(-distance)?])
103 }
104 }
105
106 pub fn reversed(&self) -> Result<ArrowRle> {
108 let rle = Rle::from_ends(self.ends().to_vec(), vec![(); self.num_runs()])?.reversed();
109 let n = self.num_runs() as u64;
110 let indices = UInt64Array::from_iter_values((0..n).rev());
111 ArrowRle::try_new(
112 rle.into_parts().0,
113 take(self.values().as_ref(), &indices, None)?,
114 )
115 }
116
117 pub fn true_ranges(&self) -> Result<(Vec<i64>, Vec<i64>)> {
120 let values = self
121 .values()
122 .as_boolean_opt()
123 .ok_or_else(|| Error::UnsupportedType(self.data_type().clone()))?;
124 let flags: Vec<bool> = values.iter().map(|v| v == Some(true)).collect();
125 let rle = Rle::from_ends(self.ends().to_vec(), flags)?;
126 Ok(rle.ranges_where(|&v| v))
127 }
128
129 pub fn fill_null(&self, fill: &dyn Array) -> Result<ArrowRle> {
131 crate::rle::check_fill(Some(fill), self.data_type())?;
132 if self.values().null_count() == 0 {
133 return Ok(self.clone());
134 }
135 let is_null = arrow_arith::boolean::is_null(self.values().as_ref())?;
136 let fill = arrow_array::Scalar::new(crate::rle::array_ref(fill));
137 let values = zip(&is_null, &fill, self.values())?;
138 ArrowRle::try_new(self.ends().to_vec(), values)?.merge()
139 }
140}
141
142impl ArrowRleBatch {
143 pub fn collapse(&self, keep: &[&str], kernel: Kernel) -> Result<ArrowRleBatch> {
152 let keys = self.keys();
153 let indices = keep
154 .iter()
155 .map(|name| keys.schema().index_of(name))
156 .collect::<std::result::Result<Vec<_>, _>>()?;
157 let kept = keys.project(&indices)?;
158 let converter = key_converter(&kept)?;
159 let rows = key_rows(&converter, &kept)?;
160
161 let mut groups: Vec<Vec<usize>> = Vec::new();
162 let mut first_rows = Vec::new();
163 let mut positions = HashMap::new();
164 for (i, row) in rows.iter().enumerate() {
165 let g = *positions.entry(row).or_insert_with(|| {
166 first_rows.push(i as u64);
167 groups.push(Vec::new());
168 groups.len() - 1
169 });
170 groups[g].push(i);
171 }
172
173 let data_type = self.values().data_type();
174 let fill = default_fill(data_type);
175 let rles = groups
176 .par_iter()
177 .enumerate()
178 .map(|(position, members)| {
179 let fold = || {
180 let mut acc = self.get_index(members[0]).expect("in range").merge()?;
181 for &i in &members[1..] {
182 let next = self.get_index(i).expect("in range");
183 acc = acc.zip_with(&next, fill.as_deref(), fill.as_deref(), kernel)?;
184 }
185 Ok(acc)
186 };
187 fold().map_err(|e: Error| e.in_key(position))
188 })
189 .collect::<Result<Vec<_>>>()?;
190
191 let first_rows = UInt64Array::from(first_rows);
192 let columns = kept
193 .columns()
194 .iter()
195 .map(|c| take(c.as_ref(), &first_rows, None))
196 .collect::<std::result::Result<Vec<_>, _>>()?;
197 let new_keys = RecordBatch::try_new(kept.schema(), columns)?;
198 let out_type = rles
199 .first()
200 .map_or(data_type.clone(), |r| r.data_type().clone());
201 ArrowRleBatch::from_rles(new_keys, rles, &out_type)
202 }
203}
204
205impl ArrowRleBatch {
206 pub fn shift(&self, distance: i64, fill: &dyn Array) -> Result<ArrowRleBatch> {
208 self.map_rles(|r| r.shift(distance, fill))
209 }
210
211 pub fn reversed(&self) -> Result<ArrowRleBatch> {
213 self.map_rles(ArrowRle::reversed)
214 }
215
216 pub fn map_rles<F>(&self, f: F) -> Result<ArrowRleBatch>
219 where
220 F: Fn(&ArrowRle) -> Result<ArrowRle> + Sync,
221 {
222 let rles = (0..self.len())
223 .into_par_iter()
224 .map(|i| f(&self.get_index(i).expect("in range")).map_err(|e| e.in_key(i)))
225 .collect::<Result<Vec<_>>>()?;
226 let data_type = rles
227 .first()
228 .map_or(self.values().data_type().clone(), |r| r.data_type().clone());
229 ArrowRleBatch::from_rles(self.keys().clone(), rles, &data_type)
230 }
231
232 pub fn concat(batches: &[ArrowRleBatch]) -> Result<ArrowRleBatch> {
237 let Some(first) = batches.first() else {
238 return Err(Error::NoInputs);
239 };
240 let converter = key_converter(first.keys())?;
241 let mut groups: Vec<Vec<(usize, usize)>> = Vec::new();
242 let mut positions = HashMap::new();
243 for (b, batch) in batches.iter().enumerate() {
244 first.check_key_schema(batch.keys())?;
245 let rows = key_rows(&converter, batch.keys())?;
246 for (i, row) in rows.iter().enumerate() {
247 let g = *positions.entry(row.owned()).or_insert_with(|| {
248 groups.push(Vec::new());
249 groups.len() - 1
250 });
251 groups[g].push((b, i));
252 }
253 }
254 let rles = groups
255 .par_iter()
256 .enumerate()
257 .map(|(position, members)| {
258 let parts: Vec<ArrowRle> = members
259 .iter()
260 .map(|&(b, i)| batches[b].get_index(i).expect("in range"))
261 .collect();
262 concat(&parts).map_err(|e| e.in_key(position))
263 })
264 .collect::<Result<Vec<_>>>()?;
265 let sources: Vec<(usize, usize)> = groups.iter().map(|g| g[0]).collect();
266 let columns = (0..first.keys().num_columns())
267 .map(|c| {
268 let arrays: Vec<&dyn Array> = batches
269 .iter()
270 .map(|b| b.keys().column(c).as_ref())
271 .collect();
272 interleave(&arrays, &sources)
273 })
274 .collect::<std::result::Result<Vec<_>, _>>()?;
275 let keys = RecordBatch::try_new_with_options(
276 first.keys().schema(),
277 columns,
278 &RecordBatchOptions::new().with_row_count(Some(sources.len())),
279 )?;
280 ArrowRleBatch::from_rles(keys, rles, first.values().data_type())
281 }
282}