perf: avoid eager diff loading and full-file typing work

This commit is contained in:
2026-10-11 15:06:05 +02:00
parent 7b4bc80538
commit 2e05725a38
11 changed files with 1881 additions and 386 deletions
+25 -12
View File
@@ -5,7 +5,7 @@ use std::{
sync::{
Arc,
atomic::{AtomicBool, AtomicU64, Ordering},
mpsc::{self, Receiver, SyncSender},
mpsc::{self, Receiver, Sender},
},
thread::{self, JoinHandle},
};
@@ -25,7 +25,7 @@ use crate::{
type DiffResult = (u64, Result<DiffOutcome, String>);
struct DiffWorker {
requests: Option<SyncSender<(u64, DiffOperation)>>,
requests: Option<Sender<(u64, DiffOperation)>>,
results: Option<Receiver<DiffResult>>,
cancelled: Arc<AtomicBool>,
stopped: Arc<AtomicBool>,
@@ -36,7 +36,7 @@ struct DiffWorker {
impl DiffWorker {
fn start(root: PathBuf) -> Result<Self, String> {
let (requests, incoming) = mpsc::sync_channel::<(u64, DiffOperation)>(1);
let (requests, incoming) = mpsc::channel::<(u64, DiffOperation)>();
let (outgoing, results) = mpsc::sync_channel(1);
let cancelled = Arc::new(AtomicBool::new(false));
let stopped = Arc::new(AtomicBool::new(false));
@@ -56,7 +56,7 @@ impl DiffWorker {
if stop.load(Ordering::Acquire) {
break;
}
if cancelled_id.load(Ordering::Acquire) == id {
if cancelled_id.load(Ordering::Acquire) >= id {
continue;
}
let result = (|| {
@@ -68,6 +68,9 @@ impl DiffWorker {
DiffOperation::Discover => {
repository.catalog().map(DiffOutcome::Catalog)
}
DiffOperation::ListRemote(remote) => {
repository.list_remote(&remote).map(DiffOutcome::Catalog)
}
DiffOperation::FetchRemote(remote) => {
repository.fetch_remote(&remote).map(DiffOutcome::Catalog)
}
@@ -76,8 +79,18 @@ impl DiffWorker {
after,
buffers,
} => repository
.compare(&before, &after, &buffers)
.compare(id, &before, &after, &buffers)
.map(DiffOutcome::Comparison),
DiffOperation::LoadFile {
comparison_id,
file_index,
} => repository.load_file(comparison_id, file_index).map(|file| {
DiffOutcome::File {
comparison_id,
file_index,
file,
}
}),
}
})();
if stop.load(Ordering::Acquire) || outgoing.send((id, result)).is_err() {
@@ -98,16 +111,15 @@ impl DiffWorker {
}
fn request(&mut self, id: u64, operation: DiffOperation) -> Result<(), String> {
if let Some(previous) = self.pending.take() {
self.cancelled_request.store(previous, Ordering::Release);
self.cancelled.store(true, Ordering::Release);
}
self.requests
.as_ref()
.expect("live diff worker has a sender")
.try_send((id, operation))
.map_err(|error| match error {
mpsc::TrySendError::Full(_) => "Diff worker is already busy".to_owned(),
mpsc::TrySendError::Disconnected(_) => {
"Diff worker stopped unexpectedly".to_owned()
}
})?;
.send((id, operation))
.map_err(|_| "Diff worker stopped unexpectedly".to_owned())?;
self.pending = Some(id);
Ok(())
}
@@ -3387,6 +3399,7 @@ end
path: PathBuf::from("buffer.txt"),
old_path: None,
status: FileStatus::Modified,
loaded: true,
before: vec!["base".into()],
after: vec!["base".into()],
before_eof: false,