WIP: Move sum_tree module into gpui so we can use it in List

This commit is contained in:
Nathan Sobo
2021-08-20 16:18:39 -06:00
parent 2507f9b4d4
commit c3dda14490
16 changed files with 190 additions and 138 deletions
+28 -22
View File
@@ -1,30 +1,30 @@
mod anchor;
mod operation_queue;
mod point;
pub mod rope;
mod selection;
use crate::{
language::{Language, Tree},
settings::{HighlightId, HighlightMap},
time::{self, ReplicaId},
util::Bias,
worktree::{File, Worktree},
};
pub use anchor::*;
use anyhow::{anyhow, Result};
use gpui::{
sum_tree::{self, FilterCursor, SumTree},
AppContext, Entity, ModelContext, ModelHandle, Task,
};
use lazy_static::lazy_static;
use operation_queue::OperationQueue;
use parking_lot::Mutex;
pub use point::*;
pub use rope::{Chunks, Rope, TextSummary};
use seahash::SeaHasher;
pub use selection::*;
use similar::{ChangeTag, TextDiff};
use tree_sitter::{InputEdit, Parser, QueryCursor};
use zrpc::proto;
use crate::{
language::{Language, Tree},
operation_queue::{self, OperationQueue},
settings::{HighlightId, HighlightMap},
sum_tree::{self, FilterCursor, SumTree},
time::{self, ReplicaId},
util::Bias,
worktree::{File, Worktree},
};
use anyhow::{anyhow, Result};
use gpui::{AppContext, Entity, ModelContext, ModelHandle, Task};
use lazy_static::lazy_static;
use std::{
cell::RefCell,
cmp,
@@ -37,6 +37,8 @@ use std::{
sync::Arc,
time::{Duration, Instant, SystemTime, UNIX_EPOCH},
};
use tree_sitter::{InputEdit, Parser, QueryCursor};
use zrpc::proto;
#[derive(Clone, Default)]
struct DeterministicState;
@@ -120,7 +122,7 @@ pub struct Buffer {
syntax_tree: Mutex<Option<SyntaxTree>>,
is_parsing: bool,
selections: HashMap<SelectionSetId, SelectionSet>,
deferred_ops: OperationQueue<Operation>,
deferred_ops: OperationQueue,
deferred_replicas: HashSet<ReplicaId>,
replica_id: ReplicaId,
remote_id: u64,
@@ -483,6 +485,8 @@ pub enum Operation {
set_id: Option<SelectionSetId>,
lamport_timestamp: time::Lamport,
},
#[cfg(test)]
Test(time::Lamport),
}
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -1390,6 +1394,8 @@ impl Buffer {
}
self.lamport_clock.observe(lamport_timestamp);
}
#[cfg(test)]
Operation::Test(_) => {}
}
Ok(())
}
@@ -1731,6 +1737,8 @@ impl Buffer {
Operation::SetActiveSelections { set_id, .. } => {
set_id.map_or(true, |set_id| self.selections.contains_key(&set_id))
}
#[cfg(test)]
Operation::Test(_) => true,
}
}
}
@@ -2564,6 +2572,8 @@ impl Operation {
Operation::SetActiveSelections {
lamport_timestamp, ..
} => *lamport_timestamp,
#[cfg(test)]
Operation::Test(lamport_timestamp) => *lamport_timestamp,
}
}
@@ -2630,6 +2640,8 @@ impl<'a> Into<proto::Operation> for &'a Operation {
lamport_timestamp: lamport_timestamp.value,
},
),
#[cfg(test)]
Operation::Test(_) => unimplemented!()
}),
}
}
@@ -2834,12 +2846,6 @@ impl TryFrom<proto::Selection> for Selection {
}
}
impl operation_queue::Operation for Operation {
fn timestamp(&self) -> time::Lamport {
self.lamport_timestamp()
}
}
pub trait ToOffset {
fn to_offset<'a>(&self, content: impl Into<Content<'a>>) -> usize;
}
+128
View File
@@ -0,0 +1,128 @@
use super::Operation;
use crate::time;
use gpui::sum_tree::{Cursor, Dimension, Edit, Item, KeyedItem, SumTree, Summary};
use std::{fmt::Debug, ops::Add};
#[derive(Clone, Debug)]
pub struct OperationQueue(SumTree<Operation>);
#[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
pub struct OperationKey(time::Lamport);
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct OperationSummary {
pub key: OperationKey,
pub len: usize,
}
impl OperationKey {
pub fn new(timestamp: time::Lamport) -> Self {
Self(timestamp)
}
}
impl OperationQueue {
pub fn new() -> Self {
OperationQueue(SumTree::new())
}
pub fn len(&self) -> usize {
self.0.summary().len
}
pub fn insert(&mut self, mut ops: Vec<Operation>) {
ops.sort_by_key(|op| op.lamport_timestamp());
ops.dedup_by_key(|op| op.lamport_timestamp());
self.0
.edit(ops.into_iter().map(Edit::Insert).collect(), &());
}
pub fn drain(&mut self) -> Self {
let clone = self.clone();
self.0 = SumTree::new();
clone
}
pub fn cursor(&self) -> Cursor<Operation, (), ()> {
self.0.cursor()
}
}
impl Summary for OperationSummary {
type Context = ();
fn add_summary(&mut self, other: &Self, _: &()) {
assert!(self.key < other.key);
self.key = other.key;
self.len += other.len;
}
}
impl<'a> Add<&'a Self> for OperationSummary {
type Output = Self;
fn add(self, other: &Self) -> Self {
assert!(self.key < other.key);
OperationSummary {
key: other.key,
len: self.len + other.len,
}
}
}
impl<'a> Dimension<'a, OperationSummary> for OperationKey {
fn add_summary(&mut self, summary: &OperationSummary, _: &()) {
assert!(*self <= summary.key);
*self = summary.key;
}
}
impl Item for Operation {
type Summary = OperationSummary;
fn summary(&self) -> Self::Summary {
OperationSummary {
key: OperationKey::new(self.lamport_timestamp()),
len: 1,
}
}
}
impl KeyedItem for Operation {
type Key = OperationKey;
fn key(&self) -> Self::Key {
OperationKey::new(self.lamport_timestamp())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_len() {
let mut clock = time::Lamport::new(0);
let mut queue = OperationQueue::new();
assert_eq!(queue.len(), 0);
queue.insert(vec![
Operation::Test(clock.tick()),
Operation::Test(clock.tick()),
]);
assert_eq!(queue.len(), 2);
queue.insert(vec![Operation::Test(clock.tick())]);
assert_eq!(queue.len(), 3);
drop(queue.drain());
assert_eq!(queue.len(), 0);
queue.insert(vec![Operation::Test(clock.tick())]);
assert_eq!(queue.len(), 1);
}
#[derive(Clone, Debug, Eq, PartialEq)]
struct TestOperation(time::Lamport);
}
+4 -6
View File
@@ -1,9 +1,7 @@
use super::Point;
use crate::{
sum_tree::{self, SumTree},
util::Bias,
};
use crate::util::Bias;
use arrayvec::ArrayString;
use gpui::sum_tree::{self, SumTree};
use smallvec::SmallVec;
use std::{cmp, ops::Range, str};
@@ -61,7 +59,7 @@ impl Rope {
if last_chunk.0.len() + first_new_chunk_ref.0.len() <= 2 * CHUNK_BASE {
last_chunk.0.push_str(&first_new_chunk.take().unwrap().0);
} else {
let mut text = ArrayString::<[_; 4 * CHUNK_BASE]>::new();
let mut text = ArrayString::<{ 4 * CHUNK_BASE }>::new();
text.push_str(&last_chunk.0);
text.push_str(&first_new_chunk_ref.0);
let (left, right) = text.split_at(find_split_ix(&text));
@@ -330,7 +328,7 @@ impl<'a> Iterator for Chunks<'a> {
}
#[derive(Clone, Debug, Default)]
struct Chunk(ArrayString<[u8; 2 * CHUNK_BASE]>);
struct Chunk(ArrayString<{ 2 * CHUNK_BASE }>);
impl Chunk {
fn to_point(&self, target: usize) -> Point {
+3 -6
View File
@@ -2,14 +2,11 @@ use super::{
buffer::{AnchorRangeExt, TextSummary},
Anchor, Buffer, Point, ToOffset,
};
use crate::{
editor::buffer,
settings::HighlightId,
use crate::{editor::buffer, settings::HighlightId, time, util::Bias};
use gpui::{
sum_tree::{self, Cursor, FilterCursor, SumTree},
time,
util::Bias,
AppContext, ModelHandle,
};
use gpui::{AppContext, ModelHandle};
use parking_lot::Mutex;
use std::{
cmp::{self, Ordering},
+9 -8
View File
@@ -3,14 +3,11 @@ use super::{
line_wrapper::LineWrapper,
tab_map::{self, Edit as TabEdit, Snapshot as TabSnapshot, TabPoint, TextSummary},
};
use crate::{
editor::Point,
settings::HighlightId,
use crate::{editor::Point, settings::HighlightId, util::Bias, Settings};
use gpui::{
sum_tree::{self, Cursor, SumTree},
util::Bias,
Settings,
Entity, ModelContext, Task,
};
use gpui::{Entity, ModelContext, Task};
use lazy_static::lazy_static;
use smol::future::yield_now;
use std::{collections::VecDeque, ops::Range, time::Duration};
@@ -816,8 +813,12 @@ fn push_isomorphic(transforms: &mut Vec<Transform>, summary: TextSummary) {
transforms.push(Transform::isomorphic(summary));
}
impl SumTree<Transform> {
pub fn push_or_extend(&mut self, transform: Transform) {
trait SumTreeExt {
fn push_or_extend(&mut self, transform: Transform);
}
impl SumTreeExt for SumTree<Transform> {
fn push_or_extend(&mut self, transform: Transform) {
let mut transform = Some(transform);
self.update_last(
|last_transform| {