1#[derive(Debug, Clone, Copy, Eq, PartialEq)]
19pub struct RowSelector {
20 pub row_count: usize,
22
23 pub skip: bool,
25}
26
27impl RowSelector {
28 pub fn select(row_count: usize) -> Self {
30 Self {
31 row_count,
32 skip: false,
33 }
34 }
35
36 pub fn skip(row_count: usize) -> Self {
38 Self {
39 row_count,
40 skip: true,
41 }
42 }
43}
44
45pub(super) fn split_off_selectors(
47 mut selectors: Vec<RowSelector>,
48 row_count: usize,
49) -> (Vec<RowSelector>, Vec<RowSelector>) {
50 let mut total_count = 0;
51
52 let find = selectors.iter().position(|selector| {
54 total_count += selector.row_count;
55 total_count > row_count
56 });
57
58 let Some(split_idx) = find else {
59 return (selectors, Vec::new());
60 };
61
62 let mut tail = selectors.split_off(split_idx);
65
66 let next = tail.first_mut().unwrap();
68 let overflow = total_count - row_count;
69
70 if next.row_count != overflow {
71 selectors.push(RowSelector {
72 row_count: next.row_count - overflow,
73 skip: next.skip,
74 })
75 }
76 next.row_count = overflow;
77
78 (selectors, tail)
79}
80
81pub(super) fn offset_selectors(mut selectors: Vec<RowSelector>, offset: usize) -> Vec<RowSelector> {
83 let mut selected_count = 0;
84 let mut skipped_count = 0;
85
86 let find = selectors.iter().position(|selector| match selector.skip {
88 true => {
89 skipped_count += selector.row_count;
90 false
91 }
92 false => {
93 selected_count += selector.row_count;
94 selected_count > offset
95 }
96 });
97
98 let Some(split_idx) = find else {
99 selectors.clear();
100 return selectors;
101 };
102
103 let mut new_selectors = Vec::with_capacity(selectors.len() - split_idx + 1);
104 new_selectors.push(RowSelector::skip(skipped_count + offset));
105 new_selectors.push(RowSelector::select(selected_count - offset));
106 new_selectors.extend_from_slice(&selectors[split_idx + 1..]);
107
108 new_selectors
109}
110
111pub(super) fn limit_selectors(
113 mut selectors: Vec<RowSelector>,
114 mut limit: usize,
115) -> Vec<RowSelector> {
116 if limit == 0 {
117 selectors.clear();
118 }
119
120 for (idx, selection) in selectors.iter_mut().enumerate() {
121 if !selection.skip {
122 if selection.row_count >= limit {
123 selection.row_count = limit;
124 selectors.truncate(idx + 1);
125 break;
126 }
127 limit -= selection.row_count;
128 }
129 }
130 selectors
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136 use crate::arrow::arrow_reader::selection::RowSelection;
137
138 #[test]
139 fn test_from_selectors_skips_empty_selectors() {
140 let selection = RowSelection::from(vec![
141 RowSelector::select(0),
142 RowSelector::skip(0),
143 RowSelector::select(2),
144 RowSelector::select(0),
145 RowSelector::skip(1),
146 ]);
147 assert_eq!(
148 selection.selectors(),
149 vec![RowSelector::select(2), RowSelector::skip(1)]
150 );
151 }
152
153 #[test]
154 fn test_split_off() {
155 let mut selection = RowSelection::from(vec![
156 RowSelector::skip(34),
157 RowSelector::select(12),
158 RowSelector::skip(3),
159 RowSelector::select(35),
160 ]);
161
162 let split = selection.split_off(34);
163 assert_eq!(split.selectors(), vec![RowSelector::skip(34)]);
164 assert_eq!(
165 selection.selectors(),
166 vec![
167 RowSelector::select(12),
168 RowSelector::skip(3),
169 RowSelector::select(35)
170 ]
171 );
172
173 let split = selection.split_off(5);
174 assert_eq!(split.selectors(), vec![RowSelector::select(5)]);
175 assert_eq!(
176 selection.selectors(),
177 vec![
178 RowSelector::select(7),
179 RowSelector::skip(3),
180 RowSelector::select(35)
181 ]
182 );
183
184 let split = selection.split_off(8);
185 assert_eq!(
186 split.selectors(),
187 vec![RowSelector::select(7), RowSelector::skip(1)]
188 );
189 assert_eq!(
190 selection.selectors(),
191 vec![RowSelector::skip(2), RowSelector::select(35)]
192 );
193
194 let split = selection.split_off(200);
195 assert_eq!(
196 split.selectors(),
197 vec![RowSelector::skip(2), RowSelector::select(35)]
198 );
199 assert!(selection.selectors().is_empty());
200 }
201
202 #[test]
203 fn test_offset() {
204 let selection = RowSelection::from(vec![
205 RowSelector::select(5),
206 RowSelector::skip(23),
207 RowSelector::select(7),
208 RowSelector::skip(33),
209 RowSelector::select(6),
210 ]);
211
212 let selection = selection.offset(2);
213 assert_eq!(
214 selection.selectors(),
215 vec![
216 RowSelector::skip(2),
217 RowSelector::select(3),
218 RowSelector::skip(23),
219 RowSelector::select(7),
220 RowSelector::skip(33),
221 RowSelector::select(6),
222 ]
223 );
224
225 let selection = selection.offset(5);
226 assert_eq!(
227 selection.selectors(),
228 vec![
229 RowSelector::skip(30),
230 RowSelector::select(5),
231 RowSelector::skip(33),
232 RowSelector::select(6),
233 ]
234 );
235
236 let selection = selection.offset(3);
237 assert_eq!(
238 selection.selectors(),
239 vec![
240 RowSelector::skip(33),
241 RowSelector::select(2),
242 RowSelector::skip(33),
243 RowSelector::select(6),
244 ]
245 );
246
247 let selection = selection.offset(2);
248 assert_eq!(
249 selection.selectors(),
250 vec![RowSelector::skip(68), RowSelector::select(6),]
251 );
252
253 let selection = selection.offset(3);
254 assert_eq!(
255 selection.selectors(),
256 vec![RowSelector::skip(71), RowSelector::select(3),]
257 );
258 }
259
260 #[test]
261 fn test_combine() {
262 let a = vec![
263 RowSelector::skip(3),
264 RowSelector::skip(3),
265 RowSelector::select(10),
266 RowSelector::skip(4),
267 ];
268
269 let b = vec![
270 RowSelector::skip(3),
271 RowSelector::skip(3),
272 RowSelector::select(10),
273 RowSelector::skip(4),
274 RowSelector::skip(0),
275 ];
276
277 let c = vec![
278 RowSelector::skip(2),
279 RowSelector::skip(4),
280 RowSelector::select(3),
281 RowSelector::select(3),
282 RowSelector::select(4),
283 RowSelector::skip(3),
284 RowSelector::skip(1),
285 RowSelector::skip(0),
286 ];
287
288 let expected = RowSelection::from(vec![
289 RowSelector::skip(6),
290 RowSelector::select(10),
291 RowSelector::skip(4),
292 ]);
293
294 assert_eq!(RowSelection::from_iter(a), expected);
295 assert_eq!(RowSelection::from_iter(b), expected);
296 assert_eq!(RowSelection::from_iter(c), expected);
297 }
298
299 #[test]
300 fn test_combine_2elements() {
301 let a = vec![RowSelector::select(10), RowSelector::select(5)];
302 let a_expect = vec![RowSelector::select(15)];
303 assert_eq!(RowSelection::from_iter(a).selectors(), a_expect);
304
305 let b = vec![RowSelector::select(10), RowSelector::skip(5)];
306 let b_expect = vec![RowSelector::select(10), RowSelector::skip(5)];
307 assert_eq!(RowSelection::from_iter(b).selectors(), b_expect);
308
309 let c = vec![RowSelector::skip(10), RowSelector::select(5)];
310 let c_expect = vec![RowSelector::skip(10), RowSelector::select(5)];
311 assert_eq!(RowSelection::from_iter(c).selectors(), c_expect);
312
313 let d = vec![RowSelector::skip(10), RowSelector::skip(5)];
314 let d_expect = vec![RowSelector::skip(15)];
315 assert_eq!(RowSelection::from_iter(d).selectors(), d_expect);
316 }
317
318 #[test]
319 fn test_from_one_and_empty() {
320 let a = vec![RowSelector::select(10)];
321 let selection1 = RowSelection::from(a.clone());
322 assert_eq!(selection1.selectors(), a);
323
324 let b = vec![];
325 let selection1 = RowSelection::from(b.clone());
326 assert_eq!(selection1.selectors(), b)
327 }
328
329 #[test]
330 fn test_limit() {
331 let selection = RowSelection::from(vec![RowSelector::select(10), RowSelector::skip(90)]);
333 let limited = selection.limit(10);
334 assert_eq!(RowSelection::from(vec![RowSelector::select(10)]), limited);
335
336 let selection = RowSelection::from(vec![
337 RowSelector::select(10),
338 RowSelector::skip(10),
339 RowSelector::select(10),
340 RowSelector::skip(10),
341 RowSelector::select(10),
342 ]);
343
344 let limited = selection.clone().limit(5);
345 let expected = vec![RowSelector::select(5)];
346 assert_eq!(limited.selectors(), expected);
347
348 let limited = selection.clone().limit(15);
349 let expected = vec![
350 RowSelector::select(10),
351 RowSelector::skip(10),
352 RowSelector::select(5),
353 ];
354 assert_eq!(limited.selectors(), expected);
355
356 let limited = selection.clone().limit(0);
357 let expected = vec![];
358 assert_eq!(limited.selectors(), expected);
359
360 let limited = selection.clone().limit(30);
361 let expected = vec![
362 RowSelector::select(10),
363 RowSelector::skip(10),
364 RowSelector::select(10),
365 RowSelector::skip(10),
366 RowSelector::select(10),
367 ];
368 assert_eq!(limited.selectors(), expected);
369
370 let limited = selection.limit(100);
371 let expected = vec![
372 RowSelector::select(10),
373 RowSelector::skip(10),
374 RowSelector::select(10),
375 RowSelector::skip(10),
376 RowSelector::select(10),
377 ];
378 assert_eq!(limited.selectors(), expected);
379 }
380
381 #[test]
382 fn test_from_ranges() {
383 let ranges = [1..3, 4..6, 6..6, 8..8, 9..10];
384 let selection = RowSelection::from_consecutive_ranges(ranges.into_iter(), 10);
385 assert_eq!(
386 selection.selectors(),
387 vec![
388 RowSelector::skip(1),
389 RowSelector::select(2),
390 RowSelector::skip(1),
391 RowSelector::select(2),
392 RowSelector::skip(3),
393 RowSelector::select(1)
394 ]
395 );
396
397 let out_of_order_ranges = [1..3, 8..10, 4..7];
398 let result = std::panic::catch_unwind(|| {
399 RowSelection::from_consecutive_ranges(out_of_order_ranges.into_iter(), 10)
400 });
401 assert!(result.is_err());
402 }
403
404 #[test]
405 fn test_empty_selector() {
406 let selection = RowSelection::from(vec![
407 RowSelector::skip(0),
408 RowSelector::select(2),
409 RowSelector::skip(0),
410 RowSelector::select(2),
411 ]);
412 assert_eq!(selection.selectors(), vec![RowSelector::select(4)]);
413
414 let selection = RowSelection::from(vec![
415 RowSelector::select(0),
416 RowSelector::skip(2),
417 RowSelector::select(0),
418 RowSelector::skip(2),
419 ]);
420 assert_eq!(selection.selectors(), vec![RowSelector::skip(4)]);
421 }
422
423 #[test]
424 fn test_trim() {
425 let selection = RowSelection::from(vec![
426 RowSelector::skip(34),
427 RowSelector::select(12),
428 RowSelector::skip(3),
429 RowSelector::select(35),
430 ]);
431
432 let expected = vec![
433 RowSelector::skip(34),
434 RowSelector::select(12),
435 RowSelector::skip(3),
436 RowSelector::select(35),
437 ];
438
439 assert_eq!(selection.trim().selectors(), expected);
440
441 let selection = RowSelection::from(vec![
442 RowSelector::skip(34),
443 RowSelector::select(12),
444 RowSelector::skip(3),
445 ]);
446
447 let expected = vec![RowSelector::skip(34), RowSelector::select(12)];
448
449 assert_eq!(selection.trim().selectors(), expected);
450 }
451}