Un serialize project search (#2857)

This is the first batch of improvements to current project search. There
are few things we can do better still, but I want to get this out in
next Preview.
Most of the slowness at this point seems to stem from updating UI too
often.

Release Notes:
- Improved project search by making it report results sooner.

---------

Co-authored-by: Julia Risley <julia@zed.dev>
This commit is contained in:
Piotr Osiewicz 2023-08-26 01:31:52 +02:00 committed by GitHub
parent 104f5ae9cd
commit 2495d6581e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 489 additions and 300 deletions

View file

@ -4,7 +4,7 @@ use crate::{
};
use call::{room, ActiveCall, ParticipantLocation, Room};
use client::{User, RECEIVE_TIMEOUT};
use collections::HashSet;
use collections::{HashMap, HashSet};
use editor::{
test::editor_test_context::EditorTestContext, ConfirmCodeAction, ConfirmCompletion,
ConfirmRename, Editor, ExcerptRange, MultiBuffer, Redo, Rename, ToggleCodeActions, Undo,
@ -4821,15 +4821,16 @@ async fn test_project_search(
let project_b = client_b.build_remote_project(project_id, cx_b).await;
// Perform a search as the guest.
let results = project_b
.update(cx_b, |project, cx| {
project.search(
SearchQuery::text("world", false, false, Vec::new(), Vec::new()),
cx,
)
})
.await
.unwrap();
let mut results = HashMap::default();
let mut search_rx = project_b.update(cx_b, |project, cx| {
project.search(
SearchQuery::text("world", false, false, Vec::new(), Vec::new()),
cx,
)
});
while let Some((buffer, ranges)) = search_rx.next().await {
results.entry(buffer).or_insert(ranges);
}
let mut ranges_by_path = results
.into_iter()

View file

@ -6,7 +6,7 @@ use crate::{
use anyhow::{anyhow, Result};
use call::ActiveCall;
use client::RECEIVE_TIMEOUT;
use collections::BTreeMap;
use collections::{BTreeMap, HashMap};
use editor::Bias;
use fs::{repository::GitFileStatus, FakeFs, Fs as _};
use futures::StreamExt as _;
@ -722,7 +722,7 @@ async fn apply_client_operation(
if detach { "detaching" } else { "awaiting" }
);
let search = project.update(cx, |project, cx| {
let mut search = project.update(cx, |project, cx| {
project.search(
SearchQuery::text(query, false, false, Vec::new(), Vec::new()),
cx,
@ -730,15 +730,13 @@ async fn apply_client_operation(
});
drop(project);
let search = cx.background().spawn(async move {
search
.await
.map_err(|err| anyhow!("search request failed: {:?}", err))
let mut results = HashMap::default();
while let Some((buffer, ranges)) = search.next().await {
results.entry(buffer).or_insert(ranges);
}
results
});
if detach {
cx.update(|cx| search.detach_and_log_err(cx));
} else {
search.await?;
}
search.await;
}
ClientOperation::WriteFsEntry {