Share sort_layers function between query iterators

The code in the `sort_layers` function was fully duplicated between
the HighlightIter and the QueryIter. This change adds a common
`sort_layers` function that accepts a layer Vec from both.
pull/2857/head
Michael Davis 2 years ago
parent cc2531428e
commit b4bf968503
No known key found for this signature in database

@ -1475,7 +1475,7 @@ impl Syntax {
range: Option<std::ops::Range<usize>>, range: Option<std::ops::Range<usize>>,
cancellation_flag: Option<&'a AtomicUsize>, cancellation_flag: Option<&'a AtomicUsize>,
) -> impl Iterator<Item = Result<HighlightEvent, Error>> + 'a { ) -> impl Iterator<Item = Result<HighlightEvent, Error>> + 'a {
let mut layers = self let mut layers: Vec<_> = self
.layers .layers
.iter() .iter()
.filter_map(|(_, layer)| { .filter_map(|(_, layer)| {
@ -1525,11 +1525,13 @@ impl Syntax {
depth: layer.depth, // TODO: just reuse `layer` depth: layer.depth, // TODO: just reuse `layer`
}) })
}) })
.collect::<Vec<_>>(); .collect();
layers.sort_unstable_by_key(|layer| layer.sort_key()); layers.sort_unstable_by_key(|layer| layer.sort_key());
let mut result = HighlightIter { sort_layers(&mut layers);
HighlightIter {
source, source,
byte_offset: range.map_or(0, |r| r.start), byte_offset: range.map_or(0, |r| r.start),
cancellation_flag, cancellation_flag,
@ -1537,9 +1539,7 @@ impl Syntax {
layers, layers,
next_event: None, next_event: None,
last_highlight_range: None, last_highlight_range: None,
}; }
result.sort_layers();
result
} }
pub fn tree_for_byte_range(&self, start: usize, end: usize) -> &Tree { pub fn tree_for_byte_range(&self, start: usize, end: usize) -> &Tree {
@ -2343,6 +2343,58 @@ impl<'a> IterLayer for QueryIterLayer<'a> {
self.cursor self.cursor
} }
} }
/// Re-sort the given layers so that the next capture for the `layers[0]` is
/// the earliest capture in the document for all layers.
///
/// This function assumes that `layers` is already sorted except for the
/// first layer in the `Vec`. This function shifts the first layer later in
/// the `Vec` after any layers with earlier captures.
///
/// This is quicker than a regular full sort: it can only take as many
/// iterations as the number of layers and usually takes many fewer than
/// the full number of layers. The case when `layers[0]` is already the
/// layer with the earliest capture and the sort is a no-op is a fast-lane
/// which only takes one comparison operation.
///
/// This function also removes any layers which have no more query captures
/// to emit.
fn sort_layers<L: IterLayer>(layers: &mut Vec<L>) {
while !layers.is_empty() {
// If `Layer::sort_key` returns `None`, the layer has no more captures
// to emit and can be removed.
if let Some(sort_key) = layers[0].sort_key() {
let mut i = 0;
while i + 1 < layers.len() {
if let Some(next_offset) = layers[i + 1].sort_key() {
// Compare `0`'s sort key to `i + 1`'s. If `i + 1` comes
// before `0`, shift the `0` layer so it comes after the
// `i + 1` layers.
if next_offset < sort_key {
i += 1;
continue;
}
} else {
let layer = layers.remove(i + 1);
PARSER.with(|ts_parser| {
let highlighter = &mut ts_parser.borrow_mut();
highlighter.cursors.push(layer.cursor());
});
}
break;
}
if i > 0 {
layers[0..(i + 1)].rotate_left(1);
}
break;
} else {
let layer = layers.remove(0);
PARSER.with(|ts_parser| {
let highlighter = &mut ts_parser.borrow_mut();
highlighter.cursors.push(layer.cursor());
});
}
}
} }
#[derive(Clone)] #[derive(Clone)]
@ -2473,42 +2525,9 @@ impl<'a> HighlightIter<'a> {
} else { } else {
result = event.map(Ok); result = event.map(Ok);
} }
self.sort_layers(); sort_layers(&mut self.layers);
result result
} }
fn sort_layers(&mut self) {
while !self.layers.is_empty() {
if let Some(sort_key) = self.layers[0].sort_key() {
let mut i = 0;
while i + 1 < self.layers.len() {
if let Some(next_offset) = self.layers[i + 1].sort_key() {
if next_offset < sort_key {
i += 1;
continue;
}
} else {
let layer = self.layers.remove(i + 1);
PARSER.with(|ts_parser| {
let highlighter = &mut ts_parser.borrow_mut();
highlighter.cursors.push(layer.cursor);
});
}
break;
}
if i > 0 {
self.layers[0..(i + 1)].rotate_left(1);
}
break;
} else {
let layer = self.layers.remove(0);
PARSER.with(|ts_parser| {
let highlighter = &mut ts_parser.borrow_mut();
highlighter.cursors.push(layer.cursor);
});
}
}
}
} }
impl<'a> Iterator for HighlightIter<'a> { impl<'a> Iterator for HighlightIter<'a> {
@ -2660,7 +2679,7 @@ impl<'a> Iterator for HighlightIter<'a> {
} }
} }
self.sort_layers(); sort_layers(&mut self.layers);
continue 'main; continue 'main;
} }
@ -2669,7 +2688,7 @@ impl<'a> Iterator for HighlightIter<'a> {
// a different layer, then skip over this one. // a different layer, then skip over this one.
if let Some((last_start, last_end, last_depth)) = self.last_highlight_range { if let Some((last_start, last_end, last_depth)) = self.last_highlight_range {
if range.start == last_start && range.end == last_end && layer.depth < last_depth { if range.start == last_start && range.end == last_end && layer.depth < last_depth {
self.sort_layers(); sort_layers(&mut self.layers);
continue 'main; continue 'main;
} }
} }
@ -2688,7 +2707,7 @@ impl<'a> Iterator for HighlightIter<'a> {
} }
} }
self.sort_layers(); sort_layers(&mut self.layers);
continue 'main; continue 'main;
} }
} }
@ -2723,7 +2742,7 @@ impl<'a> Iterator for HighlightIter<'a> {
.emit_event(range.start, Some(HighlightEvent::HighlightStart(highlight))); .emit_event(range.start, Some(HighlightEvent::HighlightStart(highlight)));
} }
self.sort_layers(); sort_layers(&mut self.layers);
} }
} }
} }
@ -2937,7 +2956,7 @@ fn pretty_print_tree_impl<W: fmt::Write>(
struct QueryIterLayer<'a> { struct QueryIterLayer<'a> {
cursor: QueryCursor, cursor: QueryCursor,
captures: iter::Peekable<QueryCaptures<'a, 'a, RopeProvider<'a>, &'a [u8]>>, captures: RefCell<iter::Peekable<QueryCaptures<'a, 'a, RopeProvider<'a>, &'a [u8]>>>,
layer: &'a LanguageLayer, layer: &'a LanguageLayer,
} }
@ -2947,16 +2966,6 @@ impl<'a> fmt::Debug for QueryIterLayer<'a> {
} }
} }
impl<'a> QueryIterLayer<'a> {
fn sort_key(&mut self) -> Option<(usize, isize)> {
let depth = -(self.layer.depth as isize);
let (match_, capture_index) = self.captures.peek()?;
let start = match_.captures[*capture_index].node.start_byte();
Some((start, depth))
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct QueryIter<'a> { pub struct QueryIter<'a> {
layers: Vec<QueryIterLayer<'a>>, layers: Vec<QueryIterLayer<'a>>,
@ -2966,38 +2975,8 @@ impl<'a> Iterator for QueryIter<'a> {
type Item = (&'a LanguageLayer, QueryMatch<'a, 'a>, usize); type Item = (&'a LanguageLayer, QueryMatch<'a, 'a>, usize);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
// Sort the layers so that the first layer in the Vec has the next // Sort the layers so that the first layer contains the next capture.
// capture ordered by start byte and depth (descending). sort_layers(&mut self.layers);
while !self.layers.is_empty() {
if let Some(sort_key) = self.layers[0].sort_key() {
let mut i = 0;
while i + 1 < self.layers.len() {
if let Some(next_sort_key) = self.layers[i + 1].sort_key() {
if next_sort_key < sort_key {
i += 1;
continue;
}
} else {
let layer = self.layers.remove(i + 1);
PARSER.with(|ts_parser| {
let parser = &mut ts_parser.borrow_mut();
parser.cursors.push(layer.cursor);
});
}
break;
}
if i > 0 {
self.layers[0..(i + 1)].rotate_left(1);
}
break;
} else {
let layer = self.layers.remove(0);
PARSER.with(|ts_parser| {
let parser = &mut ts_parser.borrow_mut();
parser.cursors.push(layer.cursor);
})
}
}
// Emit the next capture from the lowest layer. If there are no more // Emit the next capture from the lowest layer. If there are no more
// layers, terminate. // layers, terminate.

Loading…
Cancel
Save