@@ -201,18 +201,26 @@ impl IntRange {
201
201
/// intersections between an output range and a column range are inclusions. No output range
202
202
/// straddles the boundary of one of the inputs.
203
203
///
204
+ /// Additionally, we track for each output range whether it is covered by one of the column ranges or not.
205
+ ///
204
206
/// The following input:
205
207
/// ```text
206
- /// | -------------------------| // `self`
207
- /// | ------| | ----------| |----|
208
- /// | -------| | -------|
208
+ /// ( --------------------------) // `self`
209
+ /// ( ------) ( ----------) (-)
210
+ /// ( ------) ( --------)
209
211
/// ```
210
- /// would be iterated over as follows :
212
+ /// is first intersected with `self` :
211
213
/// ```text
212
- /// ||---|--||-|---|---|---|--|
214
+ /// (--------------------------) // `self`
215
+ /// (----) (----------) (-)
216
+ /// (------) (--------)
213
217
/// ```
214
- ///
215
- /// Additionally, we track for each output range whether it is covered by one of the column ranges or not.
218
+ /// and then iterated over as follows:
219
+ /// ```text
220
+ /// (-(--)-(-)-(------)-)--(-)-
221
+ /// ```
222
+ /// where each sequence of dashes is an output range, and dashes outside parentheses are marked
223
+ /// as `Presence::Missing`.
216
224
fn split (
217
225
& self ,
218
226
column_ranges : impl Iterator < Item = IntRange > ,
@@ -245,33 +253,30 @@ impl IntRange {
245
253
. map ( unpack_intrange)
246
254
. flat_map ( |[ lo, hi] | [ ( lo, 1 ) , ( hi, -1 ) ] )
247
255
. collect ( ) ;
256
+ // We sort by boundary, and for each boundary we sort the "closing parentheses" first. The
257
+ // order of +1/-1 for a same boundary value is actually irrelevant, because we only look at
258
+ // the accumulated count between distinct boundary values.
248
259
boundaries. sort_unstable ( ) ;
249
260
250
- // Counter for parenthesis matching.
251
- let mut paren_counter = 0isize ;
252
- let boundaries_with_paren_counts = boundaries
253
- . into_iter ( )
254
- // Accumulate parenthesis counts.
255
- . map ( move |( bdy, delta) | {
256
- paren_counter += delta;
257
- ( bdy, paren_counter)
258
- } ) ;
259
-
260
261
let [ self_start, self_end] = unpack_intrange ( self . clone ( ) ) ;
262
+ // Accumulate parenthesis counts.
263
+ let mut paren_counter = 0isize ;
261
264
// Gather pairs of adjacent boundaries.
262
265
let mut prev_bdy = self_start;
263
- let mut prev_paren_count = 0 ;
264
- boundaries_with_paren_counts
265
- // End with the end of the range. The count is irrelevant .
266
+ boundaries
267
+ . into_iter ( )
268
+ // End with the end of the range. The count is ignored .
266
269
. chain ( once ( ( self_end, 0 ) ) )
267
- // List pairs of adjacent boundaries.
268
- . map ( move |( bdy, paren_count) | {
269
- let ret = ( prev_bdy, prev_paren_count, bdy) ;
270
+ // List pairs of adjacent boundaries and the count between them.
271
+ . map ( move |( bdy, delta) | {
272
+ // `delta` affects the count as we cross `bdy`, so the relevant count between
273
+ // `prev_bdy` and `bdy` is untouched by `delta`.
274
+ let ret = ( prev_bdy, paren_counter, bdy) ;
270
275
prev_bdy = bdy;
271
- prev_paren_count = paren_count ;
276
+ paren_counter += delta ;
272
277
ret
273
278
} )
274
- // Skip duplicates .
279
+ // Skip empty ranges .
275
280
. filter ( |& ( prev_bdy, _, bdy) | prev_bdy != bdy)
276
281
// Convert back to ranges.
277
282
. map ( move |( prev_bdy, paren_count, bdy) | {
@@ -503,7 +508,10 @@ impl Slice {
503
508
let smaller_lengths;
504
509
let arity = self . arity ( ) ;
505
510
let mut max_slice = self . kind ;
511
+ // Tracks the smallest variable-length slice we've seen. Any slice arity above it is
512
+ // therefore `Presence::Seen` in the column.
506
513
let mut min_var_len = usize:: MAX ;
514
+ // Tracks the fixed-length slices we've seen, to mark them as `Presence::Seen`.
507
515
let mut seen_fixed_lens = FxHashSet :: default ( ) ;
508
516
match & mut max_slice {
509
517
VarLen ( max_prefix_len, max_suffix_len) => {
0 commit comments