From dffddaec4c53c8aa58ed0bf9d5aaf7e3a088517b Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Fri, 12 Apr 2024 10:40:35 -0600 Subject: [PATCH] Revert "Revert "language: Remove buffer fingerprinting (#9007)"" (#9671) This reverts commit caed275fbf58af9c3ac89ef11229d0a6bd13016f. NOTE: this should not be merged until #9668 is on stable and the `ZedVersion#can_collaborate` is updated to exclude all clients without that change. Release Notes: - N/A --------- Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> --- Cargo.lock | 18 --------- crates/collab/src/rpc/connection_pool.rs | 2 +- .../random_project_collaboration_tests.rs | 10 ++--- crates/copilot/src/copilot.rs | 1 - crates/editor/src/items.rs | 3 +- crates/language/src/buffer.rs | 37 +++---------------- crates/language/src/proto.rs | 5 --- crates/project/src/project.rs | 12 ++---- crates/project/src/project_tests.rs | 7 +--- crates/rope/Cargo.toml | 1 - crates/rope/src/rope.rs | 18 --------- crates/rpc/proto/zed.proto | 6 +-- crates/worktree/src/worktree.rs | 14 ++----- 13 files changed, 22 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d1656e08a..92ede849ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1578,17 +1578,6 @@ dependencies = [ "workspace", ] -[[package]] -name = "bromberg_sl2" -version = "0.6.0" -source = "git+https://github.com/zed-industries/bromberg_sl2?rev=950bc5482c216c395049ae33ae4501e08975f17f#950bc5482c216c395049ae33ae4501e08975f17f" -dependencies = [ - "digest 0.9.0", - "lazy_static", - "rayon", - "seq-macro", -] - [[package]] name = "bstr" version = "1.6.2" @@ -7942,7 +7931,6 @@ name = "rope" version = "0.1.0" dependencies = [ "arrayvec", - "bromberg_sl2", "criterion", "gpui", "log", @@ -8499,12 +8487,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" -[[package]] -name = "seq-macro" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9f47faea3cad316faa914d013d24f471cd90bfca1a0c70f05a3f42c6441e99" - [[package]] name = "serde" version = "1.0.196" diff --git a/crates/collab/src/rpc/connection_pool.rs b/crates/collab/src/rpc/connection_pool.rs index ea40d39122..856fc616a3 100644 --- a/crates/collab/src/rpc/connection_pool.rs +++ b/crates/collab/src/rpc/connection_pool.rs @@ -31,7 +31,7 @@ impl fmt::Display for ZedVersion { impl ZedVersion { pub fn can_collaborate(&self) -> bool { - self.0 >= SemanticVersion::new(0, 127, 3) + self.0 >= SemanticVersion::new(0, 129, 2) } } diff --git a/crates/collab/src/tests/random_project_collaboration_tests.rs b/crates/collab/src/tests/random_project_collaboration_tests.rs index 1874b9ea6d..8674069dff 100644 --- a/crates/collab/src/tests/random_project_collaboration_tests.rs +++ b/crates/collab/src/tests/random_project_collaboration_tests.rs @@ -1347,13 +1347,11 @@ impl RandomizedTest for ProjectCollaborationTest { client.username ); - let host_saved_version_fingerprint = - host_buffer.read_with(host_cx, |b, _| b.saved_version_fingerprint()); - let guest_saved_version_fingerprint = - guest_buffer.read_with(client_cx, |b, _| b.saved_version_fingerprint()); + let host_is_dirty = host_buffer.read_with(host_cx, |b, _| b.is_dirty()); + let guest_is_dirty = guest_buffer.read_with(client_cx, |b, _| b.is_dirty()); assert_eq!( - guest_saved_version_fingerprint, host_saved_version_fingerprint, - "guest {} saved fingerprint does not match host's for path {path:?} in project {project_id}", + guest_is_dirty, host_is_dirty, + "guest {} dirty state does not match host's for path {path:?} in project {project_id}", client.username ); diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index d82eb8cc78..99f94b5511 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -1255,7 +1255,6 @@ mod tests { &self, _: BufferId, _: &clock::Global, - _: language::RopeFingerprint, _: language::LineEnding, _: Option, _: &mut AppContext, diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 30e3fbe25c..b62a767494 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -735,9 +735,8 @@ impl Item for Editor { buffer .update(&mut cx, |buffer, cx| { let version = buffer.saved_version().clone(); - let fingerprint = buffer.saved_version_fingerprint(); let mtime = buffer.saved_mtime(); - buffer.did_save(version, fingerprint, mtime, cx); + buffer.did_save(version, mtime, cx); }) .ok(); } diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 3b283de845..1c5a6b0644 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -45,9 +45,9 @@ use text::operation_queue::OperationQueue; use text::*; pub use text::{ Anchor, Bias, Buffer as TextBuffer, BufferId, BufferSnapshot as TextBufferSnapshot, Edit, - OffsetRangeExt, OffsetUtf16, Patch, Point, PointUtf16, Rope, RopeFingerprint, Selection, - SelectionGoal, Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint, - ToPointUtf16, Transaction, TransactionId, Unclipped, + OffsetRangeExt, OffsetUtf16, Patch, Point, PointUtf16, Rope, Selection, SelectionGoal, + Subscription, TextDimension, TextSummary, ToOffset, ToOffsetUtf16, ToPoint, ToPointUtf16, + Transaction, TransactionId, Unclipped, }; use theme::SyntaxTheme; #[cfg(any(test, feature = "test-support"))] @@ -87,8 +87,6 @@ pub struct Buffer { /// The version vector when this buffer was last loaded from /// or saved to disk. saved_version: clock::Global, - /// A hash of the current contents of the buffer's file. - file_fingerprint: RopeFingerprint, transaction_depth: usize, was_dirty_before_starting_transaction: Option, reload_task: Option>>, @@ -379,7 +377,6 @@ pub trait LocalFile: File { &self, buffer_id: BufferId, version: &clock::Global, - fingerprint: RopeFingerprint, line_ending: LineEnding, mtime: Option, cx: &mut AppContext, @@ -562,7 +559,6 @@ impl Buffer { diff_base: self.diff_base.as_ref().map(|h| h.to_string()), line_ending: proto::serialize_line_ending(self.line_ending()) as i32, saved_version: proto::serialize_version(&self.saved_version), - saved_version_fingerprint: proto::serialize_fingerprint(self.file_fingerprint), saved_mtime: self.saved_mtime.map(|time| time.into()), } } @@ -642,7 +638,6 @@ impl Buffer { Self { saved_mtime, saved_version: buffer.version(), - file_fingerprint: buffer.as_rope().fingerprint(), reload_task: None, transaction_depth: 0, was_dirty_before_starting_transaction: None, @@ -717,11 +712,6 @@ impl Buffer { &self.saved_version } - /// The fingerprint of the buffer's text when the buffer was last saved or reloaded from disk. - pub fn saved_version_fingerprint(&self) -> RopeFingerprint { - self.file_fingerprint - } - /// The mtime of the buffer's file when the buffer was last saved or reloaded from disk. pub fn saved_mtime(&self) -> Option { self.saved_mtime @@ -754,13 +744,11 @@ impl Buffer { pub fn did_save( &mut self, version: clock::Global, - fingerprint: RopeFingerprint, mtime: Option, cx: &mut ModelContext, ) { self.saved_version = version; self.has_conflict = false; - self.file_fingerprint = fingerprint; self.saved_mtime = mtime; cx.emit(Event::Saved); cx.notify(); @@ -792,13 +780,7 @@ impl Buffer { this.apply_diff(diff, cx); tx.send(this.finalize_last_transaction().cloned()).ok(); this.has_conflict = false; - this.did_reload( - this.version(), - this.as_rope().fingerprint(), - this.line_ending(), - new_mtime, - cx, - ); + this.did_reload(this.version(), this.line_ending(), new_mtime, cx); } else { if !diff.edits.is_empty() || this @@ -809,13 +791,7 @@ impl Buffer { this.has_conflict = true; } - this.did_reload( - prev_version, - Rope::text_fingerprint(&new_text), - this.line_ending(), - this.saved_mtime, - cx, - ); + this.did_reload(prev_version, this.line_ending(), this.saved_mtime, cx); } this.reload_task.take(); @@ -828,20 +804,17 @@ impl Buffer { pub fn did_reload( &mut self, version: clock::Global, - fingerprint: RopeFingerprint, line_ending: LineEnding, mtime: Option, cx: &mut ModelContext, ) { self.saved_version = version; - self.file_fingerprint = fingerprint; self.text.set_line_ending(line_ending); self.saved_mtime = mtime; if let Some(file) = self.file.as_ref().and_then(|f| f.as_local()) { file.buffer_reloaded( self.remote_id(), &self.saved_version, - self.file_fingerprint, self.line_ending(), self.saved_mtime, cx, diff --git a/crates/language/src/proto.rs b/crates/language/src/proto.rs index 80c22a3b60..30c209db55 100644 --- a/crates/language/src/proto.rs +++ b/crates/language/src/proto.rs @@ -10,11 +10,6 @@ use text::*; pub use proto::{BufferState, Operation}; -/// Serializes a [`RopeFingerprint`] to be sent over RPC. -pub fn serialize_fingerprint(fingerprint: RopeFingerprint) -> String { - fingerprint.to_hex() -} - /// Deserializes a `[text::LineEnding]` from the RPC representation. pub fn deserialize_line_ending(message: proto::LineEnding) -> text::LineEnding { match message { diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 0571666cb7..6c27e4d612 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -97,7 +97,7 @@ use std::{ }; use task::static_source::{StaticSource, TrackedFile}; use terminals::Terminals; -use text::{Anchor, BufferId, RopeFingerprint}; +use text::{Anchor, BufferId}; use util::{ debug_panic, defer, http::{HttpClient, Url}, @@ -8526,7 +8526,6 @@ impl Project { buffer_id: buffer_id.into(), version: serialize_version(buffer.saved_version()), mtime: buffer.saved_mtime().map(|time| time.into()), - fingerprint: language::proto::serialize_fingerprint(buffer.saved_version_fingerprint()), }) } @@ -8619,9 +8618,6 @@ impl Project { buffer_id: buffer_id.into(), version: language::proto::serialize_version(buffer.saved_version()), mtime: buffer.saved_mtime().map(|time| time.into()), - fingerprint: language::proto::serialize_fingerprint( - buffer.saved_version_fingerprint(), - ), line_ending: language::proto::serialize_line_ending( buffer.line_ending(), ) as i32, @@ -9610,7 +9606,6 @@ impl Project { _: Arc, mut cx: AsyncAppContext, ) -> Result<()> { - let fingerprint = Default::default(); let version = deserialize_version(&envelope.payload.version); let buffer_id = BufferId::new(envelope.payload.buffer_id)?; let mtime = envelope.payload.mtime.map(|time| time.into()); @@ -9623,7 +9618,7 @@ impl Project { .or_else(|| this.incomplete_remote_buffers.get(&buffer_id).cloned()); if let Some(buffer) = buffer { buffer.update(cx, |buffer, cx| { - buffer.did_save(version, fingerprint, mtime, cx); + buffer.did_save(version, mtime, cx); }); } Ok(()) @@ -9638,7 +9633,6 @@ impl Project { ) -> Result<()> { let payload = envelope.payload; let version = deserialize_version(&payload.version); - let fingerprint = RopeFingerprint::default(); let line_ending = deserialize_line_ending( proto::LineEnding::from_i32(payload.line_ending) .ok_or_else(|| anyhow!("missing line ending"))?, @@ -9653,7 +9647,7 @@ impl Project { .or_else(|| this.incomplete_remote_buffers.get(&buffer_id).cloned()); if let Some(buffer) = buffer { buffer.update(cx, |buffer, cx| { - buffer.did_reload(version, fingerprint, line_ending, mtime, cx); + buffer.did_reload(version, line_ending, mtime, cx); }); } Ok(()) diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 3f43631513..fa00ea6736 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -3122,12 +3122,7 @@ async fn test_buffer_is_dirty(cx: &mut gpui::TestAppContext) { &[language::Event::Edited, language::Event::DirtyChanged] ); events.lock().clear(); - buffer.did_save( - buffer.version(), - buffer.as_rope().fingerprint(), - buffer.file().unwrap().mtime(), - cx, - ); + buffer.did_save(buffer.version(), buffer.file().unwrap().mtime(), cx); }); // after saving, the buffer is not dirty, and emits a saved event. diff --git a/crates/rope/Cargo.toml b/crates/rope/Cargo.toml index bd76303a62..e5fb441ff5 100644 --- a/crates/rope/Cargo.toml +++ b/crates/rope/Cargo.toml @@ -13,7 +13,6 @@ path = "src/rope.rs" [dependencies] arrayvec = "0.7.1" -bromberg_sl2 = { git = "https://github.com/zed-industries/bromberg_sl2", rev = "950bc5482c216c395049ae33ae4501e08975f17f" } log.workspace = true smallvec.workspace = true sum_tree.workspace = true diff --git a/crates/rope/src/rope.rs b/crates/rope/src/rope.rs index 6a78048fc4..0de0f5558f 100644 --- a/crates/rope/src/rope.rs +++ b/crates/rope/src/rope.rs @@ -4,7 +4,6 @@ mod point_utf16; mod unclipped; use arrayvec::ArrayString; -use bromberg_sl2::HashMatrix; use smallvec::SmallVec; use std::{ cmp, fmt, io, mem, @@ -26,12 +25,6 @@ const CHUNK_BASE: usize = 6; #[cfg(not(test))] const CHUNK_BASE: usize = 64; -/// Type alias to [`HashMatrix`], an implementation of a homomorphic hash function. Two [`Rope`] instances -/// containing the same text will produce the same fingerprint. This hash function is special in that -/// it allows us to hash individual chunks and aggregate them up the [`Rope`]'s tree, with the resulting -/// hash being equivalent to hashing all the text contained in the [`Rope`] at once. -pub type RopeFingerprint = HashMatrix; - #[derive(Clone, Default)] pub struct Rope { chunks: SumTree, @@ -42,10 +35,6 @@ impl Rope { Self::default() } - pub fn text_fingerprint(text: &str) -> RopeFingerprint { - bromberg_sl2::hash_strict(text.as_bytes()) - } - pub fn append(&mut self, rope: Rope) { let mut chunks = rope.chunks.cursor::<()>(); chunks.next(&()); @@ -424,10 +413,6 @@ impl Rope { self.clip_point(Point::new(row, u32::MAX), Bias::Left) .column } - - pub fn fingerprint(&self) -> RopeFingerprint { - self.chunks.summary().fingerprint - } } impl<'a> From<&'a str> for Rope { @@ -994,14 +979,12 @@ impl sum_tree::Item for Chunk { #[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct ChunkSummary { text: TextSummary, - fingerprint: RopeFingerprint, } impl<'a> From<&'a str> for ChunkSummary { fn from(text: &'a str) -> Self { Self { text: TextSummary::from(text), - fingerprint: Rope::text_fingerprint(text), } } } @@ -1011,7 +994,6 @@ impl sum_tree::Summary for ChunkSummary { fn add_summary(&mut self, summary: &Self, _: &()) { self.text += &summary.text; - self.fingerprint = self.fingerprint * summary.fingerprint; } } diff --git a/crates/rpc/proto/zed.proto b/crates/rpc/proto/zed.proto index b97cbead3b..8cbeed1ae8 100644 --- a/crates/rpc/proto/zed.proto +++ b/crates/rpc/proto/zed.proto @@ -750,7 +750,7 @@ message BufferSaved { uint64 buffer_id = 2; repeated VectorClockEntry version = 3; Timestamp mtime = 4; - string fingerprint = 5; + reserved 5; } message BufferReloaded { @@ -758,7 +758,7 @@ message BufferReloaded { uint64 buffer_id = 2; repeated VectorClockEntry version = 3; Timestamp mtime = 4; - string fingerprint = 5; + reserved 5; LineEnding line_ending = 6; } @@ -1605,7 +1605,7 @@ message BufferState { optional string diff_base = 4; LineEnding line_ending = 5; repeated VectorClockEntry saved_version = 6; - string saved_version_fingerprint = 7; + reserved 7; Timestamp saved_mtime = 8; } diff --git a/crates/worktree/src/worktree.rs b/crates/worktree/src/worktree.rs index d807131828..a3990ecfc6 100644 --- a/crates/worktree/src/worktree.rs +++ b/crates/worktree/src/worktree.rs @@ -31,9 +31,8 @@ use gpui::{ use ignore::IgnoreStack; use itertools::Itertools; use language::{ - proto::{deserialize_version, serialize_fingerprint, serialize_line_ending, serialize_version}, - Buffer, Capability, DiagnosticEntry, File as _, LineEnding, PointUtf16, Rope, RopeFingerprint, - Unclipped, + proto::{deserialize_version, serialize_line_ending, serialize_version}, + Buffer, Capability, DiagnosticEntry, File as _, LineEnding, PointUtf16, Rope, Unclipped, }; use lsp::{DiagnosticSeverity, LanguageServerId}; use parking_lot::Mutex; @@ -1175,7 +1174,6 @@ impl LocalWorktree { } let text = buffer.as_rope().clone(); - let fingerprint = text.fingerprint(); let version = buffer.version(); let save = self.write_file(path.as_ref(), text, buffer.line_ending(), cx); let fs = Arc::clone(&self.fs); @@ -1238,12 +1236,11 @@ impl LocalWorktree { buffer_id, version: serialize_version(&version), mtime: mtime.map(|time| time.into()), - fingerprint: serialize_fingerprint(fingerprint), })?; } buffer_handle.update(&mut cx, |buffer, cx| { - buffer.did_save(version.clone(), fingerprint, mtime, cx); + buffer.did_save(version.clone(), mtime, cx); })?; Ok(()) @@ -1644,11 +1641,10 @@ impl RemoteWorktree { }) .await?; let version = deserialize_version(&response.version); - let fingerprint = RopeFingerprint::default(); let mtime = response.mtime.map(|mtime| mtime.into()); buffer_handle.update(&mut cx, |buffer, cx| { - buffer.did_save(version.clone(), fingerprint, mtime, cx); + buffer.did_save(version.clone(), mtime, cx); })?; Ok(()) @@ -3030,7 +3026,6 @@ impl language::LocalFile for File { &self, buffer_id: BufferId, version: &clock::Global, - fingerprint: RopeFingerprint, line_ending: LineEnding, mtime: Option, cx: &mut AppContext, @@ -3044,7 +3039,6 @@ impl language::LocalFile for File { buffer_id: buffer_id.into(), version: serialize_version(version), mtime: mtime.map(|time| time.into()), - fingerprint: serialize_fingerprint(fingerprint), line_ending: serialize_line_ending(line_ending) as i32, }) .log_err();