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