Don't reuse excerpt ids in MultiBuffer

This prevents anchors from swapping their ordering, which was causing issues in FoldMap.

Co-Authored-By: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
Nathan Sobo 2022-03-11 08:50:50 -07:00
parent 134496ce8f
commit 5407f25c94
2 changed files with 34 additions and 2 deletions

View File

@ -36,6 +36,7 @@ pub type ExcerptId = Locator;
pub struct MultiBuffer {
snapshot: RefCell<MultiBufferSnapshot>,
buffers: RefCell<HashMap<usize, BufferState>>,
used_excerpt_ids: SumTree<Locator>,
subscriptions: Topic,
singleton: bool,
replica_id: ReplicaId,
@ -155,6 +156,7 @@ impl MultiBuffer {
Self {
snapshot: Default::default(),
buffers: Default::default(),
used_excerpt_ids: Default::default(),
subscriptions: Default::default(),
singleton: false,
replica_id,
@ -192,6 +194,7 @@ impl MultiBuffer {
Self {
snapshot: RefCell::new(self.snapshot.borrow().clone()),
buffers: RefCell::new(buffers),
used_excerpt_ids: Default::default(),
subscriptions: Default::default(),
singleton: self.singleton,
replica_id: self.replica_id,
@ -759,13 +762,18 @@ impl MultiBuffer {
);
let mut next_id = ExcerptId::max();
if let Some(next_excerpt) = cursor.item() {
next_id = next_excerpt.id.clone();
{
let mut used_cursor = self.used_excerpt_ids.cursor::<Locator>();
used_cursor.seek(&prev_id, Bias::Right, &());
if let Some(used_id) = used_cursor.item() {
next_id = used_id.clone();
}
}
let mut ids = Vec::new();
while let Some(range) = ranges.next() {
let id = ExcerptId::between(&prev_id, &next_id);
self.used_excerpt_ids.insert_or_replace(id.clone(), &());
if let Err(ix) = buffer_state.excerpts.binary_search(&id) {
buffer_state.excerpts.insert(ix, id.clone());
}

View File

@ -49,6 +49,30 @@ impl Default for Locator {
}
}
impl sum_tree::Item for Locator {
type Summary = Locator;
fn summary(&self) -> Self::Summary {
self.clone()
}
}
impl sum_tree::KeyedItem for Locator {
type Key = Locator;
fn key(&self) -> Self::Key {
self.clone()
}
}
impl sum_tree::Summary for Locator {
type Context = ();
fn add_summary(&mut self, summary: &Self, _: &()) {
self.assign(summary);
}
}
#[cfg(test)]
mod tests {
use super::*;