From 7c66a5c1216f334bfa29bddd7e4c3a451900efbb Mon Sep 17 00:00:00 2001 From: Rose Hogenson Date: Thu, 11 Jan 2024 18:01:10 -0800 Subject: Optimise line_offset for the ASCII case. In most cases we really won't need the full binary search. We can check quickly for ASCII without ever printing anything, and fall back to binary search if we find any Unicode characters. --- src/main.rs | 19 +++++++++++++++++++ src/rope.rs | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/main.rs b/src/main.rs index 2b6a814..0dfe335 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,25 @@ fn line_offset( line: &Rope, col: u16, ) -> Result> { + let mut n = 0; + for i in 0.. { + if i == line.len() { + return Ok(i); + } + let c = line.byte(i); + if c > 127 { + break; + } + if n == col { + return Ok(i); + } + if c == b'\t' { + n += 8 - n % 8; + } else { + n += 1; + } + } + // Binary search :D let mut lo = 0; let mut hi = line.len() + 1; diff --git a/src/rope.rs b/src/rope.rs index 31c3296..737d949 100644 --- a/src/rope.rs +++ b/src/rope.rs @@ -355,4 +355,23 @@ impl Rope { } } } + + pub fn byte(&self, i: usize) -> u8 { + if i >= self.len() { + panic!("Index {} out of range 0..{}", i, self.len()); + } + match self { + Rope(Node::Leaf(l)) => l.bytes()[i], + Rope(Node::Branch(b)) => { + let mut i = i; + for c in b.children().iter() { + if i < c.len() { + return c.byte(i); + } + i -= c.len(); + } + panic!("unreachable"); + } + } + } } -- cgit v1.3.1