From eeba0993aa936219e0e0b1a3f2a15fe6acce7488 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 10 Dec 2021 09:16:58 +0100 Subject: [PATCH] Optimize anchor comparison and take full advantage of fragment IDs --- Cargo.lock | 1 + crates/text/Cargo.toml | 1 + crates/text/src/anchor.rs | 12 +++++++----- crates/text/src/locator.rs | 6 ++++++ crates/text/src/text.rs | 12 ++++-------- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a1188259ac..3c89563e3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4853,6 +4853,7 @@ dependencies = [ "ctor", "env_logger", "gpui", + "lazy_static", "log", "parking_lot", "rand 0.8.3", diff --git a/crates/text/Cargo.toml b/crates/text/Cargo.toml index 2b68a71a08..f4b7d7453f 100644 --- a/crates/text/Cargo.toml +++ b/crates/text/Cargo.toml @@ -15,6 +15,7 @@ collections = { path = "../collections" } sum_tree = { path = "../sum_tree" } anyhow = "1.0.38" arrayvec = "0.7.1" +lazy_static = "1.4" log = "0.4" parking_lot = "0.11" rand = { version = "0.8.3", optional = true } diff --git a/crates/text/src/anchor.rs b/crates/text/src/anchor.rs index a781c9f887..85be47ad90 100644 --- a/crates/text/src/anchor.rs +++ b/crates/text/src/anchor.rs @@ -28,15 +28,17 @@ impl Anchor { } pub fn cmp<'a>(&self, other: &Anchor, buffer: &Snapshot) -> Result { - let offset_comparison = if self.timestamp == other.timestamp { - self.offset.cmp(&other.offset) + let fragment_id_comparison = if self.timestamp == other.timestamp { + Ordering::Equal } else { buffer - .full_offset_for_anchor(self) - .cmp(&buffer.full_offset_for_anchor(other)) + .fragment_id_for_anchor(self) + .cmp(&buffer.fragment_id_for_anchor(other)) }; - Ok(offset_comparison.then_with(|| self.bias.cmp(&other.bias))) + Ok(fragment_id_comparison + .then_with(|| self.offset.cmp(&other.offset)) + .then_with(|| self.bias.cmp(&other.bias))) } pub fn bias_left(&self, buffer: &Buffer) -> Anchor { diff --git a/crates/text/src/locator.rs b/crates/text/src/locator.rs index 249e79b6fd..e4feaf99ac 100644 --- a/crates/text/src/locator.rs +++ b/crates/text/src/locator.rs @@ -1,6 +1,12 @@ +use lazy_static::lazy_static; use smallvec::{smallvec, SmallVec}; use std::iter; +lazy_static! { + pub static ref MIN: Locator = Locator::min(); + pub static ref MAX: Locator = Locator::max(); +} + #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Locator(SmallVec<[u64; 4]>); diff --git a/crates/text/src/text.rs b/crates/text/src/text.rs index d8c9c43d5f..6df4a67881 100644 --- a/crates/text/src/text.rs +++ b/crates/text/src/text.rs @@ -1763,12 +1763,11 @@ impl Snapshot { } } - fn full_offset_for_anchor(&self, anchor: &Anchor) -> FullOffset { + fn fragment_id_for_anchor(&self, anchor: &Anchor) -> &Locator { if *anchor == Anchor::min() { - Default::default() + &locator::MIN } else if *anchor == Anchor::max() { - let text = self.fragments.summary().text; - FullOffset(text.visible + text.deleted) + &locator::MAX } else { let anchor_key = InsertionFragmentKey { timestamp: anchor.timestamp, @@ -1790,10 +1789,7 @@ impl Snapshot { } let insertion = insertion_cursor.item().expect("invalid insertion"); debug_assert_eq!(insertion.timestamp, anchor.timestamp, "invalid insertion"); - - let mut fragment_cursor = self.fragments.cursor::<(Option<&Locator>, FullOffset)>(); - fragment_cursor.seek(&Some(&insertion.fragment_id), Bias::Left, &None); - fragment_cursor.start().1 + (anchor.offset - insertion.split_offset) + &insertion.fragment_id } }