Skip to content

Commit 1e18a0b

Browse files
authored
Merge pull request #530 from dtolnay/byterange
Optimize byte_range
2 parents 8c4135f + 7f5973b commit 1e18a0b

File tree

1 file changed

+37
-23
lines changed

1 file changed

+37
-23
lines changed

src/fallback.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -375,38 +375,52 @@ impl FileInfo {
375375
}
376376

377377
fn byte_range(&mut self, span: Span) -> Range<usize> {
378-
let lo_char = (span.lo - self.span.lo) as usize;
378+
self.byte(span.lo)..self.byte(span.hi)
379+
}
380+
381+
fn byte(&mut self, ch: u32) -> usize {
382+
let char_index = (ch - self.span.lo) as usize;
379383

380384
// Look up offset of the largest already-computed char index that is
381-
// less than or equal to the current requested one. We resume counting
382-
// chars from that point.
383-
let (&last_char_index, &last_byte_offset) = self
385+
// less than or equal to the current requested one.
386+
let (&previous_char_index, &previous_byte_offset) = self
384387
.char_index_to_byte_offset
385-
.range(..=lo_char)
388+
.range(..=char_index)
386389
.next_back()
387390
.unwrap_or((&0, &0));
388391

389-
let lo_byte = if last_char_index == lo_char {
390-
last_byte_offset
391-
} else {
392-
let total_byte_offset = match self.source_text[last_byte_offset..]
393-
.char_indices()
394-
.nth(lo_char - last_char_index)
392+
if previous_char_index == char_index {
393+
return previous_byte_offset;
394+
}
395+
396+
// Look up next char index that is greater than the requested one. We
397+
// resume counting chars from whichever point is closer.
398+
let byte_offset = match self.char_index_to_byte_offset.range(char_index..).next() {
399+
Some((&next_char_index, &next_byte_offset))
400+
if next_char_index - char_index < char_index - previous_char_index =>
395401
{
396-
Some((additional_offset, _ch)) => last_byte_offset + additional_offset,
397-
None => self.source_text.len(),
398-
};
399-
self.char_index_to_byte_offset
400-
.insert(lo_char, total_byte_offset);
401-
total_byte_offset
402+
self.source_text[..next_byte_offset]
403+
.char_indices()
404+
.nth_back(next_char_index - char_index - 1)
405+
.unwrap()
406+
.0
407+
}
408+
_ => {
409+
match self.source_text[previous_byte_offset..]
410+
.char_indices()
411+
.nth(char_index - previous_char_index)
412+
{
413+
Some((byte_offset_from_previous, _ch)) => {
414+
previous_byte_offset + byte_offset_from_previous
415+
}
416+
None => self.source_text.len(),
417+
}
418+
}
402419
};
403420

404-
let trunc_lo = &self.source_text[lo_byte..];
405-
let char_len = (span.hi - span.lo) as usize;
406-
lo_byte..match trunc_lo.char_indices().nth(char_len) {
407-
Some((offset, _ch)) => lo_byte + offset,
408-
None => self.source_text.len(),
409-
}
421+
self.char_index_to_byte_offset
422+
.insert(char_index, byte_offset);
423+
byte_offset
410424
}
411425

412426
fn source_text(&mut self, span: Span) -> String {

0 commit comments

Comments
 (0)