From da7e3c8cd876e094472a5cf27465883268190f19 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 1 Jun 2021 15:28:20 +0200 Subject: [PATCH] Implement anchors using an offset + a version vector --- zed/src/editor/buffer.rs | 222 ++++++++++++++--------- zed/src/editor/buffer/anchor.rs | 13 +- zed/src/sum_tree/cursor.rs | 311 +++++++++++--------------------- zed/src/time.rs | 16 +- 4 files changed, 271 insertions(+), 291 deletions(-) diff --git a/zed/src/editor/buffer.rs b/zed/src/editor/buffer.rs index 2241b87b2f0ca4a7ce2b16897fd165dbaf62da35..533ab0cfbe3047987016de1ef404eac7082eb6b1 100644 --- a/zed/src/editor/buffer.rs +++ b/zed/src/editor/buffer.rs @@ -351,6 +351,8 @@ pub struct FragmentSummary { text: FragmentTextSummary, max_fragment_id: FragmentId, max_version: time::Global, + min_insertion_version: time::Global, + max_insertion_version: time::Global, } #[derive(Default, Clone, Debug, PartialEq, Eq)] @@ -360,7 +362,7 @@ struct FragmentTextSummary { } impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentTextSummary { - fn add_summary(&mut self, summary: &'a FragmentSummary, _: &()) { + fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option) { self.visible += summary.text.visible; self.deleted += summary.text.deleted; } @@ -502,7 +504,7 @@ impl Buffer { base_insertion.clone(), 0..0, ), - &(), + &None, ); if base_text.len() > 0 { @@ -520,7 +522,7 @@ impl Buffer { ); fragments.push( Fragment::new(base_fragment_id, base_insertion, range_in_insertion.clone()), - &(), + &None, ); } @@ -825,7 +827,7 @@ impl Buffer { } pub fn len(&self) -> usize { - self.fragments.extent::(&()) + self.fragments.extent::(&None) } pub fn line_len(&self, row: u32) -> u32 { @@ -873,7 +875,7 @@ impl Buffer { let since_2 = since.clone(); let cursor = self.fragments.filter( move |summary| summary.max_version.changed_since(&since_2), - &(), + &None, ); Edits { @@ -1191,8 +1193,11 @@ impl Buffer { let mut fragments_cursor = old_fragments.cursor::(); - let mut new_fragments = - fragments_cursor.slice(&FragmentIdRef::new(&start_fragment_id), SeekBias::Left, &()); + let mut new_fragments = fragments_cursor.slice( + &FragmentIdRef::new(&start_fragment_id), + SeekBias::Left, + &None, + ); let mut new_ropes = RopeBuilder::new(old_visible_text.cursor(0), old_deleted_text.cursor(0)); new_ropes.push_tree(new_fragments.summary().text); @@ -1201,8 +1206,8 @@ impl Buffer { if start_offset == start_fragment.range_in_insertion.end { let fragment = fragments_cursor.item().unwrap().clone(); new_ropes.push_fragment(&fragment, fragment.visible); - new_fragments.push(fragment, &()); - fragments_cursor.next(&()); + new_fragments.push(fragment, &None); + fragments_cursor.next(&None); } while let Some(fragment) = fragments_cursor.item() { @@ -1242,11 +1247,11 @@ impl Buffer { }; if let Some(fragment) = before_range { new_ropes.push_fragment(&fragment, fragment.visible); - new_fragments.push(fragment, &()); + new_fragments.push(fragment, &None); } if let Some(fragment) = insertion { new_ropes.push_str(new_text.take().unwrap()); - new_fragments.push(fragment, &()); + new_fragments.push(fragment, &None); } if let Some(mut fragment) = within_range { let fragment_was_visible = fragment.visible; @@ -1258,11 +1263,11 @@ impl Buffer { } new_ropes.push_fragment(&fragment, fragment_was_visible); - new_fragments.push(fragment, &()); + new_fragments.push(fragment, &None); } if let Some(fragment) = after_range { new_ropes.push_fragment(&fragment, fragment.visible); - new_fragments.push(fragment, &()); + new_fragments.push(fragment, &None); } } else { if new_text.is_some() && lamport_timestamp > fragment.insertion.lamport_timestamp { @@ -1275,7 +1280,7 @@ impl Buffer { lamport_timestamp, ); new_ropes.push_str(new_text); - new_fragments.push(fragment, &()); + new_fragments.push(fragment, &None); } let fragment_was_visible = fragment.visible; @@ -1289,10 +1294,10 @@ impl Buffer { } new_ropes.push_fragment(&fragment, fragment_was_visible); - new_fragments.push(fragment, &()); + new_fragments.push(fragment, &None); } - fragments_cursor.next(&()); + fragments_cursor.next(&None); } if let Some(new_text) = new_text { @@ -1304,11 +1309,11 @@ impl Buffer { lamport_timestamp, ); new_ropes.push_str(new_text); - new_fragments.push(fragment, &()); + new_fragments.push(fragment, &None); } let (visible_text, deleted_text) = new_ropes.finish(); - new_fragments.push_tree(fragments_cursor.suffix(&()), &()); + new_fragments.push_tree(fragments_cursor.suffix(&None), &None); self.fragments = new_fragments; self.visible_text = visible_text; @@ -1409,7 +1414,7 @@ impl Buffer { let first_split_id = insertion_splits.next().unwrap(); new_fragments = - fragments_cursor.slice(&FragmentIdRef::new(first_split_id), SeekBias::Left, &()); + fragments_cursor.slice(&FragmentIdRef::new(first_split_id), SeekBias::Left, &None); new_ropes.push_tree(new_fragments.summary().text); loop { @@ -1419,14 +1424,17 @@ impl Buffer { fragment.max_undos.observe(undo.id); new_ropes.push_fragment(&fragment, was_visible); - new_fragments.push(fragment.clone(), &()); + new_fragments.push(fragment.clone(), &None); - fragments_cursor.next(&()); + fragments_cursor.next(&None); if let Some(split_id) = insertion_splits.next() { - let slice = - fragments_cursor.slice(&FragmentIdRef::new(split_id), SeekBias::Left, &()); + let slice = fragments_cursor.slice( + &FragmentIdRef::new(split_id), + SeekBias::Left, + &None, + ); new_ropes.push_tree(slice.summary().text); - new_fragments.push_tree(slice, &()); + new_fragments.push_tree(slice, &None); } else { break; } @@ -1435,7 +1443,7 @@ impl Buffer { new_fragments = fragments_cursor.slice( &FragmentIdRef::new(&start_fragment_id), SeekBias::Left, - &(), + &None, ); new_ropes.push_tree(new_fragments.summary().text); @@ -1453,13 +1461,13 @@ impl Buffer { } new_ropes.push_fragment(&fragment, fragment_was_visible); - new_fragments.push(fragment, &()); - fragments_cursor.next(&()); + new_fragments.push(fragment, &None); + fragments_cursor.next(&None); } } } - new_fragments.push_tree(fragments_cursor.suffix(&()), &()); + new_fragments.push_tree(fragments_cursor.suffix(&None), &None); let (visible_text, deleted_text) = new_ropes.finish(); drop(fragments_cursor); @@ -1551,7 +1559,7 @@ impl Buffer { let mut fragments_cursor = old_fragments.cursor::(); let mut new_fragments = - fragments_cursor.slice(&cur_range.as_ref().unwrap().start, SeekBias::Right, &()); + fragments_cursor.slice(&cur_range.as_ref().unwrap().start, SeekBias::Right, &None); let mut new_ropes = RopeBuilder::new(old_visible_text.cursor(0), old_deleted_text.cursor(0)); @@ -1595,7 +1603,7 @@ impl Buffer { fragment.range_in_insertion.start = prefix.range_in_insertion.end; new_ropes.push_fragment(&prefix, prefix.visible); - new_fragments.push(prefix.clone(), &()); + new_fragments.push(prefix.clone(), &None); new_split_tree.push( InsertionSplit { extent: prefix.range_in_insertion.end - prefix.range_in_insertion.start, @@ -1628,7 +1636,7 @@ impl Buffer { ); new_ropes.push_str(&new_text); - new_fragments.push(new_fragment, &()); + new_fragments.push(new_fragment, &None); } } @@ -1639,14 +1647,14 @@ impl Buffer { prefix.range_in_insertion.start + (range.end - fragment_start); prefix.id = FragmentId::between(&new_fragments.last().unwrap().id, &fragment.id); - version_in_range.observe_all(&fragment_summary.max_version); + version_in_range.join(&fragment_summary.max_version); if prefix.visible { prefix.deletions.insert(local_timestamp); prefix.visible = false; } fragment.range_in_insertion.start = prefix.range_in_insertion.end; new_ropes.push_fragment(&prefix, fragment_was_visible); - new_fragments.push(prefix.clone(), &()); + new_fragments.push(prefix.clone(), &None); new_split_tree.push( InsertionSplit { extent: prefix.range_in_insertion.end @@ -1660,7 +1668,7 @@ impl Buffer { end_offset = Some(fragment.range_in_insertion.start); } } else { - version_in_range.observe_all(&fragment_summary.max_version); + version_in_range.join(&fragment_summary.max_version); if fragment.visible { fragment.deletions.insert(local_timestamp); fragment.visible = false; @@ -1714,10 +1722,10 @@ impl Buffer { .insert(fragment.insertion.id, new_split_tree); new_ropes.push_fragment(&fragment, fragment_was_visible); - new_fragments.push(fragment, &()); + new_fragments.push(fragment, &None); // Scan forward until we find a fragment that is not fully contained by the current splice. - fragments_cursor.next(&()); + fragments_cursor.next(&None); if let Some(range) = cur_range.clone() { while let Some(fragment) = fragments_cursor.item() { let fragment_summary = fragments_cursor.item_summary().unwrap(); @@ -1726,15 +1734,15 @@ impl Buffer { fragment_end = fragment_start + fragment.visible_len(); if range.start < fragment_start && range.end >= fragment_end { let mut new_fragment = fragment.clone(); - version_in_range.observe_all(&fragment_summary.max_version); + version_in_range.join(&fragment_summary.max_version); if new_fragment.visible { new_fragment.deletions.insert(local_timestamp); new_fragment.visible = false; } new_ropes.push_fragment(&new_fragment, fragment_was_visible); - new_fragments.push(new_fragment, &()); - fragments_cursor.next(&()); + new_fragments.push(new_fragment, &None); + fragments_cursor.next(&None); if range.end == fragment_end { end_id = Some(fragment.insertion.id); @@ -1777,10 +1785,10 @@ impl Buffer { let slice = fragments_cursor.slice( &cur_range.as_ref().unwrap().start, SeekBias::Right, - &(), + &None, ); new_ropes.push_tree(slice.summary().text); - new_fragments.push_tree(slice, &()); + new_fragments.push_tree(slice, &None); } } } @@ -1814,11 +1822,11 @@ impl Buffer { ); new_ropes.push_str(&new_text); - new_fragments.push(new_fragment, &()); + new_fragments.push(new_fragment, &None); } } - new_fragments.push_tree(fragments_cursor.suffix(&()), &()); + new_fragments.push_tree(fragments_cursor.suffix(&None), &None); let (visible_text, deleted_text) = new_ropes.finish(); self.fragments = new_fragments; @@ -1982,8 +1990,10 @@ impl Buffer { } else if offset == max_offset && bias == AnchorBias::Right { Anchor::End } else { + let mut cursor = self.fragments.cursor::(); + cursor.seek(&offset, bias.to_seek_bias(), &None); Anchor::Middle { - offset, + offset: offset + cursor.start().deleted, bias, version: self.version(), } @@ -1991,6 +2001,60 @@ impl Buffer { } fn summary_for_anchor(&self, anchor: &Anchor) -> TextSummary { + #[derive(Copy, Clone, Debug, Eq, PartialEq)] + enum VersionedOffset { + Offset(usize), + InvalidVersion, + } + + impl VersionedOffset { + fn offset(&self) -> usize { + if let Self::Offset(offset) = self { + *offset + } else { + panic!("invalid version") + } + } + } + + impl Default for VersionedOffset { + fn default() -> Self { + Self::Offset(0) + } + } + + impl<'a> sum_tree::Dimension<'a, FragmentSummary> for VersionedOffset { + fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option) { + if let Self::Offset(offset) = self { + let version = cx.as_ref().unwrap(); + if *version >= summary.max_insertion_version { + *offset += summary.text.visible + summary.text.deleted; + } else if *version < summary.min_insertion_version { + // Every insertion in this subtree is causally after the context's version. + } else { + *self = VersionedOffset::InvalidVersion; + } + } + } + } + + impl<'a> sum_tree::SeekDimension<'a, FragmentSummary> for VersionedOffset { + fn cmp(&self, other: &Self, _: &Option) -> cmp::Ordering { + match (self, other) { + (Self::Offset(a), Self::Offset(b)) => Ord::cmp(a, b), + (Self::Offset(_), Self::InvalidVersion) => cmp::Ordering::Less, + (Self::InvalidVersion, _) => unreachable!(), + } + } + } + + impl<'a> sum_tree::Dimension<'a, FragmentSummary> for (VersionedOffset, usize) { + fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option) { + self.0.add_summary(summary, cx); + self.1 += summary.text.visible; + } + } + match anchor { Anchor::Start => TextSummary::default(), Anchor::End => self.text_summary(), @@ -2001,39 +2065,20 @@ impl Buffer { } => { let mut cursor = self .fragments - .filter::<_, usize>(|summary| !(*version >= summary.max_version), &()); - - let mut old_offset = 0; - let mut new_offset = 0; - while let Some(fragment) = cursor.item() { - let bytes_since_last_fragment = *cursor.start() - new_offset; - let comparison = offset.cmp(&(old_offset + bytes_since_last_fragment)); - if comparison == cmp::Ordering::Greater - || (comparison == cmp::Ordering::Equal && *bias == AnchorBias::Right) - { - old_offset += bytes_since_last_fragment; - new_offset += bytes_since_last_fragment; - - if fragment.was_visible(version, &self.undo_map) { - let comparison = offset.cmp(&(old_offset + fragment.visible_len())); - if comparison == cmp::Ordering::Greater - || (comparison == cmp::Ordering::Equal - && *bias == AnchorBias::Right) - { - old_offset += fragment.len(); - } else { - break; - } - } - new_offset += fragment.visible_len(); - cursor.next(&()); - } else { - break; - } - } + .cursor::(); + cursor.seek( + &VersionedOffset::Offset(*offset), + bias.to_seek_bias(), + &Some(version.clone()), + ); + let fragment = cursor.item().unwrap(); + let overshoot = if fragment.visible { + offset - cursor.start().0.offset() + } else { + 0 + }; - let ix = new_offset + offset.saturating_sub(old_offset); - self.text_summary_for_range(0..ix) + self.text_summary_for_range(0..cursor.start().1 + overshoot) } } } @@ -2262,7 +2307,7 @@ impl<'a, F: Fn(&FragmentSummary) -> bool> Iterator for Edits<'a, F> { } } - self.cursor.next(&()); + self.cursor.next(&None); } change @@ -2446,7 +2491,7 @@ impl<'a> FragmentIdRef<'a> { } impl<'a> sum_tree::Dimension<'a, FragmentSummary> for FragmentIdRef<'a> { - fn add_summary(&mut self, summary: &'a FragmentSummary, _: &()) { + fn add_summary(&mut self, summary: &'a FragmentSummary, _: &Option) { self.0 = Some(&summary.max_fragment_id) } } @@ -2497,8 +2542,11 @@ impl sum_tree::Item for Fragment { for deletion in &self.deletions { max_version.observe(*deletion); } - max_version.observe_all(&self.max_undos); + max_version.join(&self.max_undos); + let mut min_insertion_version = time::Global::new(); + min_insertion_version.observe(self.insertion.id); + let max_insertion_version = min_insertion_version.clone(); if self.visible { FragmentSummary { text: FragmentTextSummary { @@ -2507,6 +2555,8 @@ impl sum_tree::Item for Fragment { }, max_fragment_id: self.id.clone(), max_version, + min_insertion_version, + max_insertion_version, } } else { FragmentSummary { @@ -2516,20 +2566,26 @@ impl sum_tree::Item for Fragment { }, max_fragment_id: self.id.clone(), max_version, + min_insertion_version, + max_insertion_version, } } } } impl sum_tree::Summary for FragmentSummary { - type Context = (); + type Context = Option; fn add_summary(&mut self, other: &Self, _: &Self::Context) { self.text.visible += &other.text.visible; self.text.deleted += &other.text.deleted; debug_assert!(self.max_fragment_id <= other.max_fragment_id); self.max_fragment_id = other.max_fragment_id.clone(); - self.max_version.observe_all(&other.max_version); + self.max_version.join(&other.max_version); + self.min_insertion_version + .meet(&other.min_insertion_version); + self.max_insertion_version + .join(&other.max_insertion_version); } } @@ -2539,12 +2595,14 @@ impl Default for FragmentSummary { text: FragmentTextSummary::default(), max_fragment_id: FragmentId::min_value().clone(), max_version: time::Global::new(), + min_insertion_version: time::Global::new(), + max_insertion_version: time::Global::new(), } } } impl<'a> sum_tree::Dimension<'a, FragmentSummary> for usize { - fn add_summary(&mut self, summary: &FragmentSummary, _: &()) { + fn add_summary(&mut self, summary: &FragmentSummary, _: &Option) { *self += summary.text.visible; } } diff --git a/zed/src/editor/buffer/anchor.rs b/zed/src/editor/buffer/anchor.rs index 607c5d4aa884e8676fc1a8fe11dda553e4b63146..eeacaf112464164f61f107f8067b9ac8330f6cb2 100644 --- a/zed/src/editor/buffer/anchor.rs +++ b/zed/src/editor/buffer/anchor.rs @@ -1,5 +1,5 @@ use super::{Buffer, ToOffset}; -use crate::time; +use crate::{sum_tree, time}; use anyhow::Result; use std::{cmp::Ordering, ops::Range}; @@ -14,12 +14,21 @@ pub enum Anchor { }, } -#[derive(Clone, Eq, PartialEq, Debug, Hash)] +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] pub enum AnchorBias { Left, Right, } +impl AnchorBias { + pub fn to_seek_bias(self) -> sum_tree::SeekBias { + match self { + AnchorBias::Left => sum_tree::SeekBias::Left, + AnchorBias::Right => sum_tree::SeekBias::Right, + } + } +} + impl PartialOrd for AnchorBias { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) diff --git a/zed/src/sum_tree/cursor.rs b/zed/src/sum_tree/cursor.rs index e5515e45c24d7286e530a0d18f0949a72309a961..7016a79c9cb285f415ce8b52b564868be7e46671 100644 --- a/zed/src/sum_tree/cursor.rs +++ b/zed/src/sum_tree/cursor.rs @@ -415,220 +415,108 @@ where D: Dimension<'a, T::Summary>, { debug_assert!(target.cmp(&self.seek_dimension, cx) >= Ordering::Equal); - let mut containing_subtree = None; - if self.did_seek { - 'outer: while let Some(entry) = self.stack.last_mut() { - { - match *entry.tree.0 { - Node::Internal { - ref child_summaries, - ref child_trees, - .. - } => { - entry.index += 1; - for (child_tree, child_summary) in child_trees[entry.index..] - .iter() - .zip(&child_summaries[entry.index..]) - { - let mut child_end = self.seek_dimension.clone(); - child_end.add_summary(&child_summary, cx); - - let comparison = target.cmp(&child_end, cx); - if comparison == Ordering::Greater - || (comparison == Ordering::Equal && bias == SeekBias::Right) - { - self.seek_dimension = child_end; - self.sum_dimension.add_summary(child_summary, cx); - match aggregate { - SeekAggregate::None => {} - SeekAggregate::Slice(slice) => { - slice.push_tree(child_tree.clone(), cx); - } - SeekAggregate::Summary(summary) => { - summary.add_summary(child_summary, cx); - } - } - entry.index += 1; - } else { - containing_subtree = Some(child_tree); - break 'outer; - } - } - } - Node::Leaf { - ref items, - ref item_summaries, - .. - } => { - let mut slice_items = ArrayVec::<[T; 2 * TREE_BASE]>::new(); - let mut slice_item_summaries = - ArrayVec::<[T::Summary; 2 * TREE_BASE]>::new(); - let mut slice_items_summary = match aggregate { - SeekAggregate::Slice(_) => Some(T::Summary::default()), - _ => None, - }; - - for (item, item_summary) in items[entry.index..] - .iter() - .zip(&item_summaries[entry.index..]) - { - let mut child_end = self.seek_dimension.clone(); - child_end.add_summary(item_summary, cx); - - let comparison = target.cmp(&child_end, cx); - if comparison == Ordering::Greater - || (comparison == Ordering::Equal && bias == SeekBias::Right) - { - self.seek_dimension = child_end; - self.sum_dimension.add_summary(item_summary, cx); - match aggregate { - SeekAggregate::None => {} - SeekAggregate::Slice(_) => { - slice_items.push(item.clone()); - slice_item_summaries.push(item_summary.clone()); - slice_items_summary - .as_mut() - .unwrap() - .add_summary(item_summary, cx); - } - SeekAggregate::Summary(summary) => { - summary.add_summary(item_summary, cx); - } - } - entry.index += 1; - } else { - if let SeekAggregate::Slice(slice) = aggregate { - slice.push_tree( - SumTree(Arc::new(Node::Leaf { - summary: slice_items_summary.unwrap(), - items: slice_items, - item_summaries: slice_item_summaries, - })), - cx, - ); - } - break 'outer; - } - } + if !self.did_seek { + self.did_seek = true; + self.stack.push(StackEntry { + tree: self.tree, + index: 0, + seek_dimension: Default::default(), + sum_dimension: Default::default(), + }); + } - if let SeekAggregate::Slice(slice) = aggregate { - if !slice_items.is_empty() { - slice.push_tree( - SumTree(Arc::new(Node::Leaf { - summary: slice_items_summary.unwrap(), - items: slice_items, - item_summaries: slice_item_summaries, - })), - cx, - ); - } - } - } + let mut ascending = false; + 'outer: while let Some(entry) = self.stack.last_mut() { + match *entry.tree.0 { + Node::Internal { + ref child_summaries, + ref child_trees, + .. + } => { + if ascending { + entry.index += 1; } - } - self.stack.pop(); - } - } else { - self.did_seek = true; - containing_subtree = Some(self.tree); - } + for (child_tree, child_summary) in child_trees[entry.index..] + .iter() + .zip(&child_summaries[entry.index..]) + { + let mut child_end = self.seek_dimension.clone(); + child_end.add_summary(&child_summary, cx); - if let Some(mut subtree) = containing_subtree { - loop { - let mut next_subtree = None; - match *subtree.0 { - Node::Internal { - ref child_summaries, - ref child_trees, - .. - } => { - for (index, (child_tree, child_summary)) in - child_trees.iter().zip(child_summaries).enumerate() + let comparison = target.cmp(&child_end, cx); + if comparison == Ordering::Greater + || (comparison == Ordering::Equal && bias == SeekBias::Right) { - let mut child_end = self.seek_dimension.clone(); - child_end.add_summary(child_summary, cx); - - let comparison = target.cmp(&child_end, cx); - if comparison == Ordering::Greater - || (comparison == Ordering::Equal && bias == SeekBias::Right) - { - self.seek_dimension = child_end; - self.sum_dimension.add_summary(child_summary, cx); - match aggregate { - SeekAggregate::None => {} - SeekAggregate::Slice(slice) => { - slice.push_tree(child_trees[index].clone(), cx); - } - SeekAggregate::Summary(summary) => { - summary.add_summary(child_summary, cx); - } + self.seek_dimension = child_end; + self.sum_dimension.add_summary(child_summary, cx); + match aggregate { + SeekAggregate::None => {} + SeekAggregate::Slice(slice) => { + slice.push_tree(child_tree.clone(), cx); + } + SeekAggregate::Summary(summary) => { + summary.add_summary(child_summary, cx); } - } else { - self.stack.push(StackEntry { - tree: subtree, - index, - seek_dimension: self.seek_dimension.clone(), - sum_dimension: self.sum_dimension.clone(), - }); - next_subtree = Some(child_tree); - break; } + entry.index += 1; + entry.seek_dimension = self.seek_dimension.clone(); + entry.sum_dimension = self.sum_dimension.clone(); + } else { + self.stack.push(StackEntry { + tree: child_tree, + index: 0, + seek_dimension: self.seek_dimension.clone(), + sum_dimension: self.sum_dimension.clone(), + }); + ascending = false; + continue 'outer; } } - Node::Leaf { - ref items, - ref item_summaries, - .. - } => { - let mut slice_items = ArrayVec::<[T; 2 * TREE_BASE]>::new(); - let mut slice_item_summaries = - ArrayVec::<[T::Summary; 2 * TREE_BASE]>::new(); - let mut slice_items_summary = match aggregate { - SeekAggregate::Slice(_) => Some(T::Summary::default()), - _ => None, - }; - - for (index, (item, item_summary)) in - items.iter().zip(item_summaries).enumerate() + } + Node::Leaf { + ref items, + ref item_summaries, + .. + } => { + let mut slice_items = ArrayVec::<[T; 2 * TREE_BASE]>::new(); + let mut slice_item_summaries = ArrayVec::<[T::Summary; 2 * TREE_BASE]>::new(); + let mut slice_items_summary = match aggregate { + SeekAggregate::Slice(_) => Some(T::Summary::default()), + _ => None, + }; + + for (item, item_summary) in items[entry.index..] + .iter() + .zip(&item_summaries[entry.index..]) + { + let mut child_end = self.seek_dimension.clone(); + child_end.add_summary(item_summary, cx); + + let comparison = target.cmp(&child_end, cx); + if comparison == Ordering::Greater + || (comparison == Ordering::Equal && bias == SeekBias::Right) { - let mut child_end = self.seek_dimension.clone(); - child_end.add_summary(item_summary, cx); - - let comparison = target.cmp(&child_end, cx); - if comparison == Ordering::Greater - || (comparison == Ordering::Equal && bias == SeekBias::Right) - { - self.seek_dimension = child_end; - self.sum_dimension.add_summary(item_summary, cx); - match aggregate { - SeekAggregate::None => {} - SeekAggregate::Slice(_) => { - slice_items.push(item.clone()); - slice_items_summary - .as_mut() - .unwrap() - .add_summary(item_summary, cx); - slice_item_summaries.push(item_summary.clone()); - } - SeekAggregate::Summary(summary) => { - summary.add_summary(item_summary, cx); - } + self.seek_dimension = child_end; + self.sum_dimension.add_summary(item_summary, cx); + match aggregate { + SeekAggregate::None => {} + SeekAggregate::Slice(_) => { + slice_items.push(item.clone()); + slice_item_summaries.push(item_summary.clone()); + slice_items_summary + .as_mut() + .unwrap() + .add_summary(item_summary, cx); + } + SeekAggregate::Summary(summary) => { + summary.add_summary(item_summary, cx); } - } else { - self.stack.push(StackEntry { - tree: subtree, - index, - seek_dimension: self.seek_dimension.clone(), - sum_dimension: self.sum_dimension.clone(), - }); - break; } - } - - if let SeekAggregate::Slice(slice) = aggregate { - if !slice_items.is_empty() { + entry.index += 1; + } else { + if let SeekAggregate::Slice(slice) = aggregate { slice.push_tree( SumTree(Arc::new(Node::Leaf { summary: slice_items_summary.unwrap(), @@ -638,16 +526,27 @@ where cx, ); } + break 'outer; } } - }; - if let Some(next_subtree) = next_subtree { - subtree = next_subtree; - } else { - break; + if let SeekAggregate::Slice(slice) = aggregate { + if !slice_items.is_empty() { + slice.push_tree( + SumTree(Arc::new(Node::Leaf { + summary: slice_items_summary.unwrap(), + items: slice_items, + item_summaries: slice_item_summaries, + })), + cx, + ); + } + } } } + + self.stack.pop(); + ascending = true; } self.at_end = self.stack.is_empty(); diff --git a/zed/src/time.rs b/zed/src/time.rs index 8668ebfe9cfaed30a66dca3a22aec8ba18e01891..fdcc58b1fb66a72eb4b928e46f75ed5046ab83c3 100644 --- a/zed/src/time.rs +++ b/zed/src/time.rs @@ -81,12 +81,26 @@ impl Global { } } - pub fn observe_all(&mut self, other: &Self) { + pub fn join(&mut self, other: &Self) { for timestamp in other.0.iter() { self.observe(*timestamp); } } + pub fn meet(&mut self, other: &Self) { + for timestamp in other.0.iter() { + if let Some(entry) = self + .0 + .iter_mut() + .find(|t| t.replica_id == timestamp.replica_id) + { + entry.value = cmp::min(entry.value, timestamp.value); + } else { + self.0.push(*timestamp); + } + } + } + pub fn observed(&self, timestamp: Local) -> bool { self.get(timestamp.replica_id) >= timestamp.value }