Skip to content

Commit dbc5c28

Browse files
committed
retain descending span end order during partioning
1 parent 07cf301 commit dbc5c28

File tree

3 files changed

+9
-15
lines changed

3 files changed

+9
-15
lines changed

helix-core/src/syntax/span.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,9 @@ impl SpanIter {
107107
///
108108
/// * intersect: the end of span `A`
109109
fn partition_spans_at(&mut self, intersect: usize) {
110-
let first_partitioned_span = self.spans[self.index];
111-
112110
let mut i = self.index;
113111
while let Some(span) = self.spans.get_mut(i) {
114-
if span.start != self.cursor || span.end < intersect {
112+
if span.start != self.cursor || span.end <= intersect {
115113
break;
116114
}
117115

@@ -123,30 +121,23 @@ impl SpanIter {
123121
i += 1;
124122
}
125123

126-
let num_partitioned_spans = i - self.index;
127-
128124
// When spans are partioned, the span Vec may need to be re-sorted
129125
// because the `span.start` may now be greater than some `span.start`
130126
// later in the Vec. This is not a classic "sort": we take several
131127
// shortcuts to improve the runtime so that the sort may be done in
132128
// time linear to the cardinality of the span Vec. Practically speaking
133129
// the runtime is even better since we only scan from `self.index` to
134130
// the first element of the Vec with a `span.start` after this span.
135-
let intersect_span = Span {
136-
start: intersect,
137-
..first_partitioned_span
138-
};
139-
140131
let num_spans_to_resort = self.spans[i..]
141132
.iter()
142-
.take_while(|&&span| span <= intersect_span)
133+
.take_while(|&&span| span.start <= intersect)
143134
.count();
144135

145136
// Rotate the subsliced spans so that they come after the spans that
146137
// have smaller `span.start`s.
147138
if num_spans_to_resort != 0 {
148139
let first_sorted_span = i + num_spans_to_resort;
149-
self.spans[self.index..first_sorted_span].rotate_left(num_partitioned_spans);
140+
self.spans[self.index..first_sorted_span].sort_unstable();
150141
}
151142
}
152143
}

helix-core/src/syntax/span/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ fn test_many_overlapping_span_iter_events() {
111111
Source { start: 12, end: 13 },
112112
HighlightEnd, // ends 4
113113
HighlightEnd, // ends 3
114-
HighlightStart(Highlight(5)),
115114
HighlightStart(Highlight(4)),
115+
HighlightStart(Highlight(5)),
116116
Source { start: 13, end: 15 },
117117
HighlightEnd, // ends 5
118118
HighlightEnd, // ends 4

helix-core/src/syntax/test.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,8 +642,11 @@ fn span(file_size: usize, allow_empty: bool, scope: usize) -> impl Strategy<Valu
642642
})
643643
}
644644

645-
const MAX_SPAN_LIST_SIZE: usize = 20;
646-
const MAX_FILE_SIZE: usize = 40;
645+
/// The maximum number of created spans.
646+
/// Must not surpass 128 because `HighlightSet` can not represent more elements
647+
/// When trying to reduce a regression it is often useful to reduce this significantly
648+
const MAX_SPAN_LIST_SIZE: usize = 128;
649+
const MAX_FILE_SIZE: usize = 200;
647650

648651
fn span_list() -> impl Strategy<Value = Vec<Span>> + Clone {
649652
let file_size = 1..MAX_FILE_SIZE;

0 commit comments

Comments
 (0)