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/9320/head
Michael Davis 1 year ago
parent bf627c8904
commit 020d0ce7ec
No known key found for this signature in database

@ -1391,7 +1391,7 @@ impl Syntax {
range: Option<std::ops::Range<usize>>,
cancellation_flag: Option<&'a AtomicUsize>,
) -> impl Iterator<Item = Result<HighlightEvent, Error>> + 'a {
let mut layers = self
let mut layers: Vec<_> = self
.layers
.iter()
.filter_map(|(_, layer)| {
@ -1438,11 +1438,13 @@ impl Syntax {
depth: layer.depth, // TODO: just reuse `layer`
})
})
.collect::<Vec<_>>();
.collect();
layers.sort_unstable_by_key(|layer| layer.sort_key());
let mut result = HighlightIter {
sort_layers(&mut layers);
HighlightIter {
source,
byte_offset: range.map_or(0, |r| r.start),
cancellation_flag,
@ -1450,9 +1452,7 @@ impl Syntax {
layers,
next_event: None,
last_highlight_range: None,
};
result.sort_layers();
result
}
}
pub fn tree_for_byte_range(&self, start: usize, end: usize) -> &Tree {
@ -2136,6 +2136,58 @@ impl<'a> IterLayer for QueryIterLayer<'a> {
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)]
@ -2266,42 +2318,9 @@ impl<'a> HighlightIter<'a> {
} else {
result = event.map(Ok);
}
self.sort_layers();
sort_layers(&mut self.layers);
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> {
@ -2453,7 +2472,7 @@ impl<'a> Iterator for HighlightIter<'a> {
}
}
self.sort_layers();
sort_layers(&mut self.layers);
continue 'main;
}
@ -2462,7 +2481,7 @@ impl<'a> Iterator for HighlightIter<'a> {
// a different layer, then skip over this one.
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 {
self.sort_layers();
sort_layers(&mut self.layers);
continue 'main;
}
}
@ -2481,7 +2500,7 @@ impl<'a> Iterator for HighlightIter<'a> {
}
}
self.sort_layers();
sort_layers(&mut self.layers);
continue 'main;
}
}
@ -2516,7 +2535,7 @@ impl<'a> Iterator for HighlightIter<'a> {
.emit_event(range.start, Some(HighlightEvent::HighlightStart(highlight)));
}
self.sort_layers();
sort_layers(&mut self.layers);
}
}
}
@ -2728,7 +2747,7 @@ fn pretty_print_tree_impl<W: fmt::Write>(
struct QueryIterLayer<'a> {
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,
}
@ -2738,16 +2757,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)]
pub struct QueryIter<'a> {
layers: Vec<QueryIterLayer<'a>>,
@ -2757,38 +2766,8 @@ impl<'a> Iterator for QueryIter<'a> {
type Item = (&'a LanguageLayer, QueryMatch<'a, 'a>, usize);
fn next(&mut self) -> Option<Self::Item> {
// Sort the layers so that the first layer in the Vec has the next
// capture ordered by start byte and depth (descending).
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);
})
}
}
// Sort the layers so that the first layer contains the next capture.
sort_layers(&mut self.layers);
// Emit the next capture from the lowest layer. If there are no more
// layers, terminate.

Loading…
Cancel
Save