mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-30 14:17:02 +00:00
language: Memoize value of has_edits_since for a given buffer version (#13656)
Some checks are pending
CI / Check formatting and spelling (push) Waiting to run
CI / (macOS) Run Clippy and tests (push) Waiting to run
CI / (Linux) Run Clippy and tests (push) Waiting to run
CI / (Windows) Run Clippy and tests (push) Waiting to run
CI / Create a macOS bundle (push) Blocked by required conditions
CI / Create a Linux bundle (push) Blocked by required conditions
CI / Create arm64 Linux bundle (push) Blocked by required conditions
Deploy Docs / Deploy Docs (push) Waiting to run
Some checks are pending
CI / Check formatting and spelling (push) Waiting to run
CI / (macOS) Run Clippy and tests (push) Waiting to run
CI / (Linux) Run Clippy and tests (push) Waiting to run
CI / (Windows) Run Clippy and tests (push) Waiting to run
CI / Create a macOS bundle (push) Blocked by required conditions
CI / Create a Linux bundle (push) Blocked by required conditions
CI / Create arm64 Linux bundle (push) Blocked by required conditions
Deploy Docs / Deploy Docs (push) Waiting to run
As a drive-by of https://github.com/zed-industries/zed/pull/13654, I've noticed that the editor felt sluggish after I've undone the changes made by the replacement. It turns out that we are repeatedly checking whether there are any edits to estabilish dirty/conflict state of a buffer, even though this operation is pure; this PR stores away the result of a computation and refers to it before rerunning it. Release Notes: - Improve editor's performance with large undo histories
This commit is contained in:
parent
0761383752
commit
218629cdd4
1 changed files with 26 additions and 2 deletions
|
@ -31,6 +31,7 @@ use smallvec::SmallVec;
|
|||
use smol::future::yield_now;
|
||||
use std::{
|
||||
any::Any,
|
||||
cell::Cell,
|
||||
cmp::{self, Ordering},
|
||||
collections::BTreeMap,
|
||||
ffi::OsStr,
|
||||
|
@ -113,6 +114,9 @@ pub struct Buffer {
|
|||
capability: Capability,
|
||||
has_conflict: bool,
|
||||
diff_base_version: usize,
|
||||
/// Memoize calls to has_changes_since(saved_version).
|
||||
/// The contents of a cell are (self.version, has_changes) at the time of a last call.
|
||||
has_unsaved_edits: Cell<(clock::Global, bool)>,
|
||||
}
|
||||
|
||||
/// An immutable, cheaply cloneable representation of a fixed
|
||||
|
@ -690,6 +694,7 @@ impl Buffer {
|
|||
reload_task: None,
|
||||
transaction_depth: 0,
|
||||
was_dirty_before_starting_transaction: None,
|
||||
has_unsaved_edits: Cell::new((buffer.version(), false)),
|
||||
text: buffer,
|
||||
diff_base: diff_base
|
||||
.map(|mut raw_diff_base| {
|
||||
|
@ -799,6 +804,8 @@ impl Buffer {
|
|||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
self.saved_version = version;
|
||||
self.has_unsaved_edits
|
||||
.set((self.saved_version().clone(), false));
|
||||
self.has_conflict = false;
|
||||
self.saved_mtime = mtime;
|
||||
cx.emit(Event::Saved);
|
||||
|
@ -860,6 +867,8 @@ impl Buffer {
|
|||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
self.saved_version = version;
|
||||
self.has_unsaved_edits
|
||||
.set((self.saved_version.clone(), false));
|
||||
self.text.set_line_ending(line_ending);
|
||||
self.saved_mtime = mtime;
|
||||
cx.emit(Event::Reloaded);
|
||||
|
@ -1516,10 +1525,25 @@ impl Buffer {
|
|||
self.end_transaction(cx)
|
||||
}
|
||||
|
||||
fn has_unsaved_edits(&self) -> bool {
|
||||
let (last_version, has_unsaved_edits) = self.has_unsaved_edits.take();
|
||||
|
||||
if last_version == self.version {
|
||||
self.has_unsaved_edits
|
||||
.set((last_version, has_unsaved_edits));
|
||||
return has_unsaved_edits;
|
||||
}
|
||||
|
||||
let has_edits = self.has_edits_since(&self.saved_version);
|
||||
self.has_unsaved_edits
|
||||
.set((self.version.clone(), has_edits));
|
||||
has_edits
|
||||
}
|
||||
|
||||
/// Checks if the buffer has unsaved changes.
|
||||
pub fn is_dirty(&self) -> bool {
|
||||
self.has_conflict
|
||||
|| self.has_edits_since(&self.saved_version)
|
||||
|| self.has_unsaved_edits()
|
||||
|| self
|
||||
.file
|
||||
.as_ref()
|
||||
|
@ -1531,7 +1555,7 @@ impl Buffer {
|
|||
pub fn has_conflict(&self) -> bool {
|
||||
self.has_conflict
|
||||
|| self.file.as_ref().map_or(false, |file| {
|
||||
file.mtime() > self.saved_mtime && self.has_edits_since(&self.saved_version)
|
||||
file.mtime() > self.saved_mtime && self.has_unsaved_edits()
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue