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:
+63
-17
@@ -15,6 +15,7 @@ use anyhow::{Context as _, Result};
|
||||
use clock::Lamport;
|
||||
pub use clock::ReplicaId;
|
||||
use collections::{HashMap, HashSet};
|
||||
use gpui::BackgroundExecutor;
|
||||
use locator::Locator;
|
||||
use operation_queue::OperationQueue;
|
||||
pub use patch::Patch;
|
||||
@@ -709,11 +710,41 @@ impl FromIterator<char> for LineIndent {
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn new(replica_id: ReplicaId, remote_id: BufferId, base_text: impl Into<String>) -> Buffer {
|
||||
/// Create a new buffer from a string.
|
||||
pub fn new(
|
||||
replica_id: ReplicaId,
|
||||
remote_id: BufferId,
|
||||
base_text: impl Into<String>,
|
||||
executor: &BackgroundExecutor,
|
||||
) -> Buffer {
|
||||
let mut base_text = base_text.into();
|
||||
let line_ending = LineEnding::detect(&base_text);
|
||||
LineEnding::normalize(&mut base_text);
|
||||
Self::new_normalized(replica_id, remote_id, line_ending, Rope::from(&*base_text))
|
||||
Self::new_normalized(
|
||||
replica_id,
|
||||
remote_id,
|
||||
line_ending,
|
||||
Rope::from_str(&base_text, executor),
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new buffer from a string.
|
||||
///
|
||||
/// Unlike [`Buffer::new`], this does not construct the backing rope in parallel if it is large enough.
|
||||
pub fn new_slow(
|
||||
replica_id: ReplicaId,
|
||||
remote_id: BufferId,
|
||||
base_text: impl Into<String>,
|
||||
) -> Buffer {
|
||||
let mut base_text = base_text.into();
|
||||
let line_ending = LineEnding::detect(&base_text);
|
||||
LineEnding::normalize(&mut base_text);
|
||||
Self::new_normalized(
|
||||
replica_id,
|
||||
remote_id,
|
||||
line_ending,
|
||||
Rope::from_str_small(&base_text),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new_normalized(
|
||||
@@ -808,7 +839,7 @@ impl Buffer {
|
||||
self.history.group_interval
|
||||
}
|
||||
|
||||
pub fn edit<R, I, S, T>(&mut self, edits: R) -> Operation
|
||||
pub fn edit<R, I, S, T>(&mut self, edits: R, cx: &BackgroundExecutor) -> Operation
|
||||
where
|
||||
R: IntoIterator<IntoIter = I>,
|
||||
I: ExactSizeIterator<Item = (Range<S>, T)>,
|
||||
@@ -821,7 +852,7 @@ impl Buffer {
|
||||
|
||||
self.start_transaction();
|
||||
let timestamp = self.lamport_clock.tick();
|
||||
let operation = Operation::Edit(self.apply_local_edit(edits, timestamp));
|
||||
let operation = Operation::Edit(self.apply_local_edit(edits, timestamp, cx));
|
||||
|
||||
self.history.push(operation.clone());
|
||||
self.history.push_undo(operation.timestamp());
|
||||
@@ -834,6 +865,7 @@ impl Buffer {
|
||||
&mut self,
|
||||
edits: impl ExactSizeIterator<Item = (Range<S>, T)>,
|
||||
timestamp: clock::Lamport,
|
||||
executor: &BackgroundExecutor,
|
||||
) -> EditOperation {
|
||||
let mut edits_patch = Patch::default();
|
||||
let mut edit_op = EditOperation {
|
||||
@@ -922,7 +954,7 @@ impl Buffer {
|
||||
});
|
||||
insertion_slices.push(InsertionSlice::from_fragment(timestamp, &fragment));
|
||||
new_insertions.push(InsertionFragment::insert_new(&fragment));
|
||||
new_ropes.push_str(new_text.as_ref());
|
||||
new_ropes.push_str(new_text.as_ref(), executor);
|
||||
new_fragments.push(fragment, &None);
|
||||
insertion_offset += new_text.len();
|
||||
}
|
||||
@@ -1001,22 +1033,26 @@ impl Buffer {
|
||||
self.snapshot.line_ending = line_ending;
|
||||
}
|
||||
|
||||
pub fn apply_ops<I: IntoIterator<Item = Operation>>(&mut self, ops: I) {
|
||||
pub fn apply_ops<I: IntoIterator<Item = Operation>>(
|
||||
&mut self,
|
||||
ops: I,
|
||||
executor: Option<&BackgroundExecutor>,
|
||||
) {
|
||||
let mut deferred_ops = Vec::new();
|
||||
for op in ops {
|
||||
self.history.push(op.clone());
|
||||
if self.can_apply_op(&op) {
|
||||
self.apply_op(op);
|
||||
self.apply_op(op, executor);
|
||||
} else {
|
||||
self.deferred_replicas.insert(op.replica_id());
|
||||
deferred_ops.push(op);
|
||||
}
|
||||
}
|
||||
self.deferred_ops.insert(deferred_ops);
|
||||
self.flush_deferred_ops();
|
||||
self.flush_deferred_ops(executor);
|
||||
}
|
||||
|
||||
fn apply_op(&mut self, op: Operation) {
|
||||
fn apply_op(&mut self, op: Operation, executor: Option<&BackgroundExecutor>) {
|
||||
match op {
|
||||
Operation::Edit(edit) => {
|
||||
if !self.version.observed(edit.timestamp) {
|
||||
@@ -1025,6 +1061,7 @@ impl Buffer {
|
||||
&edit.ranges,
|
||||
&edit.new_text,
|
||||
edit.timestamp,
|
||||
executor,
|
||||
);
|
||||
self.snapshot.version.observe(edit.timestamp);
|
||||
self.lamport_clock.observe(edit.timestamp);
|
||||
@@ -1055,6 +1092,7 @@ impl Buffer {
|
||||
ranges: &[Range<FullOffset>],
|
||||
new_text: &[Arc<str>],
|
||||
timestamp: clock::Lamport,
|
||||
executor: Option<&BackgroundExecutor>,
|
||||
) {
|
||||
if ranges.is_empty() {
|
||||
return;
|
||||
@@ -1170,7 +1208,10 @@ impl Buffer {
|
||||
});
|
||||
insertion_slices.push(InsertionSlice::from_fragment(timestamp, &fragment));
|
||||
new_insertions.push(InsertionFragment::insert_new(&fragment));
|
||||
new_ropes.push_str(new_text);
|
||||
match executor {
|
||||
Some(executor) => new_ropes.push_str(new_text, executor),
|
||||
None => new_ropes.push_str_small(new_text),
|
||||
}
|
||||
new_fragments.push(fragment, &None);
|
||||
insertion_offset += new_text.len();
|
||||
}
|
||||
@@ -1348,12 +1389,12 @@ impl Buffer {
|
||||
self.subscriptions.publish_mut(&edits);
|
||||
}
|
||||
|
||||
fn flush_deferred_ops(&mut self) {
|
||||
fn flush_deferred_ops(&mut self, executor: Option<&BackgroundExecutor>) {
|
||||
self.deferred_replicas.clear();
|
||||
let mut deferred_ops = Vec::new();
|
||||
for op in self.deferred_ops.drain().iter().cloned() {
|
||||
if self.can_apply_op(&op) {
|
||||
self.apply_op(op);
|
||||
self.apply_op(op, executor);
|
||||
} else {
|
||||
self.deferred_replicas.insert(op.replica_id());
|
||||
deferred_ops.push(op);
|
||||
@@ -1711,9 +1752,9 @@ impl Buffer {
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
impl Buffer {
|
||||
#[track_caller]
|
||||
pub fn edit_via_marked_text(&mut self, marked_string: &str) {
|
||||
pub fn edit_via_marked_text(&mut self, marked_string: &str, cx: &BackgroundExecutor) {
|
||||
let edits = self.edits_for_marked_text(marked_string);
|
||||
self.edit(edits);
|
||||
self.edit(edits, cx);
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
@@ -1850,6 +1891,7 @@ impl Buffer {
|
||||
&mut self,
|
||||
rng: &mut T,
|
||||
edit_count: usize,
|
||||
executor: &BackgroundExecutor,
|
||||
) -> (Vec<(Range<usize>, Arc<str>)>, Operation)
|
||||
where
|
||||
T: rand::Rng,
|
||||
@@ -1857,7 +1899,7 @@ impl Buffer {
|
||||
let mut edits = self.get_random_edits(rng, edit_count);
|
||||
log::info!("mutating buffer {:?} with {:?}", self.replica_id, edits);
|
||||
|
||||
let op = self.edit(edits.iter().cloned());
|
||||
let op = self.edit(edits.iter().cloned(), executor);
|
||||
if let Operation::Edit(edit) = &op {
|
||||
assert_eq!(edits.len(), edit.new_text.len());
|
||||
for (edit, new_text) in edits.iter_mut().zip(&edit.new_text) {
|
||||
@@ -2692,8 +2734,12 @@ impl<'a> RopeBuilder<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn push_str(&mut self, text: &str) {
|
||||
self.new_visible.push(text);
|
||||
fn push_str(&mut self, text: &str, cx: &BackgroundExecutor) {
|
||||
self.new_visible.push(text, cx);
|
||||
}
|
||||
|
||||
fn push_str_small(&mut self, text: &str) {
|
||||
self.new_visible.push_small(text);
|
||||
}
|
||||
|
||||
fn finish(mut self) -> (Rope, Rope) {
|
||||
|
||||
Reference in New Issue
Block a user