sum_tree: Replace rayon with futures (#41586)

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Co-authored by: Kate <kate@zed.dev>
This commit is contained in:
Lukas Wirth
2025-10-31 10:39:01 +00:00
committed by GitHub
parent 7c29c6d7a6
commit f2ce06c7b0
67 changed files with 1271 additions and 640 deletions
+14 -7
View File
@@ -24,8 +24,8 @@ use collections::HashMap;
use fs::MTime;
use futures::channel::oneshot;
use gpui::{
App, AppContext as _, Context, Entity, EventEmitter, HighlightStyle, SharedString, StyledText,
Task, TaskLabel, TextStyle,
App, AppContext as _, BackgroundExecutor, Context, Entity, EventEmitter, HighlightStyle,
SharedString, StyledText, Task, TaskLabel, TextStyle,
};
use lsp::{LanguageServerId, NumberOrString};
@@ -832,6 +832,7 @@ impl Buffer {
ReplicaId::LOCAL,
cx.entity_id().as_non_zero_u64().into(),
base_text.into(),
&cx.background_executor(),
),
None,
Capability::ReadWrite,
@@ -862,9 +863,10 @@ impl Buffer {
replica_id: ReplicaId,
capability: Capability,
base_text: impl Into<String>,
cx: &BackgroundExecutor,
) -> Self {
Self::build(
TextBuffer::new(replica_id, remote_id, base_text.into()),
TextBuffer::new(replica_id, remote_id, base_text.into(), cx),
None,
capability,
)
@@ -877,9 +879,10 @@ impl Buffer {
capability: Capability,
message: proto::BufferState,
file: Option<Arc<dyn File>>,
cx: &BackgroundExecutor,
) -> Result<Self> {
let buffer_id = BufferId::new(message.id).context("Could not deserialize buffer_id")?;
let buffer = TextBuffer::new(replica_id, buffer_id, message.base_text);
let buffer = TextBuffer::new(replica_id, buffer_id, message.base_text, cx);
let mut this = Self::build(buffer, file, capability);
this.text.set_line_ending(proto::deserialize_line_ending(
rpc::proto::LineEnding::from_i32(message.line_ending).context("missing line_ending")?,
@@ -1138,13 +1141,14 @@ impl Buffer {
let old_snapshot = self.text.snapshot();
let mut branch_buffer = self.text.branch();
let mut syntax_snapshot = self.syntax_map.lock().snapshot();
let executor = cx.background_executor().clone();
cx.background_spawn(async move {
if !edits.is_empty() {
if let Some(language) = language.clone() {
syntax_snapshot.reparse(&old_snapshot, registry.clone(), language);
}
branch_buffer.edit(edits.iter().cloned());
branch_buffer.edit(edits.iter().cloned(), &executor);
let snapshot = branch_buffer.snapshot();
syntax_snapshot.interpolate(&snapshot);
@@ -2361,7 +2365,9 @@ impl Buffer {
let autoindent_request = autoindent_mode
.and_then(|mode| self.language.as_ref().map(|_| (self.snapshot(), mode)));
let edit_operation = self.text.edit(edits.iter().cloned());
let edit_operation = self
.text
.edit(edits.iter().cloned(), cx.background_executor());
let edit_id = edit_operation.timestamp();
if let Some((before_edit, mode)) = autoindent_request {
@@ -2592,7 +2598,8 @@ impl Buffer {
for operation in buffer_ops.iter() {
self.send_operation(Operation::Buffer(operation.clone()), false, cx);
}
self.text.apply_ops(buffer_ops);
self.text
.apply_ops(buffer_ops, Some(cx.background_executor()));
self.deferred_ops.insert(deferred_ops);
self.flush_deferred_ops(cx);
self.did_edit(&old_version, was_dirty, cx);
+29 -10
View File
@@ -75,6 +75,7 @@ fn test_set_line_ending(cx: &mut TestAppContext) {
Capability::ReadWrite,
base.read(cx).to_proto(cx),
None,
cx.background_executor(),
)
.unwrap()
});
@@ -255,14 +256,18 @@ async fn test_first_line_pattern(cx: &mut TestAppContext) {
.is_none()
);
assert!(
cx.read(|cx| languages.language_for_file(&file("the/script"), Some(&"nothing".into()), cx))
.is_none()
cx.read(|cx| languages.language_for_file(
&file("the/script"),
Some(&Rope::from_str("nothing", cx.background_executor())),
cx
))
.is_none()
);
assert_eq!(
cx.read(|cx| languages.language_for_file(
&file("the/script"),
Some(&"#!/bin/env node".into()),
Some(&Rope::from_str("#!/bin/env node", cx.background_executor())),
cx
))
.unwrap()
@@ -406,6 +411,7 @@ fn test_edit_events(cx: &mut gpui::App) {
ReplicaId::new(1),
Capability::ReadWrite,
"abcdef",
cx.background_executor(),
)
});
let buffer1_ops = Arc::new(Mutex::new(Vec::new()));
@@ -2781,8 +2787,14 @@ fn test_serialization(cx: &mut gpui::App) {
.background_executor()
.block(buffer1.read(cx).serialize_ops(None, cx));
let buffer2 = cx.new(|cx| {
let mut buffer =
Buffer::from_proto(ReplicaId::new(1), Capability::ReadWrite, state, None).unwrap();
let mut buffer = Buffer::from_proto(
ReplicaId::new(1),
Capability::ReadWrite,
state,
None,
cx.background_executor(),
)
.unwrap();
buffer.apply_ops(
ops.into_iter()
.map(|op| proto::deserialize_operation(op).unwrap()),
@@ -2806,6 +2818,7 @@ fn test_branch_and_merge(cx: &mut TestAppContext) {
Capability::ReadWrite,
base.read(cx).to_proto(cx),
None,
cx.background_executor(),
)
.unwrap()
});
@@ -3120,9 +3133,14 @@ fn test_random_collaboration(cx: &mut App, mut rng: StdRng) {
let ops = cx
.background_executor()
.block(base_buffer.read(cx).serialize_ops(None, cx));
let mut buffer =
Buffer::from_proto(ReplicaId::new(i as u16), Capability::ReadWrite, state, None)
.unwrap();
let mut buffer = Buffer::from_proto(
ReplicaId::new(i as u16),
Capability::ReadWrite,
state,
None,
cx.background_executor(),
)
.unwrap();
buffer.apply_ops(
ops.into_iter()
.map(|op| proto::deserialize_operation(op).unwrap()),
@@ -3251,6 +3269,7 @@ fn test_random_collaboration(cx: &mut App, mut rng: StdRng) {
Capability::ReadWrite,
old_buffer_state,
None,
cx.background_executor(),
)
.unwrap();
new_buffer.apply_ops(
@@ -3414,7 +3433,7 @@ fn test_contiguous_ranges() {
}
#[gpui::test(iterations = 500)]
fn test_trailing_whitespace_ranges(mut rng: StdRng) {
fn test_trailing_whitespace_ranges(mut rng: StdRng, cx: &mut TestAppContext) {
// Generate a random multi-line string containing
// some lines with trailing whitespace.
let mut text = String::new();
@@ -3438,7 +3457,7 @@ fn test_trailing_whitespace_ranges(mut rng: StdRng) {
_ => {}
}
let rope = Rope::from(text.as_str());
let rope = Rope::from_str(text.as_str(), cx.background_executor());
let actual_ranges = trailing_whitespace_ranges(&rope);
let expected_ranges = TRAILING_WHITESPACE_REGEX
.find_iter(&text)
@@ -100,6 +100,7 @@ fn test_syntax_map_layers_for_range(cx: &mut App) {
}
"#
.unindent(),
cx.background_executor(),
);
let mut syntax_map = SyntaxMap::new(&buffer);
@@ -147,7 +148,7 @@ fn test_syntax_map_layers_for_range(cx: &mut App) {
// Replace a vec! macro invocation with a plain slice, removing a syntactic layer.
let macro_name_range = range_for_text(&buffer, "vec!");
buffer.edit([(macro_name_range, "&")]);
buffer.edit([(macro_name_range, "&")], cx.background_executor());
syntax_map.interpolate(&buffer);
syntax_map.reparse(language.clone(), &buffer);
@@ -199,6 +200,7 @@ fn test_dynamic_language_injection(cx: &mut App) {
```
"#
.unindent(),
cx.background_executor(),
);
let mut syntax_map = SyntaxMap::new(&buffer);
@@ -218,7 +220,10 @@ fn test_dynamic_language_injection(cx: &mut App) {
// Replace `rs` with a path to ending in `.rb` in code block.
let macro_name_range = range_for_text(&buffer, "rs");
buffer.edit([(macro_name_range, "foo/bar/baz.rb")]);
buffer.edit(
[(macro_name_range, "foo/bar/baz.rb")],
cx.background_executor(),
);
syntax_map.interpolate(&buffer);
syntax_map.reparse(markdown.clone(), &buffer);
syntax_map.reparse(markdown_inline.clone(), &buffer);
@@ -235,7 +240,7 @@ fn test_dynamic_language_injection(cx: &mut App) {
// Replace Ruby with a language that hasn't been loaded yet.
let macro_name_range = range_for_text(&buffer, "foo/bar/baz.rb");
buffer.edit([(macro_name_range, "html")]);
buffer.edit([(macro_name_range, "html")], cx.background_executor());
syntax_map.interpolate(&buffer);
syntax_map.reparse(markdown.clone(), &buffer);
syntax_map.reparse(markdown_inline.clone(), &buffer);
@@ -811,7 +816,12 @@ fn test_syntax_map_languages_loading_with_erb(cx: &mut App) {
.unindent();
let registry = Arc::new(LanguageRegistry::test(cx.background_executor().clone()));
let mut buffer = Buffer::new(ReplicaId::LOCAL, BufferId::new(1).unwrap(), text);
let mut buffer = Buffer::new(
ReplicaId::LOCAL,
BufferId::new(1).unwrap(),
text,
cx.background_executor(),
);
let mut syntax_map = SyntaxMap::new(&buffer);
syntax_map.set_language_registry(registry.clone());
@@ -859,7 +869,7 @@ fn test_syntax_map_languages_loading_with_erb(cx: &mut App) {
.unindent();
log::info!("editing");
buffer.edit_via_marked_text(&text);
buffer.edit_via_marked_text(&text, cx.background_executor());
syntax_map.interpolate(&buffer);
syntax_map.reparse(language, &buffer);
@@ -903,7 +913,7 @@ fn test_random_syntax_map_edits_rust_macros(rng: StdRng, cx: &mut App) {
let language = Arc::new(rust_lang());
registry.add(language.clone());
test_random_edits(text, registry, language, rng);
test_random_edits(text, registry, language, rng, cx);
}
#[gpui::test(iterations = 50)]
@@ -932,7 +942,7 @@ fn test_random_syntax_map_edits_with_erb(rng: StdRng, cx: &mut App) {
registry.add(Arc::new(ruby_lang()));
registry.add(Arc::new(html_lang()));
test_random_edits(text, registry, language, rng);
test_random_edits(text, registry, language, rng, cx);
}
#[gpui::test(iterations = 50)]
@@ -965,7 +975,7 @@ fn test_random_syntax_map_edits_with_heex(rng: StdRng, cx: &mut App) {
registry.add(Arc::new(heex_lang()));
registry.add(Arc::new(html_lang()));
test_random_edits(text, registry, language, rng);
test_random_edits(text, registry, language, rng, cx);
}
fn test_random_edits(
@@ -973,12 +983,18 @@ fn test_random_edits(
registry: Arc<LanguageRegistry>,
language: Arc<Language>,
mut rng: StdRng,
cx: &mut App,
) {
let operations = env::var("OPERATIONS")
.map(|i| i.parse().expect("invalid `OPERATIONS` variable"))
.unwrap_or(10);
let mut buffer = Buffer::new(ReplicaId::LOCAL, BufferId::new(1).unwrap(), text);
let mut buffer = Buffer::new(
ReplicaId::LOCAL,
BufferId::new(1).unwrap(),
text,
cx.background_executor(),
);
let mut syntax_map = SyntaxMap::new(&buffer);
syntax_map.set_language_registry(registry.clone());
@@ -993,7 +1009,7 @@ fn test_random_edits(
let prev_buffer = buffer.snapshot();
let prev_syntax_map = syntax_map.snapshot();
buffer.randomly_edit(&mut rng, 3);
buffer.randomly_edit(&mut rng, 3, cx.background_executor());
log::info!("text:\n{}", buffer.text());
syntax_map.interpolate(&buffer);
@@ -1159,7 +1175,12 @@ fn test_edit_sequence(language_name: &str, steps: &[&str], cx: &mut App) -> (Buf
.now_or_never()
.unwrap()
.unwrap();
let mut buffer = Buffer::new(ReplicaId::LOCAL, BufferId::new(1).unwrap(), "");
let mut buffer = Buffer::new(
ReplicaId::LOCAL,
BufferId::new(1).unwrap(),
"",
cx.background_executor(),
);
let mut mutated_syntax_map = SyntaxMap::new(&buffer);
mutated_syntax_map.set_language_registry(registry.clone());
@@ -1168,7 +1189,7 @@ fn test_edit_sequence(language_name: &str, steps: &[&str], cx: &mut App) -> (Buf
for (i, marked_string) in steps.iter().enumerate() {
let marked_string = marked_string.unindent();
log::info!("incremental parse {i}: {marked_string:?}");
buffer.edit_via_marked_text(&marked_string);
buffer.edit_via_marked_text(&marked_string, cx.background_executor());
// Reparse the syntax map
mutated_syntax_map.interpolate(&buffer);