sum_tree: Reduce Cursor size for contextless summary types (#38776)

This reduces the size of cursor by a usize when the summary does not
require a context making Cursor usages and constructions slightly more
efficient.

This change is a bit annoying though, as Rust has no means of
specializing, so this uses a `ContextlessSummary` trait with a blanket
impl while turning the `Context` into a GAT `Context<'a>`. This means
`Summary` implies are a bit more verbose now while contextless ones are
slimmer. It does come with the downside that the lifetime in the GAT is
always considered invariant, so some lifetime splitting occurred due to
that.


 ```
push/4096               time:   [352.65 µs 360.87 µs 367.80 µs]
                        thrpt:  [10.621 MiB/s 10.825 MiB/s 11.077 MiB/s]
                 change:
time: [-2.6633% -1.3640% -0.0561%] (p = 0.05 < 0.05)
                        thrpt:  [+0.0561% +1.3828% +2.7361%]
                        Change within noise threshold.
Found 16 outliers among 100 measurements (16.00%)
  7 (7.00%) low severe
  3 (3.00%) low mild
  2 (2.00%) high mild
  4 (4.00%) high severe
push/65536              time:   [1.2917 ms 1.2949 ms 1.2979 ms]
                        thrpt:  [48.156 MiB/s 48.267 MiB/s 48.387 MiB/s]
                 change:
time: [+1.4428% +1.9844% +2.5299%] (p = 0.00 < 0.05)
                        thrpt:  [-2.4675% -1.9458% -1.4223%]
                        Performance has regressed.
Found 3 outliers among 100 measurements (3.00%)
  1 (1.00%) low severe
  1 (1.00%) low mild
  1 (1.00%) high severe

append/4096             time:   [677.87 ns 678.87 ns 679.83 ns]
                        thrpt:  [5.6112 GiB/s 5.6192 GiB/s 5.6274 GiB/s]
                 change:
time: [-0.8924% -0.5017% -0.1705%] (p = 0.00 < 0.05)
                        thrpt:  [+0.1708% +0.5043% +0.9004%]
                        Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) low mild
  1 (1.00%) high mild
append/65536            time:   [9.3275 µs 9.3406 µs 9.3536 µs]
                        thrpt:  [6.5253 GiB/s 6.5344 GiB/s 6.5435 GiB/s]
                 change:
time: [+0.5409% +0.7215% +0.9054%] (p = 0.00 < 0.05)
                        thrpt:  [-0.8973% -0.7163% -0.5380%]
                        Change within noise threshold.

slice/4096              time:   [27.673 µs 27.791 µs 27.907 µs]
                        thrpt:  [139.97 MiB/s 140.56 MiB/s 141.16 MiB/s]
                 change:
time: [-1.1065% -0.6725% -0.2429%] (p = 0.00 < 0.05)
                        thrpt:  [+0.2435% +0.6770% +1.1189%]
                        Change within noise threshold.
Found 5 outliers among 100 measurements (5.00%)
  4 (4.00%) low mild
  1 (1.00%) high mild
slice/65536             time:   [507.55 µs 517.40 µs 535.60 µs]
                        thrpt:  [116.69 MiB/s 120.80 MiB/s 123.14 MiB/s]
                 change:
time: [-1.3489% +0.0599% +2.2591%] (p = 0.96 > 0.05)
                        thrpt:  [-2.2092% -0.0598% +1.3674%]
                        No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
  5 (5.00%) low mild
  2 (2.00%) high mild
  1 (1.00%) high severe

bytes_in_range/4096     time:   [3.3917 µs 3.4108 µs 3.4313 µs]
                        thrpt:  [1.1117 GiB/s 1.1184 GiB/s 1.1247 GiB/s]
                 change:
time: [-5.3466% -4.7193% -4.1262%] (p = 0.00 < 0.05)
                        thrpt:  [+4.3038% +4.9531% +5.6487%]
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  1 (1.00%) low mild
  5 (5.00%) high mild
bytes_in_range/65536    time:   [88.175 µs 88.613 µs 89.111 µs]
                        thrpt:  [701.37 MiB/s 705.31 MiB/s 708.82 MiB/s]
                 change:
time: [-0.6935% +0.3769% +1.4655%] (p = 0.50 > 0.05)
                        thrpt:  [-1.4443% -0.3755% +0.6984%]
                        No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
  2 (2.00%) high mild

chars/4096              time:   [678.70 ns 680.38 ns 682.08 ns]
                        thrpt:  [5.5927 GiB/s 5.6067 GiB/s 5.6206 GiB/s]
                 change:
time: [-0.6969% -0.2755% +0.1485%] (p = 0.20 > 0.05)
                        thrpt:  [-0.1483% +0.2763% +0.7018%]
                        No change in performance detected.
Found 9 outliers among 100 measurements (9.00%)
  5 (5.00%) low mild
  4 (4.00%) high mild
chars/65536             time:   [12.720 µs 12.775 µs 12.830 µs]
                        thrpt:  [4.7573 GiB/s 4.7778 GiB/s 4.7983 GiB/s]
                 change:
time: [-0.6172% -0.1110% +0.4179%] (p = 0.68 > 0.05)
                        thrpt:  [-0.4162% +0.1112% +0.6211%]
                        No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) low mild
  1 (1.00%) high mild

clip_point/4096         time:   [33.240 µs 33.310 µs 33.394 µs]
                        thrpt:  [116.98 MiB/s 117.27 MiB/s 117.52 MiB/s]
                 change:
time: [-2.8892% -2.6305% -2.3438%] (p = 0.00 < 0.05)
                        thrpt:  [+2.4000% +2.7015% +2.9751%]
                        Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
  1 (1.00%) low mild
  4 (4.00%) high mild
  7 (7.00%) high severe
clip_point/65536        time:   [1.6531 ms 1.6586 ms 1.6640 ms]
                        thrpt:  [37.560 MiB/s 37.683 MiB/s 37.808 MiB/s]
                 change:
time: [-6.6381% -5.9395% -5.2680%] (p = 0.00 < 0.05)
                        thrpt:  [+5.5610% +6.3146% +7.1100%]
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  1 (1.00%) low mild
  2 (2.00%) high mild
  4 (4.00%) high severe

point_to_offset/4096    time:   [11.586 µs 11.603 µs 11.621 µs]
                        thrpt:  [336.15 MiB/s 336.67 MiB/s 337.16 MiB/s]
                 change:
time: [-14.289% -14.111% -13.939%] (p = 0.00 < 0.05)
                        thrpt:  [+16.197% +16.429% +16.672%]
                        Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
  3 (3.00%) low severe
  5 (5.00%) low mild
  4 (4.00%) high mild
point_to_offset/65536   time:   [527.74 µs 532.08 µs 536.51 µs]
                        thrpt:  [116.49 MiB/s 117.46 MiB/s 118.43 MiB/s]
                 change:
time: [-6.7825% -4.6235% -2.3533%] (p = 0.00 < 0.05)
                        thrpt:  [+2.4100% +4.8477% +7.2760%]
                        Performance has improved.
Found 8 outliers among 100 measurements (8.00%)
  4 (4.00%) high mild
  4 (4.00%) high severe

cursor/4096             time:   [16.154 µs 16.192 µs 16.232 µs]
                        thrpt:  [240.66 MiB/s 241.24 MiB/s 241.81 MiB/s]
                 change:
time: [-3.2536% -2.9145% -2.5526%] (p = 0.00 < 0.05)
                        thrpt:  [+2.6194% +3.0019% +3.3630%]
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  1 (1.00%) low mild
  2 (2.00%) high mild
  2 (2.00%) high severe
cursor/65536            time:   [509.60 µs 511.24 µs 512.93 µs]
                        thrpt:  [121.85 MiB/s 122.25 MiB/s 122.65 MiB/s]
                 change:
time: [-7.3677% -6.6017% -5.7840%] (p = 0.00 < 0.05)
                        thrpt:  [+6.1391% +7.0683% +7.9537%]
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  3 (3.00%) high mild
  3 (3.00%) high severe
```
Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Lukas Wirth
2025-09-24 14:35:38 +02:00
committed by GitHub
parent c5219e8fd2
commit e1b57f00a0
26 changed files with 811 additions and 785 deletions
+3 -3
View File
@@ -111,13 +111,13 @@ impl sum_tree::Item for PendingHunk {
} }
impl sum_tree::Summary for DiffHunkSummary { impl sum_tree::Summary for DiffHunkSummary {
type Context = text::BufferSnapshot; type Context<'a> = &'a text::BufferSnapshot;
fn zero(_cx: &Self::Context) -> Self { fn zero(_cx: Self::Context<'_>) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { fn add_summary(&mut self, other: &Self, buffer: Self::Context<'_>) {
self.buffer_range.start = self self.buffer_range.start = self
.buffer_range .buffer_range
.start .start
+34 -36
View File
@@ -22,7 +22,7 @@ use std::{
atomic::{AtomicUsize, Ordering::SeqCst}, atomic::{AtomicUsize, Ordering::SeqCst},
}, },
}; };
use sum_tree::{Bias, Dimensions, SumTree, Summary, TreeMap}; use sum_tree::{Bias, ContextLessSummary, Dimensions, SumTree, TreeMap};
use text::{BufferId, Edit}; use text::{BufferId, Edit};
use ui::ElementId; use ui::ElementId;
@@ -433,7 +433,7 @@ struct TransformSummary {
} }
pub struct BlockChunks<'a> { pub struct BlockChunks<'a> {
transforms: sum_tree::Cursor<'a, Transform, Dimensions<BlockRow, WrapRow>>, transforms: sum_tree::Cursor<'a, 'static, Transform, Dimensions<BlockRow, WrapRow>>,
input_chunks: wrap_map::WrapChunks<'a>, input_chunks: wrap_map::WrapChunks<'a>,
input_chunk: Chunk<'a>, input_chunk: Chunk<'a>,
output_row: u32, output_row: u32,
@@ -443,7 +443,7 @@ pub struct BlockChunks<'a> {
#[derive(Clone)] #[derive(Clone)]
pub struct BlockRows<'a> { pub struct BlockRows<'a> {
transforms: sum_tree::Cursor<'a, Transform, Dimensions<BlockRow, WrapRow>>, transforms: sum_tree::Cursor<'a, 'static, Transform, Dimensions<BlockRow, WrapRow>>,
input_rows: wrap_map::WrapRows<'a>, input_rows: wrap_map::WrapRows<'a>,
output_row: BlockRow, output_row: BlockRow,
started: bool, started: bool,
@@ -527,7 +527,7 @@ impl BlockMap {
let mut transforms = self.transforms.borrow_mut(); let mut transforms = self.transforms.borrow_mut();
let mut new_transforms = SumTree::default(); let mut new_transforms = SumTree::default();
let mut cursor = transforms.cursor::<WrapRow>(&()); let mut cursor = transforms.cursor::<WrapRow>(());
let mut last_block_ix = 0; let mut last_block_ix = 0;
let mut blocks_in_edit = Vec::new(); let mut blocks_in_edit = Vec::new();
let mut edits = edits.into_iter().peekable(); let mut edits = edits.into_iter().peekable();
@@ -541,20 +541,20 @@ impl BlockMap {
// * Isomorphic transforms that end *at* the start of the edit // * Isomorphic transforms that end *at* the start of the edit
// * Below blocks that end at the start of the edit // * Below blocks that end at the start of the edit
// However, if we hit a replace block that ends at the start of the edit we want to reconstruct it. // However, if we hit a replace block that ends at the start of the edit we want to reconstruct it.
new_transforms.append(cursor.slice(&old_start, Bias::Left), &()); new_transforms.append(cursor.slice(&old_start, Bias::Left), ());
if let Some(transform) = cursor.item() if let Some(transform) = cursor.item()
&& transform.summary.input_rows > 0 && transform.summary.input_rows > 0
&& cursor.end() == old_start && cursor.end() == old_start
&& transform.block.as_ref().is_none_or(|b| !b.is_replacement()) && transform.block.as_ref().is_none_or(|b| !b.is_replacement())
{ {
// Preserve the transform (push and next) // Preserve the transform (push and next)
new_transforms.push(transform.clone(), &()); new_transforms.push(transform.clone(), ());
cursor.next(); cursor.next();
// Preserve below blocks at end of edit // Preserve below blocks at end of edit
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
if transform.block.as_ref().is_some_and(|b| b.place_below()) { if transform.block.as_ref().is_some_and(|b| b.place_below()) {
new_transforms.push(transform.clone(), &()); new_transforms.push(transform.clone(), ());
cursor.next(); cursor.next();
} else { } else {
break; break;
@@ -720,7 +720,7 @@ impl BlockMap {
summary, summary,
block: Some(block), block: Some(block),
}, },
&(), (),
); );
} }
@@ -731,7 +731,7 @@ impl BlockMap {
push_isomorphic(&mut new_transforms, rows_after_last_block, wrap_snapshot); push_isomorphic(&mut new_transforms, rows_after_last_block, wrap_snapshot);
} }
new_transforms.append(cursor.suffix(), &()); new_transforms.append(cursor.suffix(), ());
debug_assert_eq!( debug_assert_eq!(
new_transforms.summary().input_rows, new_transforms.summary().input_rows,
wrap_snapshot.max_point().row() + 1 wrap_snapshot.max_point().row() + 1
@@ -925,11 +925,11 @@ fn push_isomorphic(tree: &mut SumTree<Transform>, rows: u32, wrap_snapshot: &Wra
tree.update_last( tree.update_last(
|last_transform| { |last_transform| {
if last_transform.block.is_none() { if last_transform.block.is_none() {
last_transform.summary.add_summary(&summary, &()); last_transform.summary.add_summary(&summary);
merged = true; merged = true;
} }
}, },
&(), (),
); );
if !merged { if !merged {
tree.push( tree.push(
@@ -937,7 +937,7 @@ fn push_isomorphic(tree: &mut SumTree<Transform>, rows: u32, wrap_snapshot: &Wra
summary, summary,
block: None, block: None,
}, },
&(), (),
); );
} }
} }
@@ -997,7 +997,7 @@ impl BlockMapReader<'_> {
.unwrap_or(self.wrap_snapshot.max_point().row() + 1), .unwrap_or(self.wrap_snapshot.max_point().row() + 1),
); );
let mut cursor = self.transforms.cursor::<Dimensions<WrapRow, BlockRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<WrapRow, BlockRow>>(());
cursor.seek(&start_wrap_row, Bias::Left); cursor.seek(&start_wrap_row, Bias::Left);
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
if cursor.start().0 > end_wrap_row { if cursor.start().0 > end_wrap_row {
@@ -1313,7 +1313,7 @@ impl BlockSnapshot {
) -> BlockChunks<'a> { ) -> BlockChunks<'a> {
let max_output_row = cmp::min(rows.end, self.transforms.summary().output_rows); let max_output_row = cmp::min(rows.end, self.transforms.summary().output_rows);
let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(());
cursor.seek(&BlockRow(rows.start), Bias::Right); cursor.seek(&BlockRow(rows.start), Bias::Right);
let transform_output_start = cursor.start().0.0; let transform_output_start = cursor.start().0.0;
let transform_input_start = cursor.start().1.0; let transform_input_start = cursor.start().1.0;
@@ -1345,7 +1345,7 @@ impl BlockSnapshot {
} }
pub(super) fn row_infos(&self, start_row: BlockRow) -> BlockRows<'_> { pub(super) fn row_infos(&self, start_row: BlockRow) -> BlockRows<'_> {
let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(());
cursor.seek(&start_row, Bias::Right); cursor.seek(&start_row, Bias::Right);
let Dimensions(output_start, input_start, _) = cursor.start(); let Dimensions(output_start, input_start, _) = cursor.start();
let overshoot = if cursor let overshoot = if cursor
@@ -1366,7 +1366,7 @@ impl BlockSnapshot {
} }
pub fn blocks_in_range(&self, rows: Range<u32>) -> impl Iterator<Item = (u32, &Block)> { pub fn blocks_in_range(&self, rows: Range<u32>) -> impl Iterator<Item = (u32, &Block)> {
let mut cursor = self.transforms.cursor::<BlockRow>(&()); let mut cursor = self.transforms.cursor::<BlockRow>(());
cursor.seek(&BlockRow(rows.start), Bias::Left); cursor.seek(&BlockRow(rows.start), Bias::Left);
while cursor.start().0 < rows.start && cursor.end().0 <= rows.start { while cursor.start().0 < rows.start && cursor.end().0 <= rows.start {
cursor.next(); cursor.next();
@@ -1397,7 +1397,7 @@ impl BlockSnapshot {
pub fn sticky_header_excerpt(&self, position: f32) -> Option<StickyHeaderExcerpt<'_>> { pub fn sticky_header_excerpt(&self, position: f32) -> Option<StickyHeaderExcerpt<'_>> {
let top_row = position as u32; let top_row = position as u32;
let mut cursor = self.transforms.cursor::<BlockRow>(&()); let mut cursor = self.transforms.cursor::<BlockRow>(());
cursor.seek(&BlockRow(top_row), Bias::Right); cursor.seek(&BlockRow(top_row), Bias::Right);
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
@@ -1436,7 +1436,7 @@ impl BlockSnapshot {
}; };
let wrap_row = WrapRow(wrap_point.row()); let wrap_row = WrapRow(wrap_point.row());
let mut cursor = self.transforms.cursor::<WrapRow>(&()); let mut cursor = self.transforms.cursor::<WrapRow>(());
cursor.seek(&wrap_row, Bias::Left); cursor.seek(&wrap_row, Bias::Left);
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
@@ -1464,7 +1464,7 @@ impl BlockSnapshot {
} }
pub fn longest_row_in_range(&self, range: Range<BlockRow>) -> BlockRow { pub fn longest_row_in_range(&self, range: Range<BlockRow>) -> BlockRow {
let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(());
cursor.seek(&range.start, Bias::Right); cursor.seek(&range.start, Bias::Right);
let mut longest_row = range.start; let mut longest_row = range.start;
@@ -1515,7 +1515,7 @@ impl BlockSnapshot {
} }
pub(super) fn line_len(&self, row: BlockRow) -> u32 { pub(super) fn line_len(&self, row: BlockRow) -> u32 {
let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(());
cursor.seek(&BlockRow(row.0), Bias::Right); cursor.seek(&BlockRow(row.0), Bias::Right);
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
let Dimensions(output_start, input_start, _) = cursor.start(); let Dimensions(output_start, input_start, _) = cursor.start();
@@ -1533,13 +1533,13 @@ impl BlockSnapshot {
} }
pub(super) fn is_block_line(&self, row: BlockRow) -> bool { pub(super) fn is_block_line(&self, row: BlockRow) -> bool {
let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(());
cursor.seek(&row, Bias::Right); cursor.seek(&row, Bias::Right);
cursor.item().is_some_and(|t| t.block.is_some()) cursor.item().is_some_and(|t| t.block.is_some())
} }
pub(super) fn is_folded_buffer_header(&self, row: BlockRow) -> bool { pub(super) fn is_folded_buffer_header(&self, row: BlockRow) -> bool {
let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(());
cursor.seek(&row, Bias::Right); cursor.seek(&row, Bias::Right);
let Some(transform) = cursor.item() else { let Some(transform) = cursor.item() else {
return false; return false;
@@ -1551,7 +1551,7 @@ impl BlockSnapshot {
let wrap_point = self let wrap_point = self
.wrap_snapshot .wrap_snapshot
.make_wrap_point(Point::new(row.0, 0), Bias::Left); .make_wrap_point(Point::new(row.0, 0), Bias::Left);
let mut cursor = self.transforms.cursor::<Dimensions<WrapRow, BlockRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<WrapRow, BlockRow>>(());
cursor.seek(&WrapRow(wrap_point.row()), Bias::Right); cursor.seek(&WrapRow(wrap_point.row()), Bias::Right);
cursor.item().is_some_and(|transform| { cursor.item().is_some_and(|transform| {
transform transform
@@ -1562,7 +1562,7 @@ impl BlockSnapshot {
} }
pub fn clip_point(&self, point: BlockPoint, bias: Bias) -> BlockPoint { pub fn clip_point(&self, point: BlockPoint, bias: Bias) -> BlockPoint {
let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(());
cursor.seek(&BlockRow(point.row), Bias::Right); cursor.seek(&BlockRow(point.row), Bias::Right);
let max_input_row = WrapRow(self.transforms.summary().input_rows); let max_input_row = WrapRow(self.transforms.summary().input_rows);
@@ -1621,7 +1621,7 @@ impl BlockSnapshot {
} }
pub fn to_block_point(&self, wrap_point: WrapPoint) -> BlockPoint { pub fn to_block_point(&self, wrap_point: WrapPoint) -> BlockPoint {
let mut cursor = self.transforms.cursor::<Dimensions<WrapRow, BlockRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<WrapRow, BlockRow>>(());
cursor.seek(&WrapRow(wrap_point.row()), Bias::Right); cursor.seek(&WrapRow(wrap_point.row()), Bias::Right);
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
if transform.block.is_some() { if transform.block.is_some() {
@@ -1639,7 +1639,7 @@ impl BlockSnapshot {
} }
pub fn to_wrap_point(&self, block_point: BlockPoint, bias: Bias) -> WrapPoint { pub fn to_wrap_point(&self, block_point: BlockPoint, bias: Bias) -> WrapPoint {
let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<BlockRow, WrapRow>>(());
cursor.seek(&BlockRow(block_point.row), Bias::Right); cursor.seek(&BlockRow(block_point.row), Bias::Right);
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
match transform.block.as_ref() { match transform.block.as_ref() {
@@ -1848,19 +1848,17 @@ impl Iterator for BlockRows<'_> {
impl sum_tree::Item for Transform { impl sum_tree::Item for Transform {
type Summary = TransformSummary; type Summary = TransformSummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
self.summary.clone() self.summary.clone()
} }
} }
impl sum_tree::Summary for TransformSummary { impl sum_tree::ContextLessSummary for TransformSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self) {
if summary.longest_row_chars > self.longest_row_chars { if summary.longest_row_chars > self.longest_row_chars {
self.longest_row = self.output_rows + summary.longest_row; self.longest_row = self.output_rows + summary.longest_row;
self.longest_row_chars = summary.longest_row_chars; self.longest_row_chars = summary.longest_row_chars;
@@ -1871,21 +1869,21 @@ impl sum_tree::Summary for TransformSummary {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for WrapRow { impl<'a> sum_tree::Dimension<'a, TransformSummary> for WrapRow {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += summary.input_rows; self.0 += summary.input_rows;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for BlockRow { impl<'a> sum_tree::Dimension<'a, TransformSummary> for BlockRow {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += summary.output_rows; self.0 += summary.output_rows;
} }
} }
+2 -2
View File
@@ -365,9 +365,9 @@ impl Default for ItemSummary {
} }
impl sum_tree::Summary for ItemSummary { impl sum_tree::Summary for ItemSummary {
type Context = MultiBufferSnapshot; type Context<'a> = &'a MultiBufferSnapshot;
fn zero(_cx: &Self::Context) -> Self { fn zero(_cx: Self::Context<'_>) -> Self {
Default::default() Default::default()
} }
+41 -43
View File
@@ -100,7 +100,7 @@ impl FoldPoint {
pub fn to_inlay_point(self, snapshot: &FoldSnapshot) -> InlayPoint { pub fn to_inlay_point(self, snapshot: &FoldSnapshot) -> InlayPoint {
let mut cursor = snapshot let mut cursor = snapshot
.transforms .transforms
.cursor::<Dimensions<FoldPoint, InlayPoint>>(&()); .cursor::<Dimensions<FoldPoint, InlayPoint>>(());
cursor.seek(&self, Bias::Right); cursor.seek(&self, Bias::Right);
let overshoot = self.0 - cursor.start().0.0; let overshoot = self.0 - cursor.start().0.0;
InlayPoint(cursor.start().1.0 + overshoot) InlayPoint(cursor.start().1.0 + overshoot)
@@ -109,7 +109,7 @@ impl FoldPoint {
pub fn to_offset(self, snapshot: &FoldSnapshot) -> FoldOffset { pub fn to_offset(self, snapshot: &FoldSnapshot) -> FoldOffset {
let mut cursor = snapshot let mut cursor = snapshot
.transforms .transforms
.cursor::<Dimensions<FoldPoint, TransformSummary>>(&()); .cursor::<Dimensions<FoldPoint, TransformSummary>>(());
cursor.seek(&self, Bias::Right); cursor.seek(&self, Bias::Right);
let overshoot = self.0 - cursor.start().1.output.lines; let overshoot = self.0 - cursor.start().1.output.lines;
let mut offset = cursor.start().1.output.len; let mut offset = cursor.start().1.output.len;
@@ -126,11 +126,11 @@ impl FoldPoint {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldPoint { impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldPoint {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += &summary.output.lines; self.0 += &summary.output.lines;
} }
} }
@@ -338,9 +338,9 @@ impl FoldMap {
}, },
placeholder: None, placeholder: None,
}, },
&(), (),
), ),
inlay_snapshot: inlay_snapshot.clone(), inlay_snapshot: inlay_snapshot,
version: 0, version: 0,
fold_metadata_by_id: TreeMap::default(), fold_metadata_by_id: TreeMap::default(),
}, },
@@ -382,7 +382,7 @@ impl FoldMap {
if !transform.is_fold() && prev_transform_isomorphic { if !transform.is_fold() && prev_transform_isomorphic {
panic!( panic!(
"found adjacent isomorphic transforms: {:?}", "found adjacent isomorphic transforms: {:?}",
self.snapshot.transforms.items(&()) self.snapshot.transforms.items(())
); );
} }
prev_transform_isomorphic = !transform.is_fold(); prev_transform_isomorphic = !transform.is_fold();
@@ -413,7 +413,7 @@ impl FoldMap {
let mut inlay_edits_iter = inlay_edits.iter().cloned().peekable(); let mut inlay_edits_iter = inlay_edits.iter().cloned().peekable();
let mut new_transforms = SumTree::<Transform>::default(); let mut new_transforms = SumTree::<Transform>::default();
let mut cursor = self.snapshot.transforms.cursor::<InlayOffset>(&()); let mut cursor = self.snapshot.transforms.cursor::<InlayOffset>(());
cursor.seek(&InlayOffset(0), Bias::Right); cursor.seek(&InlayOffset(0), Bias::Right);
while let Some(mut edit) = inlay_edits_iter.next() { while let Some(mut edit) = inlay_edits_iter.next() {
@@ -423,14 +423,14 @@ impl FoldMap {
new_transforms.update_last( new_transforms.update_last(
|transform| { |transform| {
if !transform.is_fold() { if !transform.is_fold() {
transform.summary.add_summary(&item.summary, &()); transform.summary.add_summary(&item.summary, ());
cursor.next(); cursor.next();
} }
}, },
&(), (),
); );
} }
new_transforms.append(cursor.slice(&edit.old.start, Bias::Left), &()); new_transforms.append(cursor.slice(&edit.old.start, Bias::Left), ());
edit.new.start -= edit.old.start - *cursor.start(); edit.new.start -= edit.old.start - *cursor.start();
edit.old.start = *cursor.start(); edit.old.start = *cursor.start();
@@ -544,7 +544,7 @@ impl FoldMap {
}, },
}), }),
}, },
&(), (),
); );
} }
} }
@@ -557,7 +557,7 @@ impl FoldMap {
} }
} }
new_transforms.append(cursor.suffix(), &()); new_transforms.append(cursor.suffix(), ());
if new_transforms.is_empty() { if new_transforms.is_empty() {
let text_summary = inlay_snapshot.text_summary(); let text_summary = inlay_snapshot.text_summary();
push_isomorphic(&mut new_transforms, text_summary); push_isomorphic(&mut new_transforms, text_summary);
@@ -570,9 +570,9 @@ impl FoldMap {
let mut old_transforms = self let mut old_transforms = self
.snapshot .snapshot
.transforms .transforms
.cursor::<Dimensions<InlayOffset, FoldOffset>>(&()); .cursor::<Dimensions<InlayOffset, FoldOffset>>(());
let mut new_transforms = let mut new_transforms =
new_transforms.cursor::<Dimensions<InlayOffset, FoldOffset>>(&()); new_transforms.cursor::<Dimensions<InlayOffset, FoldOffset>>(());
for mut edit in inlay_edits { for mut edit in inlay_edits {
old_transforms.seek(&edit.old.start, Bias::Left); old_transforms.seek(&edit.old.start, Bias::Left);
@@ -657,7 +657,7 @@ impl FoldSnapshot {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<FoldPoint, InlayPoint>>(&()); .cursor::<Dimensions<FoldPoint, InlayPoint>>(());
cursor.seek(&range.start, Bias::Right); cursor.seek(&range.start, Bias::Right);
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
let start_in_transform = range.start.0 - cursor.start().0.0; let start_in_transform = range.start.0 - cursor.start().0.0;
@@ -708,7 +708,7 @@ impl FoldSnapshot {
pub fn to_fold_point(&self, point: InlayPoint, bias: Bias) -> FoldPoint { pub fn to_fold_point(&self, point: InlayPoint, bias: Bias) -> FoldPoint {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<InlayPoint, FoldPoint>>(&()); .cursor::<Dimensions<InlayPoint, FoldPoint>>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
if cursor.item().is_some_and(|t| t.is_fold()) { if cursor.item().is_some_and(|t| t.is_fold()) {
if bias == Bias::Left || point == cursor.start().0 { if bias == Bias::Left || point == cursor.start().0 {
@@ -744,7 +744,7 @@ impl FoldSnapshot {
let fold_point = FoldPoint::new(start_row, 0); let fold_point = FoldPoint::new(start_row, 0);
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<FoldPoint, InlayPoint>>(&()); .cursor::<Dimensions<FoldPoint, InlayPoint>>(());
cursor.seek(&fold_point, Bias::Left); cursor.seek(&fold_point, Bias::Left);
let overshoot = fold_point.0 - cursor.start().0.0; let overshoot = fold_point.0 - cursor.start().0.0;
@@ -787,7 +787,7 @@ impl FoldSnapshot {
{ {
let buffer_offset = offset.to_offset(&self.inlay_snapshot.buffer); let buffer_offset = offset.to_offset(&self.inlay_snapshot.buffer);
let inlay_offset = self.inlay_snapshot.to_inlay_offset(buffer_offset); let inlay_offset = self.inlay_snapshot.to_inlay_offset(buffer_offset);
let mut cursor = self.transforms.cursor::<InlayOffset>(&()); let mut cursor = self.transforms.cursor::<InlayOffset>(());
cursor.seek(&inlay_offset, Bias::Right); cursor.seek(&inlay_offset, Bias::Right);
cursor.item().is_some_and(|t| t.placeholder.is_some()) cursor.item().is_some_and(|t| t.placeholder.is_some())
} }
@@ -796,7 +796,7 @@ impl FoldSnapshot {
let mut inlay_point = self let mut inlay_point = self
.inlay_snapshot .inlay_snapshot
.to_inlay_point(Point::new(buffer_row.0, 0)); .to_inlay_point(Point::new(buffer_row.0, 0));
let mut cursor = self.transforms.cursor::<InlayPoint>(&()); let mut cursor = self.transforms.cursor::<InlayPoint>(());
cursor.seek(&inlay_point, Bias::Right); cursor.seek(&inlay_point, Bias::Right);
loop { loop {
match cursor.item() { match cursor.item() {
@@ -828,7 +828,7 @@ impl FoldSnapshot {
) -> FoldChunks<'a> { ) -> FoldChunks<'a> {
let mut transform_cursor = self let mut transform_cursor = self
.transforms .transforms
.cursor::<Dimensions<FoldOffset, InlayOffset>>(&()); .cursor::<Dimensions<FoldOffset, InlayOffset>>(());
transform_cursor.seek(&range.start, Bias::Right); transform_cursor.seek(&range.start, Bias::Right);
let inlay_start = { let inlay_start = {
@@ -893,7 +893,7 @@ impl FoldSnapshot {
pub fn clip_point(&self, point: FoldPoint, bias: Bias) -> FoldPoint { pub fn clip_point(&self, point: FoldPoint, bias: Bias) -> FoldPoint {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<FoldPoint, InlayPoint>>(&()); .cursor::<Dimensions<FoldPoint, InlayPoint>>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
let transform_start = cursor.start().0.0; let transform_start = cursor.start().0.0;
@@ -925,7 +925,7 @@ fn push_isomorphic(transforms: &mut SumTree<Transform>, summary: TextSummary) {
did_merge = true; did_merge = true;
} }
}, },
&(), (),
); );
if !did_merge { if !did_merge {
transforms.push( transforms.push(
@@ -936,7 +936,7 @@ fn push_isomorphic(transforms: &mut SumTree<Transform>, summary: TextSummary) {
}, },
placeholder: None, placeholder: None,
}, },
&(), (),
) )
} }
} }
@@ -946,7 +946,7 @@ fn intersecting_folds<'a>(
folds: &'a SumTree<Fold>, folds: &'a SumTree<Fold>,
range: Range<usize>, range: Range<usize>,
inclusive: bool, inclusive: bool,
) -> FilterCursor<'a, impl 'a + FnMut(&FoldSummary) -> bool, Fold, usize> { ) -> FilterCursor<'a, 'a, impl 'a + FnMut(&FoldSummary) -> bool, Fold, usize> {
let buffer = &inlay_snapshot.buffer; let buffer = &inlay_snapshot.buffer;
let start = buffer.anchor_before(range.start.to_offset(buffer)); let start = buffer.anchor_before(range.start.to_offset(buffer));
let end = buffer.anchor_after(range.end.to_offset(buffer)); let end = buffer.anchor_after(range.end.to_offset(buffer));
@@ -1062,19 +1062,17 @@ struct TransformSummary {
impl sum_tree::Item for Transform { impl sum_tree::Item for Transform {
type Summary = TransformSummary; type Summary = TransformSummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
self.summary.clone() self.summary.clone()
} }
} }
impl sum_tree::Summary for TransformSummary { impl sum_tree::ContextLessSummary for TransformSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self) {
self.input += &other.input; self.input += &other.input;
self.output += &other.output; self.output += &other.output;
} }
@@ -1161,13 +1159,13 @@ impl Default for FoldSummary {
} }
impl sum_tree::Summary for FoldSummary { impl sum_tree::Summary for FoldSummary {
type Context = MultiBufferSnapshot; type Context<'a> = &'a MultiBufferSnapshot;
fn zero(_cx: &MultiBufferSnapshot) -> Self { fn zero(_cx: &MultiBufferSnapshot) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { fn add_summary(&mut self, other: &Self, buffer: Self::Context<'_>) {
if other.min_start.cmp(&self.min_start, buffer) == Ordering::Less { if other.min_start.cmp(&self.min_start, buffer) == Ordering::Less {
self.min_start = other.min_start; self.min_start = other.min_start;
} }
@@ -1219,7 +1217,7 @@ impl<'a> sum_tree::Dimension<'a, FoldSummary> for usize {
#[derive(Clone)] #[derive(Clone)]
pub struct FoldRows<'a> { pub struct FoldRows<'a> {
cursor: Cursor<'a, Transform, Dimensions<FoldPoint, InlayPoint>>, cursor: Cursor<'a, 'static, Transform, Dimensions<FoldPoint, InlayPoint>>,
input_rows: InlayBufferRows<'a>, input_rows: InlayBufferRows<'a>,
fold_point: FoldPoint, fold_point: FoldPoint,
} }
@@ -1340,7 +1338,7 @@ impl DerefMut for ChunkRendererContext<'_, '_> {
} }
pub struct FoldChunks<'a> { pub struct FoldChunks<'a> {
transform_cursor: Cursor<'a, Transform, Dimensions<FoldOffset, InlayOffset>>, transform_cursor: Cursor<'a, 'static, Transform, Dimensions<FoldOffset, InlayOffset>>,
inlay_chunks: InlayChunks<'a>, inlay_chunks: InlayChunks<'a>,
inlay_chunk: Option<(InlayOffset, InlayChunk<'a>)>, inlay_chunk: Option<(InlayOffset, InlayChunk<'a>)>,
inlay_offset: InlayOffset, inlay_offset: InlayOffset,
@@ -1488,7 +1486,7 @@ impl FoldOffset {
pub fn to_point(self, snapshot: &FoldSnapshot) -> FoldPoint { pub fn to_point(self, snapshot: &FoldSnapshot) -> FoldPoint {
let mut cursor = snapshot let mut cursor = snapshot
.transforms .transforms
.cursor::<Dimensions<FoldOffset, TransformSummary>>(&()); .cursor::<Dimensions<FoldOffset, TransformSummary>>(());
cursor.seek(&self, Bias::Right); cursor.seek(&self, Bias::Right);
let overshoot = if cursor.item().is_none_or(|t| t.is_fold()) { let overshoot = if cursor.item().is_none_or(|t| t.is_fold()) {
Point::new(0, (self.0 - cursor.start().0.0) as u32) Point::new(0, (self.0 - cursor.start().0.0) as u32)
@@ -1504,7 +1502,7 @@ impl FoldOffset {
pub fn to_inlay_offset(self, snapshot: &FoldSnapshot) -> InlayOffset { pub fn to_inlay_offset(self, snapshot: &FoldSnapshot) -> InlayOffset {
let mut cursor = snapshot let mut cursor = snapshot
.transforms .transforms
.cursor::<Dimensions<FoldOffset, InlayOffset>>(&()); .cursor::<Dimensions<FoldOffset, InlayOffset>>(());
cursor.seek(&self, Bias::Right); cursor.seek(&self, Bias::Right);
let overshoot = self.0 - cursor.start().0.0; let overshoot = self.0 - cursor.start().0.0;
InlayOffset(cursor.start().1.0 + overshoot) InlayOffset(cursor.start().1.0 + overshoot)
@@ -1534,31 +1532,31 @@ impl Sub for FoldOffset {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldOffset { impl<'a> sum_tree::Dimension<'a, TransformSummary> for FoldOffset {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += &summary.output.len; self.0 += &summary.output.len;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayPoint { impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayPoint {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += &summary.input.lines; self.0 += &summary.input.lines;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset { impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += &summary.input.len; self.0 += &summary.input.len;
} }
} }
+32 -42
View File
@@ -108,7 +108,7 @@ impl Inlay {
impl sum_tree::Item for Transform { impl sum_tree::Item for Transform {
type Summary = TransformSummary; type Summary = TransformSummary;
fn summary(&self, _: &()) -> Self::Summary { fn summary(&self, _: ()) -> Self::Summary {
match self { match self {
Transform::Isomorphic(summary) => TransformSummary { Transform::Isomorphic(summary) => TransformSummary {
input: *summary, input: *summary,
@@ -128,14 +128,12 @@ struct TransformSummary {
output: TextSummary, output: TextSummary,
} }
impl sum_tree::Summary for TransformSummary { impl sum_tree::ContextLessSummary for TransformSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self) {
self.input += &other.input; self.input += &other.input;
self.output += &other.output; self.output += &other.output;
} }
@@ -175,11 +173,11 @@ impl SubAssign for InlayOffset {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset { impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayOffset {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += &summary.output.len; self.0 += &summary.output.len;
} }
} }
@@ -204,45 +202,45 @@ impl Sub for InlayPoint {
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayPoint { impl<'a> sum_tree::Dimension<'a, TransformSummary> for InlayPoint {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += &summary.output.lines; self.0 += &summary.output.lines;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize { impl<'a> sum_tree::Dimension<'a, TransformSummary> for usize {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
*self += &summary.input.len; *self += &summary.input.len;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point { impl<'a> sum_tree::Dimension<'a, TransformSummary> for Point {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
*self += &summary.input.lines; *self += &summary.input.lines;
} }
} }
#[derive(Clone)] #[derive(Clone)]
pub struct InlayBufferRows<'a> { pub struct InlayBufferRows<'a> {
transforms: Cursor<'a, Transform, Dimensions<InlayPoint, Point>>, transforms: Cursor<'a, 'static, Transform, Dimensions<InlayPoint, Point>>,
buffer_rows: MultiBufferRows<'a>, buffer_rows: MultiBufferRows<'a>,
inlay_row: u32, inlay_row: u32,
max_buffer_row: MultiBufferRow, max_buffer_row: MultiBufferRow,
} }
pub struct InlayChunks<'a> { pub struct InlayChunks<'a> {
transforms: Cursor<'a, Transform, Dimensions<InlayOffset, usize>>, transforms: Cursor<'a, 'static, Transform, Dimensions<InlayOffset, usize>>,
buffer_chunks: CustomHighlightsChunks<'a>, buffer_chunks: CustomHighlightsChunks<'a>,
buffer_chunk: Option<Chunk<'a>>, buffer_chunk: Option<Chunk<'a>>,
inlay_chunks: Option<text::ChunkWithBitmaps<'a>>, inlay_chunks: Option<text::ChunkWithBitmaps<'a>>,
@@ -542,7 +540,7 @@ impl InlayMap {
let version = 0; let version = 0;
let snapshot = InlaySnapshot { let snapshot = InlaySnapshot {
buffer: buffer.clone(), buffer: buffer.clone(),
transforms: SumTree::from_iter(Some(Transform::Isomorphic(buffer.text_summary())), &()), transforms: SumTree::from_iter(Some(Transform::Isomorphic(buffer.text_summary())), ()),
version, version,
}; };
@@ -589,10 +587,10 @@ impl InlayMap {
let mut new_transforms = SumTree::default(); let mut new_transforms = SumTree::default();
let mut cursor = snapshot let mut cursor = snapshot
.transforms .transforms
.cursor::<Dimensions<usize, InlayOffset>>(&()); .cursor::<Dimensions<usize, InlayOffset>>(());
let mut buffer_edits_iter = buffer_edits.iter().peekable(); let mut buffer_edits_iter = buffer_edits.iter().peekable();
while let Some(buffer_edit) = buffer_edits_iter.next() { while let Some(buffer_edit) = buffer_edits_iter.next() {
new_transforms.append(cursor.slice(&buffer_edit.old.start, Bias::Left), &()); new_transforms.append(cursor.slice(&buffer_edit.old.start, Bias::Left), ());
if let Some(Transform::Isomorphic(transform)) = cursor.item() if let Some(Transform::Isomorphic(transform)) = cursor.item()
&& cursor.end().0 == buffer_edit.old.start && cursor.end().0 == buffer_edit.old.start
{ {
@@ -642,7 +640,7 @@ impl InlayMap {
buffer_snapshot.text_summary_for_range(prefix_start..prefix_end), buffer_snapshot.text_summary_for_range(prefix_start..prefix_end),
); );
new_transforms.push(Transform::Inlay(inlay.clone()), &()); new_transforms.push(Transform::Inlay(inlay.clone()), ());
} }
// Apply the rest of the edit. // Apply the rest of the edit.
@@ -674,9 +672,9 @@ impl InlayMap {
} }
} }
new_transforms.append(cursor.suffix(), &()); new_transforms.append(cursor.suffix(), ());
if new_transforms.is_empty() { if new_transforms.is_empty() {
new_transforms.push(Transform::Isomorphic(Default::default()), &()); new_transforms.push(Transform::Isomorphic(Default::default()), ());
} }
drop(cursor); drop(cursor);
@@ -812,7 +810,7 @@ impl InlaySnapshot {
pub fn to_point(&self, offset: InlayOffset) -> InlayPoint { pub fn to_point(&self, offset: InlayOffset) -> InlayPoint {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<InlayOffset, InlayPoint, usize>>(&()); .cursor::<Dimensions<InlayOffset, InlayPoint, usize>>(());
cursor.seek(&offset, Bias::Right); cursor.seek(&offset, Bias::Right);
let overshoot = offset.0 - cursor.start().0.0; let overshoot = offset.0 - cursor.start().0.0;
match cursor.item() { match cursor.item() {
@@ -842,7 +840,7 @@ impl InlaySnapshot {
pub fn to_offset(&self, point: InlayPoint) -> InlayOffset { pub fn to_offset(&self, point: InlayPoint) -> InlayOffset {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<InlayPoint, InlayOffset, Point>>(&()); .cursor::<Dimensions<InlayPoint, InlayOffset, Point>>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
let overshoot = point.0 - cursor.start().0.0; let overshoot = point.0 - cursor.start().0.0;
match cursor.item() { match cursor.item() {
@@ -861,7 +859,7 @@ impl InlaySnapshot {
} }
} }
pub fn to_buffer_point(&self, point: InlayPoint) -> Point { pub fn to_buffer_point(&self, point: InlayPoint) -> Point {
let mut cursor = self.transforms.cursor::<Dimensions<InlayPoint, Point>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<InlayPoint, Point>>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
match cursor.item() { match cursor.item() {
Some(Transform::Isomorphic(_)) => { Some(Transform::Isomorphic(_)) => {
@@ -873,9 +871,7 @@ impl InlaySnapshot {
} }
} }
pub fn to_buffer_offset(&self, offset: InlayOffset) -> usize { pub fn to_buffer_offset(&self, offset: InlayOffset) -> usize {
let mut cursor = self let mut cursor = self.transforms.cursor::<Dimensions<InlayOffset, usize>>(());
.transforms
.cursor::<Dimensions<InlayOffset, usize>>(&());
cursor.seek(&offset, Bias::Right); cursor.seek(&offset, Bias::Right);
match cursor.item() { match cursor.item() {
Some(Transform::Isomorphic(_)) => { Some(Transform::Isomorphic(_)) => {
@@ -888,9 +884,7 @@ impl InlaySnapshot {
} }
pub fn to_inlay_offset(&self, offset: usize) -> InlayOffset { pub fn to_inlay_offset(&self, offset: usize) -> InlayOffset {
let mut cursor = self let mut cursor = self.transforms.cursor::<Dimensions<usize, InlayOffset>>(());
.transforms
.cursor::<Dimensions<usize, InlayOffset>>(&());
cursor.seek(&offset, Bias::Left); cursor.seek(&offset, Bias::Left);
loop { loop {
match cursor.item() { match cursor.item() {
@@ -923,7 +917,7 @@ impl InlaySnapshot {
} }
} }
pub fn to_inlay_point(&self, point: Point) -> InlayPoint { pub fn to_inlay_point(&self, point: Point) -> InlayPoint {
let mut cursor = self.transforms.cursor::<Dimensions<Point, InlayPoint>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<Point, InlayPoint>>(());
cursor.seek(&point, Bias::Left); cursor.seek(&point, Bias::Left);
loop { loop {
match cursor.item() { match cursor.item() {
@@ -957,7 +951,7 @@ impl InlaySnapshot {
} }
pub fn clip_point(&self, mut point: InlayPoint, mut bias: Bias) -> InlayPoint { pub fn clip_point(&self, mut point: InlayPoint, mut bias: Bias) -> InlayPoint {
let mut cursor = self.transforms.cursor::<Dimensions<InlayPoint, Point>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<InlayPoint, Point>>(());
cursor.seek(&point, Bias::Left); cursor.seek(&point, Bias::Left);
loop { loop {
match cursor.item() { match cursor.item() {
@@ -1054,9 +1048,7 @@ impl InlaySnapshot {
pub fn text_summary_for_range(&self, range: Range<InlayOffset>) -> TextSummary { pub fn text_summary_for_range(&self, range: Range<InlayOffset>) -> TextSummary {
let mut summary = TextSummary::default(); let mut summary = TextSummary::default();
let mut cursor = self let mut cursor = self.transforms.cursor::<Dimensions<InlayOffset, usize>>(());
.transforms
.cursor::<Dimensions<InlayOffset, usize>>(&());
cursor.seek(&range.start, Bias::Right); cursor.seek(&range.start, Bias::Right);
let overshoot = range.start.0 - cursor.start().0.0; let overshoot = range.start.0 - cursor.start().0.0;
@@ -1104,7 +1096,7 @@ impl InlaySnapshot {
} }
pub fn row_infos(&self, row: u32) -> InlayBufferRows<'_> { pub fn row_infos(&self, row: u32) -> InlayBufferRows<'_> {
let mut cursor = self.transforms.cursor::<Dimensions<InlayPoint, Point>>(&()); let mut cursor = self.transforms.cursor::<Dimensions<InlayPoint, Point>>(());
let inlay_point = InlayPoint::new(row, 0); let inlay_point = InlayPoint::new(row, 0);
cursor.seek(&inlay_point, Bias::Left); cursor.seek(&inlay_point, Bias::Left);
@@ -1146,9 +1138,7 @@ impl InlaySnapshot {
language_aware: bool, language_aware: bool,
highlights: Highlights<'a>, highlights: Highlights<'a>,
) -> InlayChunks<'a> { ) -> InlayChunks<'a> {
let mut cursor = self let mut cursor = self.transforms.cursor::<Dimensions<InlayOffset, usize>>(());
.transforms
.cursor::<Dimensions<InlayOffset, usize>>(&());
cursor.seek(&range.start, Bias::Right); cursor.seek(&range.start, Bias::Right);
let buffer_range = self.to_buffer_offset(range.start)..self.to_buffer_offset(range.end); let buffer_range = self.to_buffer_offset(range.start)..self.to_buffer_offset(range.end);
@@ -1212,11 +1202,11 @@ fn push_isomorphic(sum_tree: &mut SumTree<Transform>, summary: TextSummary) {
*transform += summary.take().unwrap(); *transform += summary.take().unwrap();
} }
}, },
&(), (),
); );
if let Some(summary) = summary { if let Some(summary) = summary {
sum_tree.push(Transform::Isomorphic(summary), &()); sum_tree.push(Transform::Isomorphic(summary), ());
} }
} }
+36 -38
View File
@@ -55,7 +55,7 @@ pub struct WrapChunks<'a> {
input_chunk: Chunk<'a>, input_chunk: Chunk<'a>,
output_position: WrapPoint, output_position: WrapPoint,
max_output_row: u32, max_output_row: u32,
transforms: Cursor<'a, Transform, Dimensions<WrapPoint, TabPoint>>, transforms: Cursor<'a, 'static, Transform, Dimensions<WrapPoint, TabPoint>>,
snapshot: &'a WrapSnapshot, snapshot: &'a WrapSnapshot,
} }
@@ -66,7 +66,7 @@ pub struct WrapRows<'a> {
output_row: u32, output_row: u32,
soft_wrapped: bool, soft_wrapped: bool,
max_output_row: u32, max_output_row: u32,
transforms: Cursor<'a, Transform, Dimensions<WrapPoint, TabPoint>>, transforms: Cursor<'a, 'static, Transform, Dimensions<WrapPoint, TabPoint>>,
} }
impl WrapRows<'_> { impl WrapRows<'_> {
@@ -221,7 +221,7 @@ impl WrapMap {
if !summary.lines.is_zero() { if !summary.lines.is_zero() {
self.snapshot self.snapshot
.transforms .transforms
.push(Transform::isomorphic(summary), &()); .push(Transform::isomorphic(summary), ());
} }
let new_rows = self.snapshot.transforms.summary().output.lines.row + 1; let new_rows = self.snapshot.transforms.summary().output.lines.row + 1;
self.snapshot.interpolated = false; self.snapshot.interpolated = false;
@@ -318,7 +318,7 @@ impl WrapSnapshot {
let mut transforms = SumTree::default(); let mut transforms = SumTree::default();
let extent = tab_snapshot.text_summary(); let extent = tab_snapshot.text_summary();
if !extent.lines.is_zero() { if !extent.lines.is_zero() {
transforms.push(Transform::isomorphic(extent), &()); transforms.push(Transform::isomorphic(extent), ());
} }
Self { Self {
transforms, transforms,
@@ -336,7 +336,7 @@ impl WrapSnapshot {
if tab_edits.is_empty() { if tab_edits.is_empty() {
new_transforms = self.transforms.clone(); new_transforms = self.transforms.clone();
} else { } else {
let mut old_cursor = self.transforms.cursor::<TabPoint>(&()); let mut old_cursor = self.transforms.cursor::<TabPoint>(());
let mut tab_edits_iter = tab_edits.iter().peekable(); let mut tab_edits_iter = tab_edits.iter().peekable();
new_transforms = new_transforms =
@@ -368,7 +368,7 @@ impl WrapSnapshot {
old_cursor.next(); old_cursor.next();
new_transforms new_transforms
.append(old_cursor.slice(&next_edit.old.start, Bias::Right), &()); .append(old_cursor.slice(&next_edit.old.start, Bias::Right), ());
} }
} else { } else {
if old_cursor.end() > edit.old.end { if old_cursor.end() > edit.old.end {
@@ -378,7 +378,7 @@ impl WrapSnapshot {
new_transforms.push_or_extend(Transform::isomorphic(summary)); new_transforms.push_or_extend(Transform::isomorphic(summary));
} }
old_cursor.next(); old_cursor.next();
new_transforms.append(old_cursor.suffix(), &()); new_transforms.append(old_cursor.suffix(), ());
} }
} }
} }
@@ -434,7 +434,7 @@ impl WrapSnapshot {
new_transforms = self.transforms.clone(); new_transforms = self.transforms.clone();
} else { } else {
let mut row_edits = row_edits.into_iter().peekable(); let mut row_edits = row_edits.into_iter().peekable();
let mut old_cursor = self.transforms.cursor::<TabPoint>(&()); let mut old_cursor = self.transforms.cursor::<TabPoint>(());
new_transforms = old_cursor.slice( new_transforms = old_cursor.slice(
&TabPoint::new(row_edits.peek().unwrap().old_rows.start, 0), &TabPoint::new(row_edits.peek().unwrap().old_rows.start, 0),
@@ -511,7 +511,7 @@ impl WrapSnapshot {
if let Some(transform) = edit_transforms.next() { if let Some(transform) = edit_transforms.next() {
new_transforms.push_or_extend(transform); new_transforms.push_or_extend(transform);
} }
new_transforms.extend(edit_transforms, &()); new_transforms.extend(edit_transforms, ());
old_cursor.seek_forward(&TabPoint::new(edit.old_rows.end, 0), Bias::Right); old_cursor.seek_forward(&TabPoint::new(edit.old_rows.end, 0), Bias::Right);
if let Some(next_edit) = row_edits.peek() { if let Some(next_edit) = row_edits.peek() {
@@ -526,7 +526,7 @@ impl WrapSnapshot {
new_transforms.append( new_transforms.append(
old_cursor old_cursor
.slice(&TabPoint::new(next_edit.old_rows.start, 0), Bias::Right), .slice(&TabPoint::new(next_edit.old_rows.start, 0), Bias::Right),
&(), (),
); );
} }
} else { } else {
@@ -537,7 +537,7 @@ impl WrapSnapshot {
new_transforms.push_or_extend(Transform::isomorphic(summary)); new_transforms.push_or_extend(Transform::isomorphic(summary));
} }
old_cursor.next(); old_cursor.next();
new_transforms.append(old_cursor.suffix(), &()); new_transforms.append(old_cursor.suffix(), ());
} }
} }
} }
@@ -556,8 +556,8 @@ impl WrapSnapshot {
fn compute_edits(&self, tab_edits: &[TabEdit], new_snapshot: &WrapSnapshot) -> Patch<u32> { fn compute_edits(&self, tab_edits: &[TabEdit], new_snapshot: &WrapSnapshot) -> Patch<u32> {
let mut wrap_edits = Vec::with_capacity(tab_edits.len()); let mut wrap_edits = Vec::with_capacity(tab_edits.len());
let mut old_cursor = self.transforms.cursor::<TransformSummary>(&()); let mut old_cursor = self.transforms.cursor::<TransformSummary>(());
let mut new_cursor = new_snapshot.transforms.cursor::<TransformSummary>(&()); let mut new_cursor = new_snapshot.transforms.cursor::<TransformSummary>(());
for mut tab_edit in tab_edits.iter().cloned() { for mut tab_edit in tab_edits.iter().cloned() {
tab_edit.old.start.0.column = 0; tab_edit.old.start.0.column = 0;
tab_edit.old.end.0 += Point::new(1, 0); tab_edit.old.end.0 += Point::new(1, 0);
@@ -600,7 +600,7 @@ impl WrapSnapshot {
let output_end = WrapPoint::new(rows.end, 0); let output_end = WrapPoint::new(rows.end, 0);
let mut transforms = self let mut transforms = self
.transforms .transforms
.cursor::<Dimensions<WrapPoint, TabPoint>>(&()); .cursor::<Dimensions<WrapPoint, TabPoint>>(());
transforms.seek(&output_start, Bias::Right); transforms.seek(&output_start, Bias::Right);
let mut input_start = TabPoint(transforms.start().1.0); let mut input_start = TabPoint(transforms.start().1.0);
if transforms.item().is_some_and(|t| t.is_isomorphic()) { if transforms.item().is_some_and(|t| t.is_isomorphic()) {
@@ -630,7 +630,7 @@ impl WrapSnapshot {
pub fn line_len(&self, row: u32) -> u32 { pub fn line_len(&self, row: u32) -> u32 {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<WrapPoint, TabPoint>>(&()); .cursor::<Dimensions<WrapPoint, TabPoint>>(());
cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Left); cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Left);
if cursor if cursor
.item() .item()
@@ -657,7 +657,7 @@ impl WrapSnapshot {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<WrapPoint, TabPoint>>(&()); .cursor::<Dimensions<WrapPoint, TabPoint>>(());
cursor.seek(&start, Bias::Right); cursor.seek(&start, Bias::Right);
if let Some(transform) = cursor.item() { if let Some(transform) = cursor.item() {
let start_in_transform = start.0 - cursor.start().0.0; let start_in_transform = start.0 - cursor.start().0.0;
@@ -711,7 +711,7 @@ impl WrapSnapshot {
} }
pub fn soft_wrap_indent(&self, row: u32) -> Option<u32> { pub fn soft_wrap_indent(&self, row: u32) -> Option<u32> {
let mut cursor = self.transforms.cursor::<WrapPoint>(&()); let mut cursor = self.transforms.cursor::<WrapPoint>(());
cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Right); cursor.seek(&WrapPoint::new(row + 1, 0), Bias::Right);
cursor.item().and_then(|transform| { cursor.item().and_then(|transform| {
if transform.is_isomorphic() { if transform.is_isomorphic() {
@@ -729,7 +729,7 @@ impl WrapSnapshot {
pub fn row_infos(&self, start_row: u32) -> WrapRows<'_> { pub fn row_infos(&self, start_row: u32) -> WrapRows<'_> {
let mut transforms = self let mut transforms = self
.transforms .transforms
.cursor::<Dimensions<WrapPoint, TabPoint>>(&()); .cursor::<Dimensions<WrapPoint, TabPoint>>(());
transforms.seek(&WrapPoint::new(start_row, 0), Bias::Left); transforms.seek(&WrapPoint::new(start_row, 0), Bias::Left);
let mut input_row = transforms.start().1.row(); let mut input_row = transforms.start().1.row();
if transforms.item().is_some_and(|t| t.is_isomorphic()) { if transforms.item().is_some_and(|t| t.is_isomorphic()) {
@@ -751,7 +751,7 @@ impl WrapSnapshot {
pub fn to_tab_point(&self, point: WrapPoint) -> TabPoint { pub fn to_tab_point(&self, point: WrapPoint) -> TabPoint {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<WrapPoint, TabPoint>>(&()); .cursor::<Dimensions<WrapPoint, TabPoint>>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
let mut tab_point = cursor.start().1.0; let mut tab_point = cursor.start().1.0;
if cursor.item().is_some_and(|t| t.is_isomorphic()) { if cursor.item().is_some_and(|t| t.is_isomorphic()) {
@@ -771,14 +771,14 @@ impl WrapSnapshot {
pub fn tab_point_to_wrap_point(&self, point: TabPoint) -> WrapPoint { pub fn tab_point_to_wrap_point(&self, point: TabPoint) -> WrapPoint {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<TabPoint, WrapPoint>>(&()); .cursor::<Dimensions<TabPoint, WrapPoint>>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
WrapPoint(cursor.start().1.0 + (point.0 - cursor.start().0.0)) WrapPoint(cursor.start().1.0 + (point.0 - cursor.start().0.0))
} }
pub fn clip_point(&self, mut point: WrapPoint, bias: Bias) -> WrapPoint { pub fn clip_point(&self, mut point: WrapPoint, bias: Bias) -> WrapPoint {
if bias == Bias::Left { if bias == Bias::Left {
let mut cursor = self.transforms.cursor::<WrapPoint>(&()); let mut cursor = self.transforms.cursor::<WrapPoint>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
if cursor.item().is_some_and(|t| !t.is_isomorphic()) { if cursor.item().is_some_and(|t| !t.is_isomorphic()) {
point = *cursor.start(); point = *cursor.start();
@@ -798,7 +798,7 @@ impl WrapSnapshot {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<WrapPoint, TabPoint>>(&()); .cursor::<Dimensions<WrapPoint, TabPoint>>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
if cursor.item().is_none() { if cursor.item().is_none() {
cursor.prev(); cursor.prev();
@@ -820,7 +820,7 @@ impl WrapSnapshot {
let mut cursor = self let mut cursor = self
.transforms .transforms
.cursor::<Dimensions<WrapPoint, TabPoint>>(&()); .cursor::<Dimensions<WrapPoint, TabPoint>>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
while let Some(transform) = cursor.item() { while let Some(transform) = cursor.item() {
if transform.is_isomorphic() && cursor.start().1.column() == 0 { if transform.is_isomorphic() && cursor.start().1.column() == 0 {
@@ -857,7 +857,7 @@ impl WrapSnapshot {
); );
{ {
let mut transforms = self.transforms.cursor::<()>(&()).peekable(); let mut transforms = self.transforms.cursor::<()>(()).peekable();
while let Some(transform) = transforms.next() { while let Some(transform) = transforms.next() {
if let Some(next_transform) = transforms.peek() { if let Some(next_transform) = transforms.peek() {
assert!(transform.is_isomorphic() != next_transform.is_isomorphic()); assert!(transform.is_isomorphic() != next_transform.is_isomorphic());
@@ -1075,7 +1075,7 @@ impl Transform {
impl sum_tree::Item for Transform { impl sum_tree::Item for Transform {
type Summary = TransformSummary; type Summary = TransformSummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
self.summary.clone() self.summary.clone()
} }
} }
@@ -1106,11 +1106,11 @@ impl SumTreeExt for SumTree<Transform> {
last_transform.summary.output += &transform.summary.output; last_transform.summary.output += &transform.summary.output;
} }
}, },
&(), (),
); );
if let Some(transform) = transform { if let Some(transform) = transform {
self.push(transform, &()); self.push(transform, ());
} }
} }
} }
@@ -1137,41 +1137,39 @@ impl WrapPoint {
} }
} }
impl sum_tree::Summary for TransformSummary { impl sum_tree::ContextLessSummary for TransformSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self) {
self.input += &other.input; self.input += &other.input;
self.output += &other.output; self.output += &other.output;
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for TabPoint { impl<'a> sum_tree::Dimension<'a, TransformSummary> for TabPoint {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += summary.input.lines; self.0 += summary.input.lines;
} }
} }
impl sum_tree::SeekTarget<'_, TransformSummary, TransformSummary> for TabPoint { impl sum_tree::SeekTarget<'_, TransformSummary, TransformSummary> for TabPoint {
fn cmp(&self, cursor_location: &TransformSummary, _: &()) -> std::cmp::Ordering { fn cmp(&self, cursor_location: &TransformSummary, _: ()) -> std::cmp::Ordering {
Ord::cmp(&self.0, &cursor_location.input.lines) Ord::cmp(&self.0, &cursor_location.input.lines)
} }
} }
impl<'a> sum_tree::Dimension<'a, TransformSummary> for WrapPoint { impl<'a> sum_tree::Dimension<'a, TransformSummary> for WrapPoint {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a TransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a TransformSummary, _: ()) {
self.0 += summary.output.lines; self.0 += summary.output.lines;
} }
} }
@@ -1385,7 +1383,7 @@ mod tests {
let mut summary = TextSummary::default(); let mut summary = TextSummary::default();
for (ix, item) in wrapped_snapshot for (ix, item) in wrapped_snapshot
.transforms .transforms
.items(&()) .items(())
.into_iter() .into_iter()
.enumerate() .enumerate()
{ {
+15 -17
View File
@@ -38,29 +38,27 @@ pub struct GitBlameEntrySummary {
impl sum_tree::Item for GitBlameEntry { impl sum_tree::Item for GitBlameEntry {
type Summary = GitBlameEntrySummary; type Summary = GitBlameEntrySummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
GitBlameEntrySummary { rows: self.rows } GitBlameEntrySummary { rows: self.rows }
} }
} }
impl sum_tree::Summary for GitBlameEntrySummary { impl sum_tree::ContextLessSummary for GitBlameEntrySummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _cx: &()) { fn add_summary(&mut self, summary: &Self) {
self.rows += summary.rows; self.rows += summary.rows;
} }
} }
impl<'a> sum_tree::Dimension<'a, GitBlameEntrySummary> for u32 { impl<'a> sum_tree::Dimension<'a, GitBlameEntrySummary> for u32 {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a GitBlameEntrySummary, _cx: &()) { fn add_summary(&mut self, summary: &'a GitBlameEntrySummary, _cx: ()) {
*self += summary.rows; *self += summary.rows;
} }
} }
@@ -298,7 +296,7 @@ impl GitBlame {
self.sync(cx, buffer_id); self.sync(cx, buffer_id);
let buffer_row = info.buffer_row?; let buffer_row = info.buffer_row?;
let mut cursor = self.buffers.get(&buffer_id)?.entries.cursor::<u32>(&()); let mut cursor = self.buffers.get(&buffer_id)?.entries.cursor::<u32>(());
cursor.seek_forward(&buffer_row, Bias::Right); cursor.seek_forward(&buffer_row, Bias::Right);
Some((buffer_id, cursor.item()?.blame.clone()?)) Some((buffer_id, cursor.item()?.blame.clone()?))
}) })
@@ -406,7 +404,7 @@ impl GitBlame {
.peekable(); .peekable();
let mut new_entries = SumTree::default(); let mut new_entries = SumTree::default();
let mut cursor = blame_buffer.entries.cursor::<u32>(&()); let mut cursor = blame_buffer.entries.cursor::<u32>(());
while let Some(mut edit) = row_edits.next() { while let Some(mut edit) = row_edits.next() {
while let Some(next_edit) = row_edits.peek() { while let Some(next_edit) = row_edits.peek() {
@@ -419,7 +417,7 @@ impl GitBlame {
} }
} }
new_entries.append(cursor.slice(&edit.old.start, Bias::Right), &()); new_entries.append(cursor.slice(&edit.old.start, Bias::Right), ());
if edit.new.start > new_entries.summary().rows { if edit.new.start > new_entries.summary().rows {
new_entries.push( new_entries.push(
@@ -427,7 +425,7 @@ impl GitBlame {
rows: edit.new.start - new_entries.summary().rows, rows: edit.new.start - new_entries.summary().rows,
blame: cursor.item().and_then(|entry| entry.blame.clone()), blame: cursor.item().and_then(|entry| entry.blame.clone()),
}, },
&(), (),
); );
} }
@@ -438,7 +436,7 @@ impl GitBlame {
rows: edit.new.len() as u32, rows: edit.new.len() as u32,
blame: None, blame: None,
}, },
&(), (),
); );
} }
@@ -454,14 +452,14 @@ impl GitBlame {
rows: cursor.end() - edit.old.end, rows: cursor.end() - edit.old.end,
blame: entry.blame.clone(), blame: entry.blame.clone(),
}, },
&(), (),
); );
} }
cursor.next(); cursor.next();
} }
} }
new_entries.append(cursor.suffix(), &()); new_entries.append(cursor.suffix(), ());
drop(cursor); drop(cursor);
blame_buffer.buffer_snapshot = new_snapshot; blame_buffer.buffer_snapshot = new_snapshot;
@@ -632,7 +630,7 @@ fn build_blame_entry_sum_tree(entries: Vec<BlameEntry>, max_row: u32) -> SumTree
current_row = entry.range.end; current_row = entry.range.end;
entries entries
}), }),
&(), (),
); );
if max_row >= current_row { if max_row >= current_row {
@@ -641,7 +639,7 @@ fn build_blame_entry_sum_tree(entries: Vec<BlameEntry>, max_row: u32) -> SumTree
rows: (max_row + 1) - current_row, rows: (max_row + 1) - current_row,
blame: None, blame: None,
}, },
&(), (),
); );
} }
+3 -5
View File
@@ -378,14 +378,12 @@ impl From<FileStatus> for GitSummary {
} }
} }
impl sum_tree::Summary for GitSummary { impl sum_tree::ContextLessSummary for GitSummary {
type Context = (); fn zero() -> Self {
fn zero(_: &Self::Context) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, rhs: &Self, _: &Self::Context) { fn add_summary(&mut self, rhs: &Self) {
*self += *rhs; *self += *rhs;
} }
} }
+28 -30
View File
@@ -245,7 +245,7 @@ impl ListState {
) { ) {
let state = &mut *self.0.borrow_mut(); let state = &mut *self.0.borrow_mut();
let mut old_items = state.items.cursor::<Count>(&()); let mut old_items = state.items.cursor::<Count>(());
let mut new_items = old_items.slice(&Count(old_range.start), Bias::Right); let mut new_items = old_items.slice(&Count(old_range.start), Bias::Right);
old_items.seek_forward(&Count(old_range.end), Bias::Right); old_items.seek_forward(&Count(old_range.end), Bias::Right);
@@ -255,9 +255,9 @@ impl ListState {
spliced_count += 1; spliced_count += 1;
ListItem::Unmeasured { focus_handle } ListItem::Unmeasured { focus_handle }
}), }),
&(), (),
); );
new_items.append(old_items.suffix(), &()); new_items.append(old_items.suffix(), ());
drop(old_items); drop(old_items);
state.items = new_items; state.items = new_items;
@@ -296,7 +296,7 @@ impl ListState {
let current_offset = self.logical_scroll_top(); let current_offset = self.logical_scroll_top();
let state = &mut *self.0.borrow_mut(); let state = &mut *self.0.borrow_mut();
let mut cursor = state.items.cursor::<ListItemSummary>(&()); let mut cursor = state.items.cursor::<ListItemSummary>(());
cursor.seek(&Count(current_offset.item_ix), Bias::Right); cursor.seek(&Count(current_offset.item_ix), Bias::Right);
let start_pixel_offset = cursor.start().height + current_offset.offset_in_item; let start_pixel_offset = cursor.start().height + current_offset.offset_in_item;
@@ -339,7 +339,7 @@ impl ListState {
scroll_top.item_ix = ix; scroll_top.item_ix = ix;
scroll_top.offset_in_item = px(0.); scroll_top.offset_in_item = px(0.);
} else { } else {
let mut cursor = state.items.cursor::<ListItemSummary>(&()); let mut cursor = state.items.cursor::<ListItemSummary>(());
cursor.seek(&Count(ix + 1), Bias::Right); cursor.seek(&Count(ix + 1), Bias::Right);
let bottom = cursor.start().height + padding.top; let bottom = cursor.start().height + padding.top;
let goal_top = px(0.).max(bottom - height + padding.bottom); let goal_top = px(0.).max(bottom - height + padding.bottom);
@@ -368,7 +368,7 @@ impl ListState {
return None; return None;
} }
let mut cursor = state.items.cursor::<Dimensions<Count, Height>>(&()); let mut cursor = state.items.cursor::<Dimensions<Count, Height>>(());
cursor.seek(&Count(scroll_top.item_ix), Bias::Right); cursor.seek(&Count(scroll_top.item_ix), Bias::Right);
let scroll_top = cursor.start().1.0 + scroll_top.offset_in_item; let scroll_top = cursor.start().1.0 + scroll_top.offset_in_item;
@@ -426,7 +426,7 @@ impl ListState {
let state = &self.0.borrow(); let state = &self.0.borrow();
let logical_scroll_top = state.logical_scroll_top(); let logical_scroll_top = state.logical_scroll_top();
let mut cursor = state.items.cursor::<ListItemSummary>(&()); let mut cursor = state.items.cursor::<ListItemSummary>(());
let summary: ListItemSummary = let summary: ListItemSummary =
cursor.summary(&Count(logical_scroll_top.item_ix), Bias::Right); cursor.summary(&Count(logical_scroll_top.item_ix), Bias::Right);
let content_height = state.items.summary().height; let content_height = state.items.summary().height;
@@ -446,7 +446,7 @@ impl ListState {
impl StateInner { impl StateInner {
fn visible_range(&self, height: Pixels, scroll_top: &ListOffset) -> Range<usize> { fn visible_range(&self, height: Pixels, scroll_top: &ListOffset) -> Range<usize> {
let mut cursor = self.items.cursor::<ListItemSummary>(&()); let mut cursor = self.items.cursor::<ListItemSummary>(());
cursor.seek(&Count(scroll_top.item_ix), Bias::Right); cursor.seek(&Count(scroll_top.item_ix), Bias::Right);
let start_y = cursor.start().height + scroll_top.offset_in_item; let start_y = cursor.start().height + scroll_top.offset_in_item;
cursor.seek_forward(&Height(start_y + height), Bias::Left); cursor.seek_forward(&Height(start_y + height), Bias::Left);
@@ -478,7 +478,7 @@ impl StateInner {
if self.alignment == ListAlignment::Bottom && new_scroll_top == scroll_max { if self.alignment == ListAlignment::Bottom && new_scroll_top == scroll_max {
self.logical_scroll_top = None; self.logical_scroll_top = None;
} else { } else {
let mut cursor = self.items.cursor::<ListItemSummary>(&()); let mut cursor = self.items.cursor::<ListItemSummary>(());
cursor.seek(&Height(new_scroll_top), Bias::Right); cursor.seek(&Height(new_scroll_top), Bias::Right);
let item_ix = cursor.start().count; let item_ix = cursor.start().count;
let offset_in_item = new_scroll_top - cursor.start().height; let offset_in_item = new_scroll_top - cursor.start().height;
@@ -519,7 +519,7 @@ impl StateInner {
} }
fn scroll_top(&self, logical_scroll_top: &ListOffset) -> Pixels { fn scroll_top(&self, logical_scroll_top: &ListOffset) -> Pixels {
let mut cursor = self.items.cursor::<ListItemSummary>(&()); let mut cursor = self.items.cursor::<ListItemSummary>(());
cursor.seek(&Count(logical_scroll_top.item_ix), Bias::Right); cursor.seek(&Count(logical_scroll_top.item_ix), Bias::Right);
cursor.start().height + logical_scroll_top.offset_in_item cursor.start().height + logical_scroll_top.offset_in_item
} }
@@ -548,7 +548,7 @@ impl StateInner {
AvailableSpace::MinContent, AvailableSpace::MinContent,
); );
let mut cursor = old_items.cursor::<Count>(&()); let mut cursor = old_items.cursor::<Count>(());
// Render items after the scroll top, including those in the trailing overdraw // Render items after the scroll top, including those in the trailing overdraw
cursor.seek(&Count(scroll_top.item_ix), Bias::Right); cursor.seek(&Count(scroll_top.item_ix), Bias::Right);
@@ -663,11 +663,11 @@ impl StateInner {
} }
let measured_range = cursor.start().0..(cursor.start().0 + measured_items.len()); let measured_range = cursor.start().0..(cursor.start().0 + measured_items.len());
let mut cursor = old_items.cursor::<Count>(&()); let mut cursor = old_items.cursor::<Count>(());
let mut new_items = cursor.slice(&Count(measured_range.start), Bias::Right); let mut new_items = cursor.slice(&Count(measured_range.start), Bias::Right);
new_items.extend(measured_items, &()); new_items.extend(measured_items, ());
cursor.seek(&Count(measured_range.end), Bias::Right); cursor.seek(&Count(measured_range.end), Bias::Right);
new_items.append(cursor.suffix(), &()); new_items.append(cursor.suffix(), ());
self.items = new_items; self.items = new_items;
// If none of the visible items are focused, check if an off-screen item is focused // If none of the visible items are focused, check if an off-screen item is focused
@@ -676,7 +676,7 @@ impl StateInner {
if !rendered_focused_item { if !rendered_focused_item {
let mut cursor = self let mut cursor = self
.items .items
.filter::<_, Count>(&(), |summary| summary.has_focus_handles); .filter::<_, Count>((), |summary| summary.has_focus_handles);
cursor.next(); cursor.next();
while let Some(item) = cursor.item() { while let Some(item) = cursor.item() {
if item.contains_focused(window, cx) { if item.contains_focused(window, cx) {
@@ -741,7 +741,7 @@ impl StateInner {
offset_in_item: autoscroll_bounds.top() - item_origin.y, offset_in_item: autoscroll_bounds.top() - item_origin.y,
}); });
} else if autoscroll_bounds.bottom() > bounds.bottom() { } else if autoscroll_bounds.bottom() > bounds.bottom() {
let mut cursor = self.items.cursor::<Count>(&()); let mut cursor = self.items.cursor::<Count>(());
cursor.seek(&Count(item.index), Bias::Right); cursor.seek(&Count(item.index), Bias::Right);
let mut height = bounds.size.height - padding.top - padding.bottom; let mut height = bounds.size.height - padding.top - padding.bottom;
@@ -802,7 +802,7 @@ impl StateInner {
if self.alignment == ListAlignment::Bottom && new_scroll_top == scroll_max { if self.alignment == ListAlignment::Bottom && new_scroll_top == scroll_max {
self.logical_scroll_top = None; self.logical_scroll_top = None;
} else { } else {
let mut cursor = self.items.cursor::<ListItemSummary>(&()); let mut cursor = self.items.cursor::<ListItemSummary>(());
cursor.seek(&Height(new_scroll_top), Bias::Right); cursor.seek(&Height(new_scroll_top), Bias::Right);
let item_ix = cursor.start().count; let item_ix = cursor.start().count;
@@ -946,7 +946,7 @@ impl Element for List {
state.items.iter().map(|item| ListItem::Unmeasured { state.items.iter().map(|item| ListItem::Unmeasured {
focus_handle: item.focus_handle(), focus_handle: item.focus_handle(),
}), }),
&(), (),
); );
state.items = new_items; state.items = new_items;
@@ -1027,7 +1027,7 @@ impl Styled for List {
impl sum_tree::Item for ListItem { impl sum_tree::Item for ListItem {
type Summary = ListItemSummary; type Summary = ListItemSummary;
fn summary(&self, _: &()) -> Self::Summary { fn summary(&self, _: ()) -> Self::Summary {
match self { match self {
ListItem::Unmeasured { focus_handle } => ListItemSummary { ListItem::Unmeasured { focus_handle } => ListItemSummary {
count: 1, count: 1,
@@ -1049,14 +1049,12 @@ impl sum_tree::Item for ListItem {
} }
} }
impl sum_tree::Summary for ListItemSummary { impl sum_tree::ContextLessSummary for ListItemSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self) {
self.count += summary.count; self.count += summary.count;
self.rendered_count += summary.rendered_count; self.rendered_count += summary.rendered_count;
self.unrendered_count += summary.unrendered_count; self.unrendered_count += summary.unrendered_count;
@@ -1066,33 +1064,33 @@ impl sum_tree::Summary for ListItemSummary {
} }
impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Count { impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Count {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) { fn add_summary(&mut self, summary: &'a ListItemSummary, _: ()) {
self.0 += summary.count; self.0 += summary.count;
} }
} }
impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Height { impl<'a> sum_tree::Dimension<'a, ListItemSummary> for Height {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ListItemSummary, _: &()) { fn add_summary(&mut self, summary: &'a ListItemSummary, _: ()) {
self.0 += summary.height; self.0 += summary.height;
} }
} }
impl sum_tree::SeekTarget<'_, ListItemSummary, ListItemSummary> for Count { impl sum_tree::SeekTarget<'_, ListItemSummary, ListItemSummary> for Count {
fn cmp(&self, other: &ListItemSummary, _: &()) -> std::cmp::Ordering { fn cmp(&self, other: &ListItemSummary, _: ()) -> std::cmp::Ordering {
self.0.partial_cmp(&other.count).unwrap() self.0.partial_cmp(&other.count).unwrap()
} }
} }
impl sum_tree::SeekTarget<'_, ListItemSummary, ListItemSummary> for Height { impl sum_tree::SeekTarget<'_, ListItemSummary, ListItemSummary> for Height {
fn cmp(&self, other: &ListItemSummary, _: &()) -> std::cmp::Ordering { fn cmp(&self, other: &ListItemSummary, _: ()) -> std::cmp::Ordering {
self.0.partial_cmp(&other.height).unwrap() self.0.partial_cmp(&other.height).unwrap()
} }
} }
+3 -3
View File
@@ -269,13 +269,13 @@ impl Default for Summary {
} }
impl sum_tree::Summary for Summary { impl sum_tree::Summary for Summary {
type Context = text::BufferSnapshot; type Context<'a> = &'a text::BufferSnapshot;
fn zero(_cx: &Self::Context) -> Self { fn zero(_cx: Self::Context<'_>) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { fn add_summary(&mut self, other: &Self, buffer: Self::Context<'_>) {
if other.min_start.cmp(&self.min_start, buffer).is_lt() { if other.min_start.cmp(&self.min_start, buffer).is_lt() {
self.min_start = other.min_start; self.min_start = other.min_start;
} }
+2 -2
View File
@@ -1775,13 +1775,13 @@ impl Default for SyntaxLayerSummary {
} }
impl sum_tree::Summary for SyntaxLayerSummary { impl sum_tree::Summary for SyntaxLayerSummary {
type Context = BufferSnapshot; type Context<'a> = &'a BufferSnapshot;
fn zero(_cx: &BufferSnapshot) -> Self { fn zero(_cx: &BufferSnapshot) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, buffer: &Self::Context) { fn add_summary(&mut self, other: &Self, buffer: Self::Context<'_>) {
if other.max_depth > self.max_depth { if other.max_depth > self.max_depth {
self.max_depth = other.max_depth; self.max_depth = other.max_depth;
self.range = other.range.clone(); self.range = other.range.clone();
+123 -129
View File
@@ -412,7 +412,7 @@ struct Excerpt {
#[derive(Clone)] #[derive(Clone)]
pub struct MultiBufferExcerpt<'a> { pub struct MultiBufferExcerpt<'a> {
excerpt: &'a Excerpt, excerpt: &'a Excerpt,
diff_transforms: sum_tree::Cursor<'a, DiffTransform, DiffTransforms<usize>>, diff_transforms: sum_tree::Cursor<'a, 'static, DiffTransform, DiffTransforms<usize>>,
offset: usize, offset: usize,
excerpt_offset: ExcerptDimension<usize>, excerpt_offset: ExcerptDimension<usize>,
buffer_offset: usize, buffer_offset: usize,
@@ -468,8 +468,8 @@ pub struct MultiBufferRows<'a> {
} }
pub struct MultiBufferChunks<'a> { pub struct MultiBufferChunks<'a> {
excerpts: Cursor<'a, Excerpt, ExcerptOffset>, excerpts: Cursor<'a, 'static, Excerpt, ExcerptOffset>,
diff_transforms: Cursor<'a, DiffTransform, Dimensions<usize, ExcerptOffset>>, diff_transforms: Cursor<'a, 'static, DiffTransform, Dimensions<usize, ExcerptOffset>>,
diffs: &'a TreeMap<BufferId, BufferDiffSnapshot>, diffs: &'a TreeMap<BufferId, BufferDiffSnapshot>,
diff_base_chunks: Option<(BufferId, BufferChunks<'a>)>, diff_base_chunks: Option<(BufferId, BufferChunks<'a>)>,
buffer_chunk: Option<Chunk<'a>>, buffer_chunk: Option<Chunk<'a>>,
@@ -507,7 +507,7 @@ struct DiffTransforms<D> {
} }
impl<'a, D: TextDimension> Dimension<'a, DiffTransformSummary> for DiffTransforms<D> { impl<'a, D: TextDimension> Dimension<'a, DiffTransformSummary> for DiffTransforms<D> {
fn zero(cx: &<DiffTransformSummary as sum_tree::Summary>::Context) -> Self { fn zero(cx: <DiffTransformSummary as sum_tree::Summary>::Context<'_>) -> Self {
Self { Self {
output_dimension: OutputDimension::zero(cx), output_dimension: OutputDimension::zero(cx),
excerpt_dimension: <ExcerptDimension<D> as Dimension<'a, DiffTransformSummary>>::zero( excerpt_dimension: <ExcerptDimension<D> as Dimension<'a, DiffTransformSummary>>::zero(
@@ -519,7 +519,7 @@ impl<'a, D: TextDimension> Dimension<'a, DiffTransformSummary> for DiffTransform
fn add_summary( fn add_summary(
&mut self, &mut self,
summary: &'a DiffTransformSummary, summary: &'a DiffTransformSummary,
cx: &<DiffTransformSummary as sum_tree::Summary>::Context, cx: <DiffTransformSummary as sum_tree::Summary>::Context<'_>,
) { ) {
self.output_dimension.add_summary(summary, cx); self.output_dimension.add_summary(summary, cx);
self.excerpt_dimension.add_summary(summary, cx); self.excerpt_dimension.add_summary(summary, cx);
@@ -528,8 +528,8 @@ impl<'a, D: TextDimension> Dimension<'a, DiffTransformSummary> for DiffTransform
#[derive(Clone)] #[derive(Clone)]
struct MultiBufferCursor<'a, D: TextDimension> { struct MultiBufferCursor<'a, D: TextDimension> {
excerpts: Cursor<'a, Excerpt, ExcerptDimension<D>>, excerpts: Cursor<'a, 'static, Excerpt, ExcerptDimension<D>>,
diff_transforms: Cursor<'a, DiffTransform, DiffTransforms<D>>, diff_transforms: Cursor<'a, 'static, DiffTransform, DiffTransforms<D>>,
diffs: &'a TreeMap<BufferId, BufferDiffSnapshot>, diffs: &'a TreeMap<BufferId, BufferDiffSnapshot>,
cached_region: Option<MultiBufferRegion<'a, D>>, cached_region: Option<MultiBufferRegion<'a, D>>,
} }
@@ -1196,7 +1196,7 @@ impl MultiBuffer {
let mut ranges = Vec::new(); let mut ranges = Vec::new();
let snapshot = self.read(cx); let snapshot = self.read(cx);
let buffers = self.buffers.borrow(); let buffers = self.buffers.borrow();
let mut cursor = snapshot.excerpts.cursor::<ExcerptSummary>(&()); let mut cursor = snapshot.excerpts.cursor::<ExcerptSummary>(());
for (buffer_id, buffer_transaction) in &transaction.buffer_transactions { for (buffer_id, buffer_transaction) in &transaction.buffer_transactions {
let Some(buffer_state) = buffers.get(buffer_id) else { let Some(buffer_state) = buffers.get(buffer_id) else {
@@ -1311,7 +1311,7 @@ impl MultiBuffer {
let mut selections_by_buffer: HashMap<BufferId, Vec<Selection<text::Anchor>>> = let mut selections_by_buffer: HashMap<BufferId, Vec<Selection<text::Anchor>>> =
Default::default(); Default::default();
let snapshot = self.read(cx); let snapshot = self.read(cx);
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(&()); let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(());
for selection in selections { for selection in selections {
let start_locator = snapshot.excerpt_locator_for_id(selection.start.excerpt_id); let start_locator = snapshot.excerpt_locator_for_id(selection.start.excerpt_id);
let end_locator = snapshot.excerpt_locator_for_id(selection.end.excerpt_id); let end_locator = snapshot.excerpt_locator_for_id(selection.end.excerpt_id);
@@ -1762,7 +1762,7 @@ impl MultiBuffer {
let mut next_excerpt_id = move || ExcerptId(post_inc(&mut next_excerpt_id)); let mut next_excerpt_id = move || ExcerptId(post_inc(&mut next_excerpt_id));
let mut excerpts_cursor = snapshot.excerpts.cursor::<Option<&Locator>>(&()); let mut excerpts_cursor = snapshot.excerpts.cursor::<Option<&Locator>>(());
excerpts_cursor.next(); excerpts_cursor.next();
loop { loop {
@@ -1963,7 +1963,7 @@ impl MultiBuffer {
let mut prev_locator = snapshot.excerpt_locator_for_id(prev_excerpt_id).clone(); let mut prev_locator = snapshot.excerpt_locator_for_id(prev_excerpt_id).clone();
let mut new_excerpt_ids = mem::take(&mut snapshot.excerpt_ids); let mut new_excerpt_ids = mem::take(&mut snapshot.excerpt_ids);
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(&()); let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(());
let mut new_excerpts = cursor.slice(&prev_locator, Bias::Right); let mut new_excerpts = cursor.slice(&prev_locator, Bias::Right);
prev_locator = cursor.start().unwrap_or(Locator::min_ref()).clone(); prev_locator = cursor.start().unwrap_or(Locator::min_ref()).clone();
@@ -1972,7 +1972,7 @@ impl MultiBuffer {
|excerpt| { |excerpt| {
excerpt.has_trailing_newline = true; excerpt.has_trailing_newline = true;
}, },
&(), (),
); );
let next_locator = if let Some(excerpt) = cursor.item() { let next_locator = if let Some(excerpt) = cursor.item() {
@@ -2002,20 +2002,20 @@ impl MultiBuffer {
range, range,
ranges.peek().is_some() || cursor.item().is_some(), ranges.peek().is_some() || cursor.item().is_some(),
); );
new_excerpts.push(excerpt, &()); new_excerpts.push(excerpt, ());
prev_locator = locator.clone(); prev_locator = locator.clone();
if let Some(last_mapping_entry) = new_excerpt_ids.last() { if let Some(last_mapping_entry) = new_excerpt_ids.last() {
assert!(id > last_mapping_entry.id, "excerpt ids must be increasing"); assert!(id > last_mapping_entry.id, "excerpt ids must be increasing");
} }
new_excerpt_ids.push(ExcerptIdMapping { id, locator }, &()); new_excerpt_ids.push(ExcerptIdMapping { id, locator }, ());
} }
let edit_end = ExcerptOffset::new(new_excerpts.summary().text.len); let edit_end = ExcerptOffset::new(new_excerpts.summary().text.len);
let suffix = cursor.suffix(); let suffix = cursor.suffix();
let changed_trailing_excerpt = suffix.is_empty(); let changed_trailing_excerpt = suffix.is_empty();
new_excerpts.append(suffix, &()); new_excerpts.append(suffix, ());
drop(cursor); drop(cursor);
snapshot.excerpts = new_excerpts; snapshot.excerpts = new_excerpts;
snapshot.excerpt_ids = new_excerpt_ids; snapshot.excerpt_ids = new_excerpt_ids;
@@ -2091,7 +2091,7 @@ impl MultiBuffer {
let mut excerpts = Vec::new(); let mut excerpts = Vec::new();
let snapshot = self.read(cx); let snapshot = self.read(cx);
let buffers = self.buffers.borrow(); let buffers = self.buffers.borrow();
let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(&()); let mut cursor = snapshot.excerpts.cursor::<Option<&Locator>>(());
if let Some(locators) = buffers.get(&buffer_id).map(|state| &state.excerpts) { if let Some(locators) = buffers.get(&buffer_id).map(|state| &state.excerpts) {
for locator in locators { for locator in locators {
cursor.seek_forward(&Some(locator), Bias::Left); cursor.seek_forward(&Some(locator), Bias::Left);
@@ -2111,10 +2111,10 @@ impl MultiBuffer {
let buffers = self.buffers.borrow(); let buffers = self.buffers.borrow();
let mut excerpts = snapshot let mut excerpts = snapshot
.excerpts .excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptDimension<Point>>>(&()); .cursor::<Dimensions<Option<&Locator>, ExcerptDimension<Point>>>(());
let mut diff_transforms = snapshot let mut diff_transforms = snapshot
.diff_transforms .diff_transforms
.cursor::<Dimensions<ExcerptDimension<Point>, OutputDimension<Point>>>(&()); .cursor::<Dimensions<ExcerptDimension<Point>, OutputDimension<Point>>>(());
diff_transforms.next(); diff_transforms.next();
let locators = buffers let locators = buffers
.get(&buffer_id) .get(&buffer_id)
@@ -2280,7 +2280,7 @@ impl MultiBuffer {
let mut new_excerpts = SumTree::default(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(&()); .cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(());
let mut edits = Vec::new(); let mut edits = Vec::new();
let mut excerpt_ids = ids.iter().copied().peekable(); let mut excerpt_ids = ids.iter().copied().peekable();
let mut removed_buffer_ids = Vec::new(); let mut removed_buffer_ids = Vec::new();
@@ -2289,7 +2289,7 @@ impl MultiBuffer {
self.paths_by_excerpt.remove(&excerpt_id); self.paths_by_excerpt.remove(&excerpt_id);
// Seek to the next excerpt to remove, preserving any preceding excerpts. // Seek to the next excerpt to remove, preserving any preceding excerpts.
let locator = snapshot.excerpt_locator_for_id(excerpt_id); let locator = snapshot.excerpt_locator_for_id(excerpt_id);
new_excerpts.append(cursor.slice(&Some(locator), Bias::Left), &()); new_excerpts.append(cursor.slice(&Some(locator), Bias::Left), ());
if let Some(mut excerpt) = cursor.item() { if let Some(mut excerpt) = cursor.item() {
if excerpt.id != excerpt_id { if excerpt.id != excerpt_id {
@@ -2331,7 +2331,7 @@ impl MultiBuffer {
// the previous excerpt. // the previous excerpt.
if cursor.item().is_none() && old_start.value > 0 { if cursor.item().is_none() && old_start.value > 0 {
old_start.value -= 1; old_start.value -= 1;
new_excerpts.update_last(|e| e.has_trailing_newline = false, &()); new_excerpts.update_last(|e| e.has_trailing_newline = false, ());
} }
// Push an edit for the removal of this run of excerpts. // Push an edit for the removal of this run of excerpts.
@@ -2345,7 +2345,7 @@ impl MultiBuffer {
} }
let suffix = cursor.suffix(); let suffix = cursor.suffix();
let changed_trailing_excerpt = suffix.is_empty(); let changed_trailing_excerpt = suffix.is_empty();
new_excerpts.append(suffix, &()); new_excerpts.append(suffix, ());
drop(cursor); drop(cursor);
snapshot.excerpts = new_excerpts; snapshot.excerpts = new_excerpts;
for buffer_id in &removed_buffer_ids { for buffer_id in &removed_buffer_ids {
@@ -2487,7 +2487,7 @@ impl MultiBuffer {
for locator in &buffer_state.excerpts { for locator in &buffer_state.excerpts {
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(&()); .cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(());
cursor.seek_forward(&Some(locator), Bias::Left); cursor.seek_forward(&Some(locator), Bias::Left);
if let Some(excerpt) = cursor.item() if let Some(excerpt) = cursor.item()
&& excerpt.locator == *locator && excerpt.locator == *locator
@@ -2721,7 +2721,7 @@ impl MultiBuffer {
pub fn single_hunk_is_expanded(&self, range: Range<Anchor>, cx: &App) -> bool { pub fn single_hunk_is_expanded(&self, range: Range<Anchor>, cx: &App) -> bool {
let snapshot = self.read(cx); let snapshot = self.read(cx);
let mut cursor = snapshot.diff_transforms.cursor::<usize>(&()); let mut cursor = snapshot.diff_transforms.cursor::<usize>(());
let offset_range = range.to_offset(&snapshot); let offset_range = range.to_offset(&snapshot);
cursor.seek(&offset_range.start, Bias::Left); cursor.seek(&offset_range.start, Bias::Left);
while let Some(item) = cursor.item() { while let Some(item) = cursor.item() {
@@ -2738,7 +2738,7 @@ impl MultiBuffer {
pub fn has_expanded_diff_hunks_in_ranges(&self, ranges: &[Range<Anchor>], cx: &App) -> bool { pub fn has_expanded_diff_hunks_in_ranges(&self, ranges: &[Range<Anchor>], cx: &App) -> bool {
let snapshot = self.read(cx); let snapshot = self.read(cx);
let mut cursor = snapshot.diff_transforms.cursor::<usize>(&()); let mut cursor = snapshot.diff_transforms.cursor::<usize>(());
for range in ranges { for range in ranges {
let range = range.to_point(&snapshot); let range = range.to_point(&snapshot);
let start = snapshot.point_to_offset(Point::new(range.start.row, 0)); let start = snapshot.point_to_offset(Point::new(range.start.row, 0));
@@ -2844,11 +2844,11 @@ impl MultiBuffer {
let mut new_excerpts = SumTree::default(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(&()); .cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(());
let mut edits = Vec::<Edit<ExcerptOffset>>::new(); let mut edits = Vec::<Edit<ExcerptOffset>>::new();
let prefix = cursor.slice(&Some(locator), Bias::Left); let prefix = cursor.slice(&Some(locator), Bias::Left);
new_excerpts.append(prefix, &()); new_excerpts.append(prefix, ());
let mut excerpt = cursor.item().unwrap().clone(); let mut excerpt = cursor.item().unwrap().clone();
let old_text_len = ExcerptOffset::new(excerpt.text_summary.len); let old_text_len = ExcerptOffset::new(excerpt.text_summary.len);
@@ -2880,11 +2880,11 @@ impl MultiBuffer {
edits.push(edit); edits.push(edit);
} }
new_excerpts.push(excerpt, &()); new_excerpts.push(excerpt, ());
cursor.next(); cursor.next();
new_excerpts.append(cursor.suffix(), &()); new_excerpts.append(cursor.suffix(), ());
drop(cursor); drop(cursor);
snapshot.excerpts = new_excerpts; snapshot.excerpts = new_excerpts;
@@ -2920,12 +2920,12 @@ impl MultiBuffer {
let mut new_excerpts = SumTree::default(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(&()); .cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(());
let mut edits = Vec::<Edit<ExcerptOffset>>::new(); let mut edits = Vec::<Edit<ExcerptOffset>>::new();
for locator in &locators { for locator in &locators {
let prefix = cursor.slice(&Some(locator), Bias::Left); let prefix = cursor.slice(&Some(locator), Bias::Left);
new_excerpts.append(prefix, &()); new_excerpts.append(prefix, ());
let mut excerpt = cursor.item().unwrap().clone(); let mut excerpt = cursor.item().unwrap().clone();
let old_text_len = ExcerptOffset::new(excerpt.text_summary.len); let old_text_len = ExcerptOffset::new(excerpt.text_summary.len);
@@ -2984,12 +2984,12 @@ impl MultiBuffer {
edits.push(edit); edits.push(edit);
} }
new_excerpts.push(excerpt, &()); new_excerpts.push(excerpt, ());
cursor.next(); cursor.next();
} }
new_excerpts.append(cursor.suffix(), &()); new_excerpts.append(cursor.suffix(), ());
drop(cursor); drop(cursor);
snapshot.excerpts = new_excerpts; snapshot.excerpts = new_excerpts;
@@ -3066,10 +3066,10 @@ impl MultiBuffer {
let mut new_excerpts = SumTree::default(); let mut new_excerpts = SumTree::default();
let mut cursor = snapshot let mut cursor = snapshot
.excerpts .excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(&()); .cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(());
for (locator, buffer, buffer_edited) in excerpts_to_edit { for (locator, buffer, buffer_edited) in excerpts_to_edit {
new_excerpts.append(cursor.slice(&Some(locator), Bias::Left), &()); new_excerpts.append(cursor.slice(&Some(locator), Bias::Left), ());
let old_excerpt = cursor.item().unwrap(); let old_excerpt = cursor.item().unwrap();
let buffer = buffer.read(cx); let buffer = buffer.read(cx);
let buffer_id = buffer.remote_id(); let buffer_id = buffer.remote_id();
@@ -3110,10 +3110,10 @@ impl MultiBuffer {
new_excerpt.buffer = buffer.snapshot(); new_excerpt.buffer = buffer.snapshot();
} }
new_excerpts.push(new_excerpt, &()); new_excerpts.push(new_excerpt, ());
cursor.next(); cursor.next();
} }
new_excerpts.append(cursor.suffix(), &()); new_excerpts.append(cursor.suffix(), ());
drop(cursor); drop(cursor);
snapshot.excerpts = new_excerpts; snapshot.excerpts = new_excerpts;
@@ -3131,10 +3131,10 @@ impl MultiBuffer {
return; return;
} }
let mut excerpts = snapshot.excerpts.cursor::<ExcerptOffset>(&()); let mut excerpts = snapshot.excerpts.cursor::<ExcerptOffset>(());
let mut old_diff_transforms = snapshot let mut old_diff_transforms = snapshot
.diff_transforms .diff_transforms
.cursor::<Dimensions<ExcerptOffset, usize>>(&()); .cursor::<Dimensions<ExcerptOffset, usize>>(());
let mut new_diff_transforms = SumTree::default(); let mut new_diff_transforms = SumTree::default();
let mut old_expanded_hunks = HashSet::default(); let mut old_expanded_hunks = HashSet::default();
let mut output_edits = Vec::new(); let mut output_edits = Vec::new();
@@ -3241,7 +3241,7 @@ impl MultiBuffer {
summary: Default::default(), summary: Default::default(),
inserted_hunk_info: None, inserted_hunk_info: None,
}, },
&(), (),
); );
} }
@@ -3399,7 +3399,7 @@ impl MultiBuffer {
hunk_info, hunk_info,
has_trailing_newline, has_trailing_newline,
}, },
&(), (),
); );
} }
@@ -3436,13 +3436,13 @@ impl MultiBuffer {
*summary, *summary,
) )
{ {
let mut cursor = subtree.cursor::<()>(&()); let mut cursor = subtree.cursor::<()>(());
cursor.next(); cursor.next();
cursor.next(); cursor.next();
new_transforms.append(cursor.suffix(), &()); new_transforms.append(cursor.suffix(), ());
return; return;
} }
new_transforms.append(subtree, &()); new_transforms.append(subtree, ());
} }
fn push_diff_transform( fn push_diff_transform(
@@ -3462,7 +3462,7 @@ impl MultiBuffer {
{ {
return; return;
} }
new_transforms.push(transform, &()); new_transforms.push(transform, ());
} }
fn push_buffer_content_transform( fn push_buffer_content_transform(
@@ -3496,7 +3496,7 @@ impl MultiBuffer {
summary: summary_to_add, summary: summary_to_add,
inserted_hunk_info, inserted_hunk_info,
}, },
&(), (),
) )
} }
} }
@@ -3521,7 +3521,7 @@ impl MultiBuffer {
did_extend = true; did_extend = true;
} }
}, },
&(), (),
); );
did_extend did_extend
} }
@@ -4033,7 +4033,7 @@ impl MultiBufferSnapshot {
cursor.seek(&query_range.start); cursor.seek(&query_range.start);
if let Some(region) = cursor.region().filter(|region| !region.is_main_buffer) if let Some(region) = cursor.region().filter(|region| !region.is_main_buffer)
&& region.range.start > D::zero(&()) && region.range.start > D::zero(())
{ {
cursor.prev() cursor.prev()
} }
@@ -4368,8 +4368,8 @@ impl MultiBufferSnapshot {
let mut chunks = MultiBufferChunks { let mut chunks = MultiBufferChunks {
excerpt_offset_range: ExcerptOffset::new(0)..ExcerptOffset::new(0), excerpt_offset_range: ExcerptOffset::new(0)..ExcerptOffset::new(0),
range: 0..0, range: 0..0,
excerpts: self.excerpts.cursor(&()), excerpts: self.excerpts.cursor(()),
diff_transforms: self.diff_transforms.cursor(&()), diff_transforms: self.diff_transforms.cursor(()),
diffs: &self.diffs, diffs: &self.diffs,
diff_base_chunks: None, diff_base_chunks: None,
excerpt_chunks: None, excerpt_chunks: None,
@@ -4706,7 +4706,7 @@ impl MultiBufferSnapshot {
let range = range.start.to_offset(self)..range.end.to_offset(self); let range = range.start.to_offset(self)..range.end.to_offset(self);
let mut cursor = self let mut cursor = self
.diff_transforms .diff_transforms
.cursor::<Dimensions<usize, ExcerptOffset>>(&()); .cursor::<Dimensions<usize, ExcerptOffset>>(());
cursor.seek(&range.start, Bias::Right); cursor.seek(&range.start, Bias::Right);
let Some(first_transform) = cursor.item() else { let Some(first_transform) = cursor.item() else {
@@ -4801,8 +4801,8 @@ impl MultiBufferSnapshot {
D: TextDimension, D: TextDimension,
{ {
// let mut range = range.start..range.end; // let mut range = range.start..range.end;
let mut summary = D::zero(&()); let mut summary = D::zero(());
let mut cursor = self.excerpts.cursor::<ExcerptOffset>(&()); let mut cursor = self.excerpts.cursor::<ExcerptOffset>(());
cursor.seek(&range.start, Bias::Right); cursor.seek(&range.start, Bias::Right);
if let Some(excerpt) = cursor.item() { if let Some(excerpt) = cursor.item() {
let mut end_before_newline = cursor.end(); let mut end_before_newline = cursor.end();
@@ -4920,7 +4920,7 @@ impl MultiBufferSnapshot {
fn excerpt_offset_for_anchor(&self, anchor: &Anchor) -> ExcerptOffset { fn excerpt_offset_for_anchor(&self, anchor: &Anchor) -> ExcerptOffset {
let mut cursor = self let mut cursor = self
.excerpts .excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(&()); .cursor::<Dimensions<Option<&Locator>, ExcerptOffset>>(());
let locator = self.excerpt_locator_for_id(anchor.excerpt_id); let locator = self.excerpt_locator_for_id(anchor.excerpt_id);
cursor.seek(&Some(locator), Bias::Left); cursor.seek(&Some(locator), Bias::Left);
@@ -4960,10 +4960,10 @@ impl MultiBufferSnapshot {
I: 'a + IntoIterator<Item = &'a Anchor>, I: 'a + IntoIterator<Item = &'a Anchor>,
{ {
let mut anchors = anchors.into_iter().peekable(); let mut anchors = anchors.into_iter().peekable();
let mut cursor = self.excerpts.cursor::<ExcerptSummary>(&()); let mut cursor = self.excerpts.cursor::<ExcerptSummary>(());
let mut diff_transforms_cursor = self let mut diff_transforms_cursor = self
.diff_transforms .diff_transforms
.cursor::<Dimensions<ExcerptDimension<D>, OutputDimension<D>>>(&()); .cursor::<Dimensions<ExcerptDimension<D>, OutputDimension<D>>>(());
diff_transforms_cursor.next(); diff_transforms_cursor.next();
let mut summaries = Vec::new(); let mut summaries = Vec::new();
@@ -5081,7 +5081,7 @@ impl MultiBufferSnapshot {
I: 'a + IntoIterator<Item = &'a Anchor>, I: 'a + IntoIterator<Item = &'a Anchor>,
{ {
let mut anchors = anchors.into_iter().enumerate().peekable(); let mut anchors = anchors.into_iter().enumerate().peekable();
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(&()); let mut cursor = self.excerpts.cursor::<Option<&Locator>>(());
cursor.next(); cursor.next();
let mut result = Vec::new(); let mut result = Vec::new();
@@ -5195,7 +5195,7 @@ impl MultiBufferSnapshot {
// offset in the excerpts, and whether the position is within a deleted hunk. // offset in the excerpts, and whether the position is within a deleted hunk.
let mut diff_transforms = self let mut diff_transforms = self
.diff_transforms .diff_transforms
.cursor::<Dimensions<usize, ExcerptOffset>>(&()); .cursor::<Dimensions<usize, ExcerptOffset>>(());
diff_transforms.seek(&offset, Bias::Right); diff_transforms.seek(&offset, Bias::Right);
if offset == diff_transforms.start().0 if offset == diff_transforms.start().0
@@ -5232,7 +5232,7 @@ impl MultiBufferSnapshot {
let mut excerpts = self let mut excerpts = self
.excerpts .excerpts
.cursor::<Dimensions<ExcerptOffset, Option<ExcerptId>>>(&()); .cursor::<Dimensions<ExcerptOffset, Option<ExcerptId>>>(());
excerpts.seek(&excerpt_offset, Bias::Right); excerpts.seek(&excerpt_offset, Bias::Right);
if excerpts.item().is_none() && excerpt_offset == excerpts.start().0 && bias == Bias::Left { if excerpts.item().is_none() && excerpt_offset == excerpts.start().0 && bias == Bias::Left {
excerpts.prev(); excerpts.prev();
@@ -5277,7 +5277,7 @@ impl MultiBufferSnapshot {
) -> Option<Anchor> { ) -> Option<Anchor> {
let excerpt_id = self.latest_excerpt_id(excerpt_id); let excerpt_id = self.latest_excerpt_id(excerpt_id);
let locator = self.excerpt_locator_for_id(excerpt_id); let locator = self.excerpt_locator_for_id(excerpt_id);
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(&()); let mut cursor = self.excerpts.cursor::<Option<&Locator>>(());
cursor.seek(locator, Bias::Left); cursor.seek(locator, Bias::Left);
if let Some(excerpt) = cursor.item() if let Some(excerpt) = cursor.item()
&& excerpt.id == excerpt_id && excerpt.id == excerpt_id
@@ -5317,8 +5317,8 @@ impl MultiBufferSnapshot {
} }
fn cursor<D: TextDimension + Default>(&self) -> MultiBufferCursor<'_, D> { fn cursor<D: TextDimension + Default>(&self) -> MultiBufferCursor<'_, D> {
let excerpts = self.excerpts.cursor(&()); let excerpts = self.excerpts.cursor(());
let diff_transforms = self.diff_transforms.cursor(&()); let diff_transforms = self.diff_transforms.cursor(());
MultiBufferCursor { MultiBufferCursor {
excerpts, excerpts,
diff_transforms, diff_transforms,
@@ -5331,11 +5331,11 @@ impl MultiBufferSnapshot {
let start_locator = self.excerpt_locator_for_id(id); let start_locator = self.excerpt_locator_for_id(id);
let mut excerpts = self let mut excerpts = self
.excerpts .excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptDimension<usize>>>(&()); .cursor::<Dimensions<Option<&Locator>, ExcerptDimension<usize>>>(());
excerpts.seek(&Some(start_locator), Bias::Left); excerpts.seek(&Some(start_locator), Bias::Left);
excerpts.prev(); excerpts.prev();
let mut diff_transforms = self.diff_transforms.cursor::<DiffTransforms<usize>>(&()); let mut diff_transforms = self.diff_transforms.cursor::<DiffTransforms<usize>>(());
diff_transforms.seek(&excerpts.start().1, Bias::Left); diff_transforms.seek(&excerpts.start().1, Bias::Left);
if diff_transforms.end().excerpt_dimension < excerpts.start().1 { if diff_transforms.end().excerpt_dimension < excerpts.start().1 {
diff_transforms.next(); diff_transforms.next();
@@ -6188,7 +6188,7 @@ impl MultiBufferSnapshot {
} else if id == ExcerptId::max() { } else if id == ExcerptId::max() {
Locator::max_ref() Locator::max_ref()
} else { } else {
let mut cursor = self.excerpt_ids.cursor::<ExcerptId>(&()); let mut cursor = self.excerpt_ids.cursor::<ExcerptId>(());
cursor.seek(&id, Bias::Left); cursor.seek(&id, Bias::Left);
if let Some(entry) = cursor.item() if let Some(entry) = cursor.item()
&& entry.id == id && entry.id == id
@@ -6223,7 +6223,7 @@ impl MultiBufferSnapshot {
} }
} }
let mut cursor = self.excerpt_ids.cursor::<ExcerptId>(&()); let mut cursor = self.excerpt_ids.cursor::<ExcerptId>(());
for id in sorted_ids { for id in sorted_ids {
if cursor.seek_forward(&id, Bias::Left) { if cursor.seek_forward(&id, Bias::Left) {
locators.push(cursor.item().unwrap().locator.clone()); locators.push(cursor.item().unwrap().locator.clone());
@@ -6247,14 +6247,14 @@ impl MultiBufferSnapshot {
pub fn range_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<Range<Point>> { pub fn range_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<Range<Point>> {
let mut cursor = self let mut cursor = self
.excerpts .excerpts
.cursor::<Dimensions<Option<&Locator>, ExcerptDimension<Point>>>(&()); .cursor::<Dimensions<Option<&Locator>, ExcerptDimension<Point>>>(());
let locator = self.excerpt_locator_for_id(excerpt_id); let locator = self.excerpt_locator_for_id(excerpt_id);
if cursor.seek(&Some(locator), Bias::Left) { if cursor.seek(&Some(locator), Bias::Left) {
let start = cursor.start().1.clone(); let start = cursor.start().1.clone();
let end = cursor.end().1; let end = cursor.end().1;
let mut diff_transforms = self let mut diff_transforms = self
.diff_transforms .diff_transforms
.cursor::<Dimensions<ExcerptDimension<Point>, OutputDimension<Point>>>(&()); .cursor::<Dimensions<ExcerptDimension<Point>, OutputDimension<Point>>>(());
diff_transforms.seek(&start, Bias::Left); diff_transforms.seek(&start, Bias::Left);
let overshoot = start.0 - diff_transforms.start().0.0; let overshoot = start.0 - diff_transforms.start().0.0;
let start = diff_transforms.start().1.0 + overshoot; let start = diff_transforms.start().1.0 + overshoot;
@@ -6268,7 +6268,7 @@ impl MultiBufferSnapshot {
} }
pub fn buffer_range_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<Range<text::Anchor>> { pub fn buffer_range_for_excerpt(&self, excerpt_id: ExcerptId) -> Option<Range<text::Anchor>> {
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(&()); let mut cursor = self.excerpts.cursor::<Option<&Locator>>(());
let locator = self.excerpt_locator_for_id(excerpt_id); let locator = self.excerpt_locator_for_id(excerpt_id);
if cursor.seek(&Some(locator), Bias::Left) if cursor.seek(&Some(locator), Bias::Left)
&& let Some(excerpt) = cursor.item() && let Some(excerpt) = cursor.item()
@@ -6279,7 +6279,7 @@ impl MultiBufferSnapshot {
} }
fn excerpt(&self, excerpt_id: ExcerptId) -> Option<&Excerpt> { fn excerpt(&self, excerpt_id: ExcerptId) -> Option<&Excerpt> {
let mut cursor = self.excerpts.cursor::<Option<&Locator>>(&()); let mut cursor = self.excerpts.cursor::<Option<&Locator>>(());
let locator = self.excerpt_locator_for_id(excerpt_id); let locator = self.excerpt_locator_for_id(excerpt_id);
cursor.seek(&Some(locator), Bias::Left); cursor.seek(&Some(locator), Bias::Left);
if let Some(excerpt) = cursor.item() if let Some(excerpt) = cursor.item()
@@ -6334,7 +6334,7 @@ impl MultiBufferSnapshot {
range: &'a Range<Anchor>, range: &'a Range<Anchor>,
include_local: bool, include_local: bool,
) -> impl 'a + Iterator<Item = (ReplicaId, bool, CursorShape, Selection<Anchor>)> { ) -> impl 'a + Iterator<Item = (ReplicaId, bool, CursorShape, Selection<Anchor>)> {
let mut cursor = self.excerpts.cursor::<ExcerptSummary>(&()); let mut cursor = self.excerpts.cursor::<ExcerptSummary>(());
let start_locator = self.excerpt_locator_for_id(range.start.excerpt_id); let start_locator = self.excerpt_locator_for_id(range.start.excerpt_id);
let end_locator = self.excerpt_locator_for_id(range.end.excerpt_id); let end_locator = self.excerpt_locator_for_id(range.end.excerpt_id);
cursor.seek(start_locator, Bias::Left); cursor.seek(start_locator, Bias::Left);
@@ -6448,8 +6448,8 @@ impl MultiBufferSnapshot {
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
fn check_invariants(&self) { fn check_invariants(&self) {
let excerpts = self.excerpts.items(&()); let excerpts = self.excerpts.items(());
let excerpt_ids = self.excerpt_ids.items(&()); let excerpt_ids = self.excerpt_ids.items(());
for (ix, excerpt) in excerpts.iter().enumerate() { for (ix, excerpt) in excerpts.iter().enumerate() {
if ix == 0 { if ix == 0 {
@@ -6476,7 +6476,7 @@ impl MultiBufferSnapshot {
"incorrect input summary. expected {:?}, got {:?}. transforms: {:+?}", "incorrect input summary. expected {:?}, got {:?}. transforms: {:+?}",
self.excerpts.summary().text.len, self.excerpts.summary().text.len,
self.diff_transforms.summary().input, self.diff_transforms.summary().input,
self.diff_transforms.items(&()), self.diff_transforms.items(()),
); );
} }
@@ -6495,7 +6495,7 @@ impl MultiBufferSnapshot {
{ {
panic!( panic!(
"multiple adjacent buffer content transforms with is_inserted_hunk = {inserted_hunk_info:?}. transforms: {:+?}", "multiple adjacent buffer content transforms with is_inserted_hunk = {inserted_hunk_info:?}. transforms: {:+?}",
self.diff_transforms.items(&()) self.diff_transforms.items(())
); );
} }
if summary.len == 0 && !self.is_empty() { if summary.len == 0 && !self.is_empty() {
@@ -7243,7 +7243,7 @@ impl fmt::Debug for Excerpt {
impl sum_tree::Item for Excerpt { impl sum_tree::Item for Excerpt {
type Summary = ExcerptSummary; type Summary = ExcerptSummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
let mut text = self.text_summary; let mut text = self.text_summary;
if self.has_trailing_newline { if self.has_trailing_newline {
text += TextSummary::from("\n"); text += TextSummary::from("\n");
@@ -7260,7 +7260,7 @@ impl sum_tree::Item for Excerpt {
impl sum_tree::Item for ExcerptIdMapping { impl sum_tree::Item for ExcerptIdMapping {
type Summary = ExcerptId; type Summary = ExcerptId;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
self.id self.id
} }
} }
@@ -7287,7 +7287,7 @@ impl DiffTransform {
impl sum_tree::Item for DiffTransform { impl sum_tree::Item for DiffTransform {
type Summary = DiffTransformSummary; type Summary = DiffTransformSummary;
fn summary(&self, _: &<Self::Summary as sum_tree::Summary>::Context) -> Self::Summary { fn summary(&self, _: <Self::Summary as sum_tree::Summary>::Context<'_>) -> Self::Summary {
match self { match self {
DiffTransform::BufferContent { summary, .. } => DiffTransformSummary { DiffTransform::BufferContent { summary, .. } => DiffTransformSummary {
input: *summary, input: *summary,
@@ -7307,83 +7307,77 @@ impl DiffTransformSummary {
} }
} }
impl sum_tree::Summary for DiffTransformSummary { impl sum_tree::ContextLessSummary for DiffTransformSummary {
type Context = (); fn zero() -> Self {
fn zero(_: &Self::Context) -> Self {
DiffTransformSummary { DiffTransformSummary {
input: TextSummary::default(), input: TextSummary::default(),
output: TextSummary::default(), output: TextSummary::default(),
} }
} }
fn add_summary(&mut self, summary: &Self, _: &Self::Context) { fn add_summary(&mut self, other: &Self) {
self.input += &summary.input; self.input += other.input;
self.output += &summary.output; self.output += other.output;
} }
} }
impl sum_tree::Summary for ExcerptId { impl sum_tree::ContextLessSummary for ExcerptId {
type Context = (); fn zero() -> Self {
Self(0)
fn zero(_cx: &()) -> Self {
Default::default()
} }
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, summary: &Self) {
*self = *other; *self = cmp::max(*self, *summary);
} }
} }
impl sum_tree::Summary for ExcerptSummary { impl sum_tree::ContextLessSummary for ExcerptSummary {
type Context = (); fn zero() -> Self {
Self::default()
fn zero(_cx: &()) -> Self {
Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self) {
debug_assert!(summary.excerpt_locator > self.excerpt_locator); debug_assert!(summary.excerpt_locator > self.excerpt_locator);
self.excerpt_locator = summary.excerpt_locator.clone(); self.excerpt_locator = summary.excerpt_locator.clone();
Summary::add_summary(&mut self.text, &summary.text, &()); Summary::add_summary(&mut self.text, &summary.text, ());
self.widest_line_number = cmp::max(self.widest_line_number, summary.widest_line_number); self.widest_line_number = cmp::max(self.widest_line_number, summary.widest_line_number);
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for ExcerptOffset { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for ExcerptOffset {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: ()) {
self.value += summary.text.len; self.value += summary.text.len;
} }
} }
impl sum_tree::SeekTarget<'_, ExcerptSummary, ExcerptSummary> for ExcerptOffset { impl sum_tree::SeekTarget<'_, ExcerptSummary, ExcerptSummary> for ExcerptOffset {
fn cmp(&self, cursor_location: &ExcerptSummary, _: &()) -> cmp::Ordering { fn cmp(&self, cursor_location: &ExcerptSummary, _: ()) -> cmp::Ordering {
Ord::cmp(&self.value, &cursor_location.text.len) Ord::cmp(&self.value, &cursor_location.text.len)
} }
} }
impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, Option<&'a Locator>> for Locator { impl<'a> sum_tree::SeekTarget<'a, ExcerptSummary, Option<&'a Locator>> for Locator {
fn cmp(&self, cursor_location: &Option<&'a Locator>, _: &()) -> cmp::Ordering { fn cmp(&self, cursor_location: &Option<&'a Locator>, _: ()) -> cmp::Ordering {
Ord::cmp(&Some(self), cursor_location) Ord::cmp(&Some(self), cursor_location)
} }
} }
impl sum_tree::SeekTarget<'_, ExcerptSummary, ExcerptSummary> for Locator { impl sum_tree::SeekTarget<'_, ExcerptSummary, ExcerptSummary> for Locator {
fn cmp(&self, cursor_location: &ExcerptSummary, _: &()) -> cmp::Ordering { fn cmp(&self, cursor_location: &ExcerptSummary, _: ()) -> cmp::Ordering {
Ord::cmp(self, &cursor_location.excerpt_locator) Ord::cmp(self, &cursor_location.excerpt_locator)
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for ExcerptPoint { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for ExcerptPoint {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: ()) {
self.value += summary.text.lines; self.value += summary.text.lines;
} }
} }
@@ -7391,31 +7385,31 @@ impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for ExcerptPoint {
impl<'a, D: TextDimension + Default> sum_tree::Dimension<'a, ExcerptSummary> impl<'a, D: TextDimension + Default> sum_tree::Dimension<'a, ExcerptSummary>
for ExcerptDimension<D> for ExcerptDimension<D>
{ {
fn zero(_: &()) -> Self { fn zero(_: ()) -> Self {
ExcerptDimension(D::default()) ExcerptDimension(D::default())
} }
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: ()) {
self.0.add_assign(&D::from_text_summary(&summary.text)) self.0.add_assign(&D::from_text_summary(&summary.text))
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<&'a Locator> { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<&'a Locator> {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: ()) {
*self = Some(&summary.excerpt_locator); *self = Some(&summary.excerpt_locator);
} }
} }
impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<ExcerptId> { impl<'a> sum_tree::Dimension<'a, ExcerptSummary> for Option<ExcerptId> {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ExcerptSummary, _: &()) { fn add_summary(&mut self, summary: &'a ExcerptSummary, _: ()) {
*self = Some(summary.excerpt_id); *self = Some(summary.excerpt_id);
} }
} }
@@ -7427,21 +7421,21 @@ struct ExcerptDimension<T>(T);
struct OutputDimension<T>(T); struct OutputDimension<T>(T);
impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for ExcerptOffset { impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for ExcerptOffset {
fn zero(_: &()) -> Self { fn zero(_: ()) -> Self {
ExcerptOffset::new(0) ExcerptOffset::new(0)
} }
fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: ()) {
self.value += summary.input.len; self.value += summary.input.len;
} }
} }
impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for ExcerptPoint { impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for ExcerptPoint {
fn zero(_: &()) -> Self { fn zero(_: ()) -> Self {
ExcerptPoint::new(0, 0) ExcerptPoint::new(0, 0)
} }
fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: ()) {
self.value += summary.input.lines; self.value += summary.input.lines;
} }
} }
@@ -7449,7 +7443,7 @@ impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for ExcerptPoint {
impl<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransformSummary> impl<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransformSummary>
for ExcerptDimension<D> for ExcerptDimension<D>
{ {
fn cmp(&self, cursor_location: &DiffTransformSummary, _: &()) -> cmp::Ordering { fn cmp(&self, cursor_location: &DiffTransformSummary, _: ()) -> cmp::Ordering {
Ord::cmp(&self.0, &D::from_text_summary(&cursor_location.input)) Ord::cmp(&self.0, &D::from_text_summary(&cursor_location.input))
} }
} }
@@ -7457,17 +7451,17 @@ impl<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, Diff
impl<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransforms<D>> impl<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransforms<D>>
for ExcerptDimension<D> for ExcerptDimension<D>
{ {
fn cmp(&self, cursor_location: &DiffTransforms<D>, _: &()) -> cmp::Ordering { fn cmp(&self, cursor_location: &DiffTransforms<D>, _: ()) -> cmp::Ordering {
Ord::cmp(&self.0, &cursor_location.excerpt_dimension.0) Ord::cmp(&self.0, &cursor_location.excerpt_dimension.0)
} }
} }
impl<'a, D: TextDimension> sum_tree::Dimension<'a, DiffTransformSummary> for ExcerptDimension<D> { impl<'a, D: TextDimension> sum_tree::Dimension<'a, DiffTransformSummary> for ExcerptDimension<D> {
fn zero(_: &()) -> Self { fn zero(_: ()) -> Self {
ExcerptDimension(D::default()) ExcerptDimension(D::default())
} }
fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: ()) {
self.0.add_assign(&D::from_text_summary(&summary.input)) self.0.add_assign(&D::from_text_summary(&summary.input))
} }
} }
@@ -7475,47 +7469,47 @@ impl<'a, D: TextDimension> sum_tree::Dimension<'a, DiffTransformSummary> for Exc
impl<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransforms<D>> impl<D: TextDimension + Ord> sum_tree::SeekTarget<'_, DiffTransformSummary, DiffTransforms<D>>
for OutputDimension<D> for OutputDimension<D>
{ {
fn cmp(&self, cursor_location: &DiffTransforms<D>, _: &()) -> cmp::Ordering { fn cmp(&self, cursor_location: &DiffTransforms<D>, _: ()) -> cmp::Ordering {
Ord::cmp(&self.0, &cursor_location.output_dimension.0) Ord::cmp(&self.0, &cursor_location.output_dimension.0)
} }
} }
impl<'a, D: TextDimension> sum_tree::Dimension<'a, DiffTransformSummary> for OutputDimension<D> { impl<'a, D: TextDimension> sum_tree::Dimension<'a, DiffTransformSummary> for OutputDimension<D> {
fn zero(_: &()) -> Self { fn zero(_: ()) -> Self {
OutputDimension(D::default()) OutputDimension(D::default())
} }
fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: ()) {
self.0.add_assign(&D::from_text_summary(&summary.output)) self.0.add_assign(&D::from_text_summary(&summary.output))
} }
} }
impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for TextSummary { impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for TextSummary {
fn zero(_: &()) -> Self { fn zero(_: ()) -> Self {
TextSummary::default() TextSummary::default()
} }
fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: ()) {
*self += summary.output *self += summary.output
} }
} }
impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for usize { impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for usize {
fn zero(_: &()) -> Self { fn zero(_: ()) -> Self {
0 0
} }
fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: ()) {
*self += summary.output.len *self += summary.output.len
} }
} }
impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for Point { impl<'a> sum_tree::Dimension<'a, DiffTransformSummary> for Point {
fn zero(_: &()) -> Self { fn zero(_: ()) -> Self {
Point::new(0, 0) Point::new(0, 0)
} }
fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: &()) { fn add_summary(&mut self, summary: &'a DiffTransformSummary, _: ()) {
*self += summary.output.lines *self += summary.output.lines
} }
} }
+14 -16
View File
@@ -123,12 +123,12 @@ impl NotificationStore {
return None; return None;
} }
let ix = count - 1 - ix; let ix = count - 1 - ix;
let mut cursor = self.notifications.cursor::<Count>(&()); let mut cursor = self.notifications.cursor::<Count>(());
cursor.seek(&Count(ix), Bias::Right); cursor.seek(&Count(ix), Bias::Right);
cursor.item() cursor.item()
} }
pub fn notification_for_id(&self, id: u64) -> Option<&NotificationEntry> { pub fn notification_for_id(&self, id: u64) -> Option<&NotificationEntry> {
let mut cursor = self.notifications.cursor::<NotificationId>(&()); let mut cursor = self.notifications.cursor::<NotificationId>(());
cursor.seek(&NotificationId(id), Bias::Left); cursor.seek(&NotificationId(id), Bias::Left);
if let Some(item) = cursor.item() if let Some(item) = cursor.item()
&& item.id == id && item.id == id
@@ -297,12 +297,12 @@ impl NotificationStore {
) { ) {
let mut cursor = self let mut cursor = self
.notifications .notifications
.cursor::<Dimensions<NotificationId, Count>>(&()); .cursor::<Dimensions<NotificationId, Count>>(());
let mut new_notifications = SumTree::default(); let mut new_notifications = SumTree::default();
let mut old_range = 0..0; let mut old_range = 0..0;
for (i, (id, new_notification)) in notifications.into_iter().enumerate() { for (i, (id, new_notification)) in notifications.into_iter().enumerate() {
new_notifications.append(cursor.slice(&NotificationId(id), Bias::Left), &()); new_notifications.append(cursor.slice(&NotificationId(id), Bias::Left), ());
if i == 0 { if i == 0 {
old_range.start = cursor.start().1.0; old_range.start = cursor.start().1.0;
@@ -334,13 +334,13 @@ impl NotificationStore {
} }
if let Some(notification) = new_notification { if let Some(notification) = new_notification {
new_notifications.push(notification, &()); new_notifications.push(notification, ());
} }
} }
old_range.end = cursor.start().1.0; old_range.end = cursor.start().1.0;
let new_count = new_notifications.summary().count - old_range.start; let new_count = new_notifications.summary().count - old_range.start;
new_notifications.append(cursor.suffix(), &()); new_notifications.append(cursor.suffix(), ());
drop(cursor); drop(cursor);
self.notifications = new_notifications; self.notifications = new_notifications;
@@ -381,7 +381,7 @@ impl EventEmitter<NotificationEvent> for NotificationStore {}
impl sum_tree::Item for NotificationEntry { impl sum_tree::Item for NotificationEntry {
type Summary = NotificationSummary; type Summary = NotificationSummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
NotificationSummary { NotificationSummary {
max_id: self.id, max_id: self.id,
count: 1, count: 1,
@@ -390,14 +390,12 @@ impl sum_tree::Item for NotificationEntry {
} }
} }
impl sum_tree::Summary for NotificationSummary { impl sum_tree::ContextLessSummary for NotificationSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self) {
self.max_id = self.max_id.max(summary.max_id); self.max_id = self.max_id.max(summary.max_id);
self.count += summary.count; self.count += summary.count;
self.unread_count += summary.unread_count; self.unread_count += summary.unread_count;
@@ -405,22 +403,22 @@ impl sum_tree::Summary for NotificationSummary {
} }
impl sum_tree::Dimension<'_, NotificationSummary> for NotificationId { impl sum_tree::Dimension<'_, NotificationSummary> for NotificationId {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &NotificationSummary, _: &()) { fn add_summary(&mut self, summary: &NotificationSummary, _: ()) {
debug_assert!(summary.max_id > self.0); debug_assert!(summary.max_id > self.0);
self.0 = summary.max_id; self.0 = summary.max_id;
} }
} }
impl sum_tree::Dimension<'_, NotificationSummary> for Count { impl sum_tree::Dimension<'_, NotificationSummary> for Count {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &NotificationSummary, _: &()) { fn add_summary(&mut self, summary: &NotificationSummary, _: ()) {
self.0 += summary.count; self.0 += summary.count;
} }
} }
+7 -7
View File
@@ -209,7 +209,7 @@ impl TryFrom<proto::StatusEntry> for StatusEntry {
impl sum_tree::Item for StatusEntry { impl sum_tree::Item for StatusEntry {
type Summary = PathSummary<GitSummary>; type Summary = PathSummary<GitSummary>;
fn summary(&self, _: &<Self::Summary as sum_tree::Summary>::Context) -> Self::Summary { fn summary(&self, _: <Self::Summary as sum_tree::Summary>::Context<'_>) -> Self::Summary {
PathSummary { PathSummary {
max_path: self.repo_path.0.clone(), max_path: self.repo_path.0.clone(),
item_summary: self.status.summary(), item_summary: self.status.summary(),
@@ -2890,7 +2890,7 @@ impl RepositorySnapshot {
pub fn status_for_path(&self, path: &RepoPath) -> Option<StatusEntry> { pub fn status_for_path(&self, path: &RepoPath) -> Option<StatusEntry> {
self.statuses_by_path self.statuses_by_path
.get(&PathKey(path.0.clone()), &()) .get(&PathKey(path.0.clone()), ())
.cloned() .cloned()
} }
@@ -4470,7 +4470,7 @@ impl Repository {
}), }),
) )
.collect::<Vec<_>>(); .collect::<Vec<_>>();
self.snapshot.statuses_by_path.edit(edits, &()); self.snapshot.statuses_by_path.edit(edits, ());
if update.is_last_update { if update.is_last_update {
self.snapshot.scan_id = update.scan_id; self.snapshot.scan_id = update.scan_id;
} }
@@ -4771,7 +4771,7 @@ impl Repository {
.background_spawn(async move { .background_spawn(async move {
let mut changed_path_statuses = Vec::new(); let mut changed_path_statuses = Vec::new();
let prev_statuses = prev_snapshot.statuses_by_path.clone(); let prev_statuses = prev_snapshot.statuses_by_path.clone();
let mut cursor = prev_statuses.cursor::<PathProgress>(&()); let mut cursor = prev_statuses.cursor::<PathProgress>(());
for (repo_path, status) in &*statuses.entries { for (repo_path, status) in &*statuses.entries {
changed_paths.remove(repo_path); changed_paths.remove(repo_path);
@@ -4786,7 +4786,7 @@ impl Repository {
status: *status, status: *status,
})); }));
} }
let mut cursor = prev_statuses.cursor::<PathProgress>(&()); let mut cursor = prev_statuses.cursor::<PathProgress>(());
for path in changed_paths.into_iter() { for path in changed_paths.into_iter() {
if cursor.seek_forward(&PathTarget::Path(&path), Bias::Left) { if cursor.seek_forward(&PathTarget::Path(&path), Bias::Left) {
changed_path_statuses.push(Edit::Remove(PathKey(path.0))); changed_path_statuses.push(Edit::Remove(PathKey(path.0)));
@@ -4803,7 +4803,7 @@ impl Repository {
if !changed_path_statuses.is_empty() { if !changed_path_statuses.is_empty() {
this.snapshot this.snapshot
.statuses_by_path .statuses_by_path
.edit(changed_path_statuses, &()); .edit(changed_path_statuses, ());
this.snapshot.scan_id += 1; this.snapshot.scan_id += 1;
} }
@@ -5072,7 +5072,7 @@ async fn compute_snapshot(
repo_path: repo_path.clone(), repo_path: repo_path.clone(),
status: *status, status: *status,
}), }),
&(), (),
); );
let (merge_details, merge_heads_changed) = let (merge_details, merge_heads_changed) =
MergeDetails::load(&backend, &statuses_by_path, &prev_snapshot).await?; MergeDetails::load(&backend, &statuses_by_path, &prev_snapshot).await?;
@@ -12,7 +12,10 @@ pub struct GitTraversal<'a> {
traversal: Traversal<'a>, traversal: Traversal<'a>,
current_entry_summary: Option<GitSummary>, current_entry_summary: Option<GitSummary>,
repo_root_to_snapshot: BTreeMap<&'a Path, &'a RepositorySnapshot>, repo_root_to_snapshot: BTreeMap<&'a Path, &'a RepositorySnapshot>,
repo_location: Option<(RepositoryId, Cursor<'a, StatusEntry, PathProgress<'a>>)>, repo_location: Option<(
RepositoryId,
Cursor<'a, 'static, StatusEntry, PathProgress<'a>>,
)>,
} }
impl<'a> GitTraversal<'a> { impl<'a> GitTraversal<'a> {
@@ -85,7 +88,7 @@ impl<'a> GitTraversal<'a> {
.map(|(prev_repo_id, _)| *prev_repo_id) .map(|(prev_repo_id, _)| *prev_repo_id)
!= Some(repo.id) != Some(repo.id)
{ {
self.repo_location = Some((repo.id, repo.statuses_by_path.cursor::<PathProgress>(&()))); self.repo_location = Some((repo.id, repo.statuses_by_path.cursor::<PathProgress>(())));
} }
let Some((_, statuses)) = &mut self.repo_location else { let Some((_, statuses)) = &mut self.repo_location else {
+29 -1
View File
@@ -144,7 +144,7 @@ fn rope_benchmarks(c: &mut Criterion) {
group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| { group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {
let rope = generate_random_rope(rng.clone(), *size); let rope = generate_random_rope(rng.clone(), *size);
b.iter_with_large_drop(|| { b.iter(|| {
let chars = rope.chars().count(); let chars = rope.chars().count();
assert!(chars > 0); assert!(chars > 0);
}); });
@@ -190,6 +190,34 @@ fn rope_benchmarks(c: &mut Criterion) {
}); });
} }
group.finish(); group.finish();
let mut group = c.benchmark_group("cursor");
for size in sizes.iter() {
group.throughput(Throughput::Bytes(*size as u64));
group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, &size| {
let rope = generate_random_rope(rng.clone(), *size);
b.iter_batched(
|| {
let mut rng = rng.clone();
let num_points = rope.len() / 10;
let mut points = Vec::new();
for _ in 0..num_points {
points.push(rng.random_range(0..rope.len()));
}
points
},
|offsets| {
for offset in offsets.iter() {
black_box(rope.cursor(*offset));
}
},
BatchSize::SmallInput,
);
});
}
group.finish();
} }
criterion_group!(benches, rope_benchmarks); criterion_group!(benches, rope_benchmarks);
+57 -61
View File
@@ -34,7 +34,7 @@ impl Rope {
if self.chunks.is_empty() { if self.chunks.is_empty() {
return offset == 0; return offset == 0;
} }
let mut cursor = self.chunks.cursor::<usize>(&()); let mut cursor = self.chunks.cursor::<usize>(());
cursor.seek(&offset, Bias::Left); cursor.seek(&offset, Bias::Left);
let chunk_offset = offset - cursor.start(); let chunk_offset = offset - cursor.start();
cursor cursor
@@ -53,7 +53,7 @@ impl Rope {
(u8 as i8) >= -0x40 (u8 as i8) >= -0x40
} }
let mut cursor = self.chunks.cursor::<usize>(&()); let mut cursor = self.chunks.cursor::<usize>(());
cursor.seek(&index, Bias::Left); cursor.seek(&index, Bias::Left);
let chunk_offset = index - cursor.start(); let chunk_offset = index - cursor.start();
let lower_idx = cursor.item().map(|chunk| { let lower_idx = cursor.item().map(|chunk| {
@@ -85,7 +85,7 @@ impl Rope {
(u8 as i8) >= -0x40 (u8 as i8) >= -0x40
} }
let mut cursor = self.chunks.cursor::<usize>(&()); let mut cursor = self.chunks.cursor::<usize>(());
cursor.seek(&index, Bias::Left); cursor.seek(&index, Bias::Left);
let chunk_offset = index - cursor.start(); let chunk_offset = index - cursor.start();
let upper_idx = cursor.item().map(|chunk| { let upper_idx = cursor.item().map(|chunk| {
@@ -110,15 +110,15 @@ impl Rope {
{ {
self.push_chunk(chunk.as_slice()); self.push_chunk(chunk.as_slice());
let mut chunks = rope.chunks.cursor::<()>(&()); let mut chunks = rope.chunks.cursor::<()>(());
chunks.next(); chunks.next();
chunks.next(); chunks.next();
self.chunks.append(chunks.suffix(), &()); self.chunks.append(chunks.suffix(), ());
self.check_invariants(); self.check_invariants();
return; return;
} }
self.chunks.append(rope.chunks.clone(), &()); self.chunks.append(rope.chunks.clone(), ());
self.check_invariants(); self.check_invariants();
} }
@@ -165,7 +165,7 @@ impl Rope {
last_chunk.push_str(suffix); last_chunk.push_str(suffix);
text = remainder; text = remainder;
}, },
&(), (),
); );
if text.len() > 2048 { if text.len() > 2048 {
@@ -190,10 +190,10 @@ impl Rope {
if new_chunks.len() >= PARALLEL_THRESHOLD { if new_chunks.len() >= PARALLEL_THRESHOLD {
self.chunks self.chunks
.par_extend(new_chunks.into_vec().into_par_iter().map(Chunk::new), &()); .par_extend(new_chunks.into_vec().into_par_iter().map(Chunk::new), ());
} else { } else {
self.chunks self.chunks
.extend(new_chunks.into_iter().map(Chunk::new), &()); .extend(new_chunks.into_iter().map(Chunk::new), ());
} }
self.check_invariants(); self.check_invariants();
@@ -234,10 +234,10 @@ impl Rope {
if new_chunks.len() >= PARALLEL_THRESHOLD { if new_chunks.len() >= PARALLEL_THRESHOLD {
self.chunks self.chunks
.par_extend(new_chunks.into_par_iter().map(Chunk::new), &()); .par_extend(new_chunks.into_par_iter().map(Chunk::new), ());
} else { } else {
self.chunks self.chunks
.extend(new_chunks.into_iter().map(Chunk::new), &()); .extend(new_chunks.into_iter().map(Chunk::new), ());
} }
self.check_invariants(); self.check_invariants();
@@ -263,11 +263,11 @@ impl Rope {
last_chunk.append(suffix); last_chunk.append(suffix);
chunk = remainder; chunk = remainder;
}, },
&(), (),
); );
if !chunk.is_empty() { if !chunk.is_empty() {
self.chunks.push(chunk.into(), &()); self.chunks.push(chunk.into(), ());
} }
} }
@@ -281,7 +281,7 @@ impl Rope {
{ {
// Ensure all chunks except maybe the last one are not underflowing. // Ensure all chunks except maybe the last one are not underflowing.
// Allow some wiggle room for multibyte characters at chunk boundaries. // Allow some wiggle room for multibyte characters at chunk boundaries.
let mut chunks = self.chunks.cursor::<()>(&()).peekable(); let mut chunks = self.chunks.cursor::<()>(()).peekable();
while let Some(chunk) = chunks.next() { while let Some(chunk) = chunks.next() {
if chunks.peek().is_some() { if chunks.peek().is_some() {
assert!(chunk.text.len() + 3 >= chunk::MIN_BASE); assert!(chunk.text.len() + 3 >= chunk::MIN_BASE);
@@ -295,7 +295,7 @@ impl Rope {
} }
pub fn len(&self) -> usize { pub fn len(&self) -> usize {
self.chunks.extent(&()) self.chunks.extent(())
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
@@ -303,11 +303,11 @@ impl Rope {
} }
pub fn max_point(&self) -> Point { pub fn max_point(&self) -> Point {
self.chunks.extent(&()) self.chunks.extent(())
} }
pub fn max_point_utf16(&self) -> PointUtf16 { pub fn max_point_utf16(&self) -> PointUtf16 {
self.chunks.extent(&()) self.chunks.extent(())
} }
pub fn cursor(&self, offset: usize) -> Cursor<'_> { pub fn cursor(&self, offset: usize) -> Cursor<'_> {
@@ -351,7 +351,7 @@ impl Rope {
if offset >= self.summary().len { if offset >= self.summary().len {
return self.summary().len_utf16; return self.summary().len_utf16;
} }
let mut cursor = self.chunks.cursor::<Dimensions<usize, OffsetUtf16>>(&()); let mut cursor = self.chunks.cursor::<Dimensions<usize, OffsetUtf16>>(());
cursor.seek(&offset, Bias::Left); cursor.seek(&offset, Bias::Left);
let overshoot = offset - cursor.start().0; let overshoot = offset - cursor.start().0;
cursor.start().1 cursor.start().1
@@ -364,7 +364,7 @@ impl Rope {
if offset >= self.summary().len_utf16 { if offset >= self.summary().len_utf16 {
return self.summary().len; return self.summary().len;
} }
let mut cursor = self.chunks.cursor::<Dimensions<OffsetUtf16, usize>>(&()); let mut cursor = self.chunks.cursor::<Dimensions<OffsetUtf16, usize>>(());
cursor.seek(&offset, Bias::Left); cursor.seek(&offset, Bias::Left);
let overshoot = offset - cursor.start().0; let overshoot = offset - cursor.start().0;
cursor.start().1 cursor.start().1
@@ -377,7 +377,7 @@ impl Rope {
if offset >= self.summary().len { if offset >= self.summary().len {
return self.summary().lines; return self.summary().lines;
} }
let mut cursor = self.chunks.cursor::<Dimensions<usize, Point>>(&()); let mut cursor = self.chunks.cursor::<Dimensions<usize, Point>>(());
cursor.seek(&offset, Bias::Left); cursor.seek(&offset, Bias::Left);
let overshoot = offset - cursor.start().0; let overshoot = offset - cursor.start().0;
cursor.start().1 cursor.start().1
@@ -390,7 +390,7 @@ impl Rope {
if offset >= self.summary().len { if offset >= self.summary().len {
return self.summary().lines_utf16(); return self.summary().lines_utf16();
} }
let mut cursor = self.chunks.cursor::<Dimensions<usize, PointUtf16>>(&()); let mut cursor = self.chunks.cursor::<Dimensions<usize, PointUtf16>>(());
cursor.seek(&offset, Bias::Left); cursor.seek(&offset, Bias::Left);
let overshoot = offset - cursor.start().0; let overshoot = offset - cursor.start().0;
cursor.start().1 cursor.start().1
@@ -403,7 +403,7 @@ impl Rope {
if point >= self.summary().lines { if point >= self.summary().lines {
return self.summary().lines_utf16(); return self.summary().lines_utf16();
} }
let mut cursor = self.chunks.cursor::<Dimensions<Point, PointUtf16>>(&()); let mut cursor = self.chunks.cursor::<Dimensions<Point, PointUtf16>>(());
cursor.seek(&point, Bias::Left); cursor.seek(&point, Bias::Left);
let overshoot = point - cursor.start().0; let overshoot = point - cursor.start().0;
cursor.start().1 cursor.start().1
@@ -416,7 +416,7 @@ impl Rope {
if point >= self.summary().lines { if point >= self.summary().lines {
return self.summary().len; return self.summary().len;
} }
let mut cursor = self.chunks.cursor::<Dimensions<Point, usize>>(&()); let mut cursor = self.chunks.cursor::<Dimensions<Point, usize>>(());
cursor.seek(&point, Bias::Left); cursor.seek(&point, Bias::Left);
let overshoot = point - cursor.start().0; let overshoot = point - cursor.start().0;
cursor.start().1 cursor.start().1
@@ -437,7 +437,7 @@ impl Rope {
if point >= self.summary().lines_utf16() { if point >= self.summary().lines_utf16() {
return self.summary().len; return self.summary().len;
} }
let mut cursor = self.chunks.cursor::<Dimensions<PointUtf16, usize>>(&()); let mut cursor = self.chunks.cursor::<Dimensions<PointUtf16, usize>>(());
cursor.seek(&point, Bias::Left); cursor.seek(&point, Bias::Left);
let overshoot = point - cursor.start().0; let overshoot = point - cursor.start().0;
cursor.start().1 cursor.start().1
@@ -450,7 +450,7 @@ impl Rope {
if point.0 >= self.summary().lines_utf16() { if point.0 >= self.summary().lines_utf16() {
return self.summary().lines; return self.summary().lines;
} }
let mut cursor = self.chunks.cursor::<Dimensions<PointUtf16, Point>>(&()); let mut cursor = self.chunks.cursor::<Dimensions<PointUtf16, Point>>(());
cursor.seek(&point.0, Bias::Left); cursor.seek(&point.0, Bias::Left);
let overshoot = Unclipped(point.0 - cursor.start().0); let overshoot = Unclipped(point.0 - cursor.start().0);
cursor.start().1 cursor.start().1
@@ -467,7 +467,7 @@ impl Rope {
} }
pub fn clip_offset_utf16(&self, offset: OffsetUtf16, bias: Bias) -> OffsetUtf16 { pub fn clip_offset_utf16(&self, offset: OffsetUtf16, bias: Bias) -> OffsetUtf16 {
let mut cursor = self.chunks.cursor::<OffsetUtf16>(&()); let mut cursor = self.chunks.cursor::<OffsetUtf16>(());
cursor.seek(&offset, Bias::Right); cursor.seek(&offset, Bias::Right);
if let Some(chunk) = cursor.item() { if let Some(chunk) = cursor.item() {
let overshoot = offset - cursor.start(); let overshoot = offset - cursor.start();
@@ -478,7 +478,7 @@ impl Rope {
} }
pub fn clip_point(&self, point: Point, bias: Bias) -> Point { pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
let mut cursor = self.chunks.cursor::<Point>(&()); let mut cursor = self.chunks.cursor::<Point>(());
cursor.seek(&point, Bias::Right); cursor.seek(&point, Bias::Right);
if let Some(chunk) = cursor.item() { if let Some(chunk) = cursor.item() {
let overshoot = point - cursor.start(); let overshoot = point - cursor.start();
@@ -489,7 +489,7 @@ impl Rope {
} }
pub fn clip_point_utf16(&self, point: Unclipped<PointUtf16>, bias: Bias) -> PointUtf16 { pub fn clip_point_utf16(&self, point: Unclipped<PointUtf16>, bias: Bias) -> PointUtf16 {
let mut cursor = self.chunks.cursor::<PointUtf16>(&()); let mut cursor = self.chunks.cursor::<PointUtf16>(());
cursor.seek(&point.0, Bias::Right); cursor.seek(&point.0, Bias::Right);
if let Some(chunk) = cursor.item() { if let Some(chunk) = cursor.item() {
let overshoot = Unclipped(point.0 - cursor.start()); let overshoot = Unclipped(point.0 - cursor.start());
@@ -564,13 +564,13 @@ impl fmt::Debug for Rope {
pub struct Cursor<'a> { pub struct Cursor<'a> {
rope: &'a Rope, rope: &'a Rope,
chunks: sum_tree::Cursor<'a, Chunk, usize>, chunks: sum_tree::Cursor<'a, 'static, Chunk, usize>,
offset: usize, offset: usize,
} }
impl<'a> Cursor<'a> { impl<'a> Cursor<'a> {
pub fn new(rope: &'a Rope, offset: usize) -> Self { pub fn new(rope: &'a Rope, offset: usize) -> Self {
let mut chunks = rope.chunks.cursor(&()); let mut chunks = rope.chunks.cursor(());
chunks.seek(&offset, Bias::Right); chunks.seek(&offset, Bias::Right);
Self { Self {
rope, rope,
@@ -619,7 +619,7 @@ impl<'a> Cursor<'a> {
pub fn summary<D: TextDimension>(&mut self, end_offset: usize) -> D { pub fn summary<D: TextDimension>(&mut self, end_offset: usize) -> D {
debug_assert!(end_offset >= self.offset); debug_assert!(end_offset >= self.offset);
let mut summary = D::zero(&()); let mut summary = D::zero(());
if let Some(start_chunk) = self.chunks.item() { if let Some(start_chunk) = self.chunks.item() {
let start_ix = self.offset - self.chunks.start(); let start_ix = self.offset - self.chunks.start();
let end_ix = cmp::min(end_offset, self.chunks.end()) - self.chunks.start(); let end_ix = cmp::min(end_offset, self.chunks.end()) - self.chunks.start();
@@ -640,7 +640,7 @@ impl<'a> Cursor<'a> {
} }
pub fn suffix(mut self) -> Rope { pub fn suffix(mut self) -> Rope {
self.slice(self.rope.chunks.extent(&())) self.slice(self.rope.chunks.extent(()))
} }
pub fn offset(&self) -> usize { pub fn offset(&self) -> usize {
@@ -659,7 +659,7 @@ pub struct ChunkBitmaps<'a> {
#[derive(Clone)] #[derive(Clone)]
pub struct Chunks<'a> { pub struct Chunks<'a> {
chunks: sum_tree::Cursor<'a, Chunk, usize>, chunks: sum_tree::Cursor<'a, 'static, Chunk, usize>,
range: Range<usize>, range: Range<usize>,
offset: usize, offset: usize,
reversed: bool, reversed: bool,
@@ -667,7 +667,7 @@ pub struct Chunks<'a> {
impl<'a> Chunks<'a> { impl<'a> Chunks<'a> {
pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self { pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self {
let mut chunks = rope.chunks.cursor(&()); let mut chunks = rope.chunks.cursor(());
let offset = if reversed { let offset = if reversed {
chunks.seek(&range.end, Bias::Left); chunks.seek(&range.end, Bias::Left);
range.end range.end
@@ -994,14 +994,14 @@ impl<'a> Iterator for Chunks<'a> {
} }
pub struct Bytes<'a> { pub struct Bytes<'a> {
chunks: sum_tree::Cursor<'a, Chunk, usize>, chunks: sum_tree::Cursor<'a, 'static, Chunk, usize>,
range: Range<usize>, range: Range<usize>,
reversed: bool, reversed: bool,
} }
impl<'a> Bytes<'a> { impl<'a> Bytes<'a> {
pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self { pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self {
let mut chunks = rope.chunks.cursor(&()); let mut chunks = rope.chunks.cursor(());
if reversed { if reversed {
chunks.seek(&range.end, Bias::Left); chunks.seek(&range.end, Bias::Left);
} else { } else {
@@ -1079,7 +1079,7 @@ pub struct Lines<'a> {
reversed: bool, reversed: bool,
} }
impl Lines<'_> { impl<'a> Lines<'a> {
pub fn next(&mut self) -> Option<&str> { pub fn next(&mut self) -> Option<&str> {
if self.done { if self.done {
return None; return None;
@@ -1144,7 +1144,7 @@ impl Lines<'_> {
impl sum_tree::Item for Chunk { impl sum_tree::Item for Chunk {
type Summary = ChunkSummary; type Summary = ChunkSummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
ChunkSummary { ChunkSummary {
text: self.as_slice().text_summary(), text: self.as_slice().text_summary(),
} }
@@ -1156,14 +1156,12 @@ pub struct ChunkSummary {
text: TextSummary, text: TextSummary,
} }
impl sum_tree::Summary for ChunkSummary { impl sum_tree::ContextLessSummary for ChunkSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self) {
self.text += &summary.text; self.text += &summary.text;
} }
} }
@@ -1273,14 +1271,12 @@ impl<'a> From<&'a str> for TextSummary {
} }
} }
impl sum_tree::Summary for TextSummary { impl sum_tree::ContextLessSummary for TextSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &Self::Context) { fn add_summary(&mut self, summary: &Self) {
*self += summary; *self += summary;
} }
} }
@@ -1359,11 +1355,11 @@ impl<D1: TextDimension, D2: TextDimension> TextDimension for Dimensions<D1, D2,
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for TextSummary { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for TextSummary {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: ()) {
*self += &summary.text; *self += &summary.text;
} }
} }
@@ -1383,11 +1379,11 @@ impl TextDimension for TextSummary {
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for usize { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for usize {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: ()) {
*self += summary.text.len; *self += summary.text.len;
} }
} }
@@ -1407,11 +1403,11 @@ impl TextDimension for usize {
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for OffsetUtf16 { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for OffsetUtf16 {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: ()) {
*self += summary.text.len_utf16; *self += summary.text.len_utf16;
} }
} }
@@ -1431,11 +1427,11 @@ impl TextDimension for OffsetUtf16 {
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for Point { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for Point {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: ()) {
*self += summary.text.lines; *self += summary.text.lines;
} }
} }
@@ -1455,11 +1451,11 @@ impl TextDimension for Point {
} }
impl<'a> sum_tree::Dimension<'a, ChunkSummary> for PointUtf16 { impl<'a> sum_tree::Dimension<'a, ChunkSummary> for PointUtf16 {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: ()) {
*self += summary.text.lines_utf16(); *self += summary.text.lines_utf16();
} }
} }
@@ -1547,14 +1543,14 @@ where
K: sum_tree::Dimension<'a, ChunkSummary>, K: sum_tree::Dimension<'a, ChunkSummary>,
V: sum_tree::Dimension<'a, ChunkSummary>, V: sum_tree::Dimension<'a, ChunkSummary>,
{ {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Self { Self {
key: K::zero(_cx), key: K::zero(_cx),
value: Some(V::zero(_cx)), value: Some(V::zero(_cx)),
} }
} }
fn add_summary(&mut self, summary: &'a ChunkSummary, _cx: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _cx: ()) {
self.key.add_summary(summary, _cx); self.key.add_summary(summary, _cx);
if let Some(value) = &mut self.value { if let Some(value) = &mut self.value {
value.add_summary(summary, _cx); value.add_summary(summary, _cx);
@@ -2233,7 +2229,7 @@ mod tests {
impl Rope { impl Rope {
fn text(&self) -> String { fn text(&self) -> String {
let mut text = String::new(); let mut text = String::new();
for chunk in self.chunks.cursor::<()>(&()) { for chunk in self.chunks.cursor::<()>(()) {
text.push_str(&chunk.text); text.push_str(&chunk.text);
} }
text text
+4 -4
View File
@@ -13,12 +13,12 @@ impl<T> From<T> for Unclipped<T> {
impl<'a, T: sum_tree::Dimension<'a, ChunkSummary>> sum_tree::Dimension<'a, ChunkSummary> impl<'a, T: sum_tree::Dimension<'a, ChunkSummary>> sum_tree::Dimension<'a, ChunkSummary>
for Unclipped<T> for Unclipped<T>
{ {
fn zero(_: &()) -> Self { fn zero(_: ()) -> Self {
Self(T::zero(&())) Self(T::zero(()))
} }
fn add_summary(&mut self, summary: &'a ChunkSummary, _: &()) { fn add_summary(&mut self, summary: &'a ChunkSummary, _: ()) {
self.0.add_summary(summary, &()); self.0.add_summary(summary, ());
} }
} }
+78 -55
View File
@@ -5,10 +5,17 @@ use std::{cmp::Ordering, mem, sync::Arc};
#[derive(Clone)] #[derive(Clone)]
struct StackEntry<'a, T: Item, D> { struct StackEntry<'a, T: Item, D> {
tree: &'a SumTree<T>, tree: &'a SumTree<T>,
index: usize, index: u32,
position: D, position: D,
} }
impl<'a, T: Item, D> StackEntry<'a, T, D> {
#[inline]
fn index(&self) -> usize {
self.index as usize
}
}
impl<T: Item + fmt::Debug, D: fmt::Debug> fmt::Debug for StackEntry<'_, T, D> { impl<T: Item + fmt::Debug, D: fmt::Debug> fmt::Debug for StackEntry<'_, T, D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("StackEntry") f.debug_struct("StackEntry")
@@ -19,16 +26,16 @@ impl<T: Item + fmt::Debug, D: fmt::Debug> fmt::Debug for StackEntry<'_, T, D> {
} }
#[derive(Clone)] #[derive(Clone)]
pub struct Cursor<'a, T: Item, D> { pub struct Cursor<'a, 'b, T: Item, D> {
tree: &'a SumTree<T>, tree: &'a SumTree<T>,
stack: ArrayVec<StackEntry<'a, T, D>, 16>, stack: ArrayVec<StackEntry<'a, T, D>, 16>,
position: D, position: D,
did_seek: bool, did_seek: bool,
at_end: bool, at_end: bool,
cx: &'a <T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'b>,
} }
impl<T: Item + fmt::Debug, D: fmt::Debug> fmt::Debug for Cursor<'_, T, D> impl<T: Item + fmt::Debug, D: fmt::Debug> fmt::Debug for Cursor<'_, '_, T, D>
where where
T::Summary: fmt::Debug, T::Summary: fmt::Debug,
{ {
@@ -48,12 +55,12 @@ pub struct Iter<'a, T: Item> {
stack: ArrayVec<StackEntry<'a, T, ()>, 16>, stack: ArrayVec<StackEntry<'a, T, ()>, 16>,
} }
impl<'a, T, D> Cursor<'a, T, D> impl<'a, 'b, T, D> Cursor<'a, 'b, T, D>
where where
T: Item, T: Item,
D: Dimension<'a, T::Summary>, D: Dimension<'a, T::Summary>,
{ {
pub fn new(tree: &'a SumTree<T>, cx: &'a <T::Summary as Summary>::Context) -> Self { pub fn new(tree: &'a SumTree<T>, cx: <T::Summary as Summary>::Context<'b>) -> Self {
Self { Self {
tree, tree,
stack: ArrayVec::new(), stack: ArrayVec::new(),
@@ -93,10 +100,10 @@ where
if let Some(entry) = self.stack.last() { if let Some(entry) = self.stack.last() {
match *entry.tree.0 { match *entry.tree.0 {
Node::Leaf { ref items, .. } => { Node::Leaf { ref items, .. } => {
if entry.index == items.len() { if entry.index() == items.len() {
None None
} else { } else {
Some(&items[entry.index]) Some(&items[entry.index()])
} }
} }
_ => unreachable!(), _ => unreachable!(),
@@ -114,10 +121,10 @@ where
Node::Leaf { Node::Leaf {
ref item_summaries, .. ref item_summaries, ..
} => { } => {
if entry.index == item_summaries.len() { if entry.index() == item_summaries.len() {
None None
} else { } else {
Some(&item_summaries[entry.index]) Some(&item_summaries[entry.index()])
} }
} }
_ => unreachable!(), _ => unreachable!(),
@@ -131,7 +138,7 @@ where
pub fn next_item(&self) -> Option<&'a T> { pub fn next_item(&self) -> Option<&'a T> {
self.assert_did_seek(); self.assert_did_seek();
if let Some(entry) = self.stack.last() { if let Some(entry) = self.stack.last() {
if entry.index == entry.tree.0.items().len() - 1 { if entry.index() == entry.tree.0.items().len() - 1 {
if let Some(next_leaf) = self.next_leaf() { if let Some(next_leaf) = self.next_leaf() {
Some(next_leaf.0.items().first().unwrap()) Some(next_leaf.0.items().first().unwrap())
} else { } else {
@@ -139,7 +146,7 @@ where
} }
} else { } else {
match *entry.tree.0 { match *entry.tree.0 {
Node::Leaf { ref items, .. } => Some(&items[entry.index + 1]), Node::Leaf { ref items, .. } => Some(&items[entry.index() + 1]),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@@ -153,11 +160,11 @@ where
#[track_caller] #[track_caller]
fn next_leaf(&self) -> Option<&'a SumTree<T>> { fn next_leaf(&self) -> Option<&'a SumTree<T>> {
for entry in self.stack.iter().rev().skip(1) { for entry in self.stack.iter().rev().skip(1) {
if entry.index < entry.tree.0.child_trees().len() - 1 { if entry.index() < entry.tree.0.child_trees().len() - 1 {
match *entry.tree.0 { match *entry.tree.0 {
Node::Internal { Node::Internal {
ref child_trees, .. ref child_trees, ..
} => return Some(child_trees[entry.index + 1].leftmost_leaf()), } => return Some(child_trees[entry.index() + 1].leftmost_leaf()),
Node::Leaf { .. } => unreachable!(), Node::Leaf { .. } => unreachable!(),
}; };
} }
@@ -169,7 +176,7 @@ where
pub fn prev_item(&self) -> Option<&'a T> { pub fn prev_item(&self) -> Option<&'a T> {
self.assert_did_seek(); self.assert_did_seek();
if let Some(entry) = self.stack.last() { if let Some(entry) = self.stack.last() {
if entry.index == 0 { if entry.index() == 0 {
if let Some(prev_leaf) = self.prev_leaf() { if let Some(prev_leaf) = self.prev_leaf() {
Some(prev_leaf.0.items().last().unwrap()) Some(prev_leaf.0.items().last().unwrap())
} else { } else {
@@ -177,7 +184,7 @@ where
} }
} else { } else {
match *entry.tree.0 { match *entry.tree.0 {
Node::Leaf { ref items, .. } => Some(&items[entry.index - 1]), Node::Leaf { ref items, .. } => Some(&items[entry.index() - 1]),
_ => unreachable!(), _ => unreachable!(),
} }
} }
@@ -191,11 +198,11 @@ where
#[track_caller] #[track_caller]
fn prev_leaf(&self) -> Option<&'a SumTree<T>> { fn prev_leaf(&self) -> Option<&'a SumTree<T>> {
for entry in self.stack.iter().rev().skip(1) { for entry in self.stack.iter().rev().skip(1) {
if entry.index != 0 { if entry.index() != 0 {
match *entry.tree.0 { match *entry.tree.0 {
Node::Internal { Node::Internal {
ref child_trees, .. ref child_trees, ..
} => return Some(child_trees[entry.index - 1].rightmost_leaf()), } => return Some(child_trees[entry.index() - 1].rightmost_leaf()),
Node::Leaf { .. } => unreachable!(), Node::Leaf { .. } => unreachable!(),
}; };
} }
@@ -224,7 +231,7 @@ where
if !self.tree.is_empty() { if !self.tree.is_empty() {
self.stack.push(StackEntry { self.stack.push(StackEntry {
tree: self.tree, tree: self.tree,
index: self.tree.0.child_summaries().len(), index: self.tree.0.child_summaries().len() as u32,
position: D::from_summary(self.tree.summary(), self.cx), position: D::from_summary(self.tree.summary(), self.cx),
}); });
} }
@@ -240,7 +247,7 @@ where
let entry = self.stack.last_mut().unwrap(); let entry = self.stack.last_mut().unwrap();
if !descending { if !descending {
if entry.index == 0 { if entry.index() == 0 {
self.stack.pop(); self.stack.pop();
continue; continue;
} else { } else {
@@ -248,20 +255,20 @@ where
} }
} }
for summary in &entry.tree.0.child_summaries()[..entry.index] { for summary in &entry.tree.0.child_summaries()[..entry.index()] {
self.position.add_summary(summary, self.cx); self.position.add_summary(summary, self.cx);
} }
entry.position = self.position.clone(); entry.position = self.position.clone();
descending = filter_node(&entry.tree.0.child_summaries()[entry.index]); descending = filter_node(&entry.tree.0.child_summaries()[entry.index()]);
match entry.tree.0.as_ref() { match entry.tree.0.as_ref() {
Node::Internal { child_trees, .. } => { Node::Internal { child_trees, .. } => {
if descending { if descending {
let tree = &child_trees[entry.index]; let tree = &child_trees[entry.index()];
self.stack.push(StackEntry { self.stack.push(StackEntry {
position: D::zero(self.cx), position: D::zero(self.cx),
tree, tree,
index: tree.0.child_summaries().len() - 1, index: tree.0.child_summaries().len() as u32 - 1,
}) })
} }
} }
@@ -312,8 +319,8 @@ where
entry.position = self.position.clone(); entry.position = self.position.clone();
} }
while entry.index < child_summaries.len() { while entry.index() < child_summaries.len() {
let next_summary = &child_summaries[entry.index]; let next_summary = &child_summaries[entry.index()];
if filter_node(next_summary) { if filter_node(next_summary) {
break; break;
} else { } else {
@@ -323,18 +330,18 @@ where
} }
} }
child_trees.get(entry.index) child_trees.get(entry.index())
} }
Node::Leaf { item_summaries, .. } => { Node::Leaf { item_summaries, .. } => {
if !descend { if !descend {
let item_summary = &item_summaries[entry.index]; let item_summary = &item_summaries[entry.index()];
entry.index += 1; entry.index += 1;
entry.position.add_summary(item_summary, self.cx); entry.position.add_summary(item_summary, self.cx);
self.position.add_summary(item_summary, self.cx); self.position.add_summary(item_summary, self.cx);
} }
loop { loop {
if let Some(next_item_summary) = item_summaries.get(entry.index) { if let Some(next_item_summary) = item_summaries.get(entry.index()) {
if filter_node(next_item_summary) { if filter_node(next_item_summary) {
return; return;
} else { } else {
@@ -376,7 +383,7 @@ where
} }
} }
impl<'a, T, D> Cursor<'a, T, D> impl<'a, 'b, T, D> Cursor<'a, 'b, T, D>
where where
T: Item, T: Item,
D: Dimension<'a, T::Summary>, D: Dimension<'a, T::Summary>,
@@ -465,9 +472,9 @@ where
entry.position = self.position.clone(); entry.position = self.position.clone();
} }
for (child_tree, child_summary) in child_trees[entry.index..] for (child_tree, child_summary) in child_trees[entry.index()..]
.iter() .iter()
.zip(&child_summaries[entry.index..]) .zip(&child_summaries[entry.index()..])
{ {
let mut child_end = self.position.clone(); let mut child_end = self.position.clone();
child_end.add_summary(child_summary, self.cx); child_end.add_summary(child_summary, self.cx);
@@ -498,9 +505,9 @@ where
} => { } => {
aggregate.begin_leaf(); aggregate.begin_leaf();
for (item, item_summary) in items[entry.index..] for (item, item_summary) in items[entry.index()..]
.iter() .iter()
.zip(&item_summaries[entry.index..]) .zip(&item_summaries[entry.index()..])
{ {
let mut child_end = self.position.clone(); let mut child_end = self.position.clone();
child_end.add_summary(item_summary, self.cx); child_end.add_summary(item_summary, self.cx);
@@ -572,14 +579,14 @@ impl<'a, T: Item> Iterator for Iter<'a, T> {
if !descend { if !descend {
entry.index += 1; entry.index += 1;
} }
child_trees.get(entry.index) child_trees.get(entry.index())
} }
Node::Leaf { items, .. } => { Node::Leaf { items, .. } => {
if !descend { if !descend {
entry.index += 1; entry.index += 1;
} }
if let Some(next_item) = items.get(entry.index) { if let Some(next_item) = items.get(entry.index()) {
return Some(next_item); return Some(next_item);
} else { } else {
None None
@@ -605,7 +612,7 @@ impl<'a, T: Item> Iterator for Iter<'a, T> {
} }
} }
impl<'a, T: Item, D> Iterator for Cursor<'a, T, D> impl<'a, 'b, T: Item, D> Iterator for Cursor<'a, 'b, T, D>
where where
D: Dimension<'a, T::Summary>, D: Dimension<'a, T::Summary>,
{ {
@@ -625,12 +632,12 @@ where
} }
} }
pub struct FilterCursor<'a, F, T: Item, D> { pub struct FilterCursor<'a, 'b, F, T: Item, D> {
cursor: Cursor<'a, T, D>, cursor: Cursor<'a, 'b, T, D>,
filter_node: F, filter_node: F,
} }
impl<'a, F, T: Item, D> FilterCursor<'a, F, T, D> impl<'a, 'b, F, T: Item, D> FilterCursor<'a, 'b, F, T, D>
where where
F: FnMut(&T::Summary) -> bool, F: FnMut(&T::Summary) -> bool,
T: Item, T: Item,
@@ -638,7 +645,7 @@ where
{ {
pub fn new( pub fn new(
tree: &'a SumTree<T>, tree: &'a SumTree<T>,
cx: &'a <T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'b>,
filter_node: F, filter_node: F,
) -> Self { ) -> Self {
let cursor = tree.cursor::<D>(cx); let cursor = tree.cursor::<D>(cx);
@@ -673,7 +680,7 @@ where
} }
} }
impl<'a, F, T: Item, U> Iterator for FilterCursor<'a, F, T, U> impl<'a, 'b, F, T: Item, U> Iterator for FilterCursor<'a, 'b, F, T, U>
where where
F: FnMut(&T::Summary) -> bool, F: FnMut(&T::Summary) -> bool,
U: Dimension<'a, T::Summary>, U: Dimension<'a, T::Summary>,
@@ -696,18 +703,18 @@ where
trait SeekAggregate<'a, T: Item> { trait SeekAggregate<'a, T: Item> {
fn begin_leaf(&mut self); fn begin_leaf(&mut self);
fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context); fn end_leaf(&mut self, cx: <T::Summary as Summary>::Context<'_>);
fn push_item( fn push_item(
&mut self, &mut self,
item: &'a T, item: &'a T,
summary: &'a T::Summary, summary: &'a T::Summary,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
); );
fn push_tree( fn push_tree(
&mut self, &mut self,
tree: &'a SumTree<T>, tree: &'a SumTree<T>,
summary: &'a T::Summary, summary: &'a T::Summary,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
); );
} }
@@ -722,14 +729,20 @@ struct SummarySeekAggregate<D>(D);
impl<T: Item> SeekAggregate<'_, T> for () { impl<T: Item> SeekAggregate<'_, T> for () {
fn begin_leaf(&mut self) {} fn begin_leaf(&mut self) {}
fn end_leaf(&mut self, _: &<T::Summary as Summary>::Context) {} fn end_leaf(&mut self, _: <T::Summary as Summary>::Context<'_>) {}
fn push_item(&mut self, _: &T, _: &T::Summary, _: &<T::Summary as Summary>::Context) {} fn push_item(&mut self, _: &T, _: &T::Summary, _: <T::Summary as Summary>::Context<'_>) {}
fn push_tree(&mut self, _: &SumTree<T>, _: &T::Summary, _: &<T::Summary as Summary>::Context) {} fn push_tree(
&mut self,
_: &SumTree<T>,
_: &T::Summary,
_: <T::Summary as Summary>::Context<'_>,
) {
}
} }
impl<T: Item> SeekAggregate<'_, T> for SliceSeekAggregate<T> { impl<T: Item> SeekAggregate<'_, T> for SliceSeekAggregate<T> {
fn begin_leaf(&mut self) {} fn begin_leaf(&mut self) {}
fn end_leaf(&mut self, cx: &<T::Summary as Summary>::Context) { fn end_leaf(&mut self, cx: <T::Summary as Summary>::Context<'_>) {
self.tree.append( self.tree.append(
SumTree(Arc::new(Node::Leaf { SumTree(Arc::new(Node::Leaf {
summary: mem::replace(&mut self.leaf_summary, <T::Summary as Summary>::zero(cx)), summary: mem::replace(&mut self.leaf_summary, <T::Summary as Summary>::zero(cx)),
@@ -739,7 +752,12 @@ impl<T: Item> SeekAggregate<'_, T> for SliceSeekAggregate<T> {
cx, cx,
); );
} }
fn push_item(&mut self, item: &T, summary: &T::Summary, cx: &<T::Summary as Summary>::Context) { fn push_item(
&mut self,
item: &T,
summary: &T::Summary,
cx: <T::Summary as Summary>::Context<'_>,
) {
self.leaf_items.push(item.clone()); self.leaf_items.push(item.clone());
self.leaf_item_summaries.push(summary.clone()); self.leaf_item_summaries.push(summary.clone());
Summary::add_summary(&mut self.leaf_summary, summary, cx); Summary::add_summary(&mut self.leaf_summary, summary, cx);
@@ -748,7 +766,7 @@ impl<T: Item> SeekAggregate<'_, T> for SliceSeekAggregate<T> {
&mut self, &mut self,
tree: &SumTree<T>, tree: &SumTree<T>,
_: &T::Summary, _: &T::Summary,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
) { ) {
self.tree.append(tree.clone(), cx); self.tree.append(tree.clone(), cx);
} }
@@ -759,15 +777,20 @@ where
D: Dimension<'a, T::Summary>, D: Dimension<'a, T::Summary>,
{ {
fn begin_leaf(&mut self) {} fn begin_leaf(&mut self) {}
fn end_leaf(&mut self, _: &<T::Summary as Summary>::Context) {} fn end_leaf(&mut self, _: <T::Summary as Summary>::Context<'_>) {}
fn push_item(&mut self, _: &T, summary: &'a T::Summary, cx: &<T::Summary as Summary>::Context) { fn push_item(
&mut self,
_: &T,
summary: &'a T::Summary,
cx: <T::Summary as Summary>::Context<'_>,
) {
self.0.add_summary(summary, cx); self.0.add_summary(summary, cx);
} }
fn push_tree( fn push_tree(
&mut self, &mut self,
_: &SumTree<T>, _: &SumTree<T>,
summary: &'a T::Summary, summary: &'a T::Summary,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
) { ) {
self.0.add_summary(summary, cx); self.0.add_summary(summary, cx);
} }
@@ -782,7 +805,7 @@ impl<D> End<D> {
} }
impl<'a, S: Summary, D: Dimension<'a, S>> SeekTarget<'a, S, D> for End<D> { impl<'a, S: Summary, D: Dimension<'a, S>> SeekTarget<'a, S, D> for End<D> {
fn cmp(&self, _: &D, _: &S::Context) -> Ordering { fn cmp(&self, _: &D, _: S::Context<'_>) -> Ordering {
Ordering::Greater Ordering::Greater
} }
} }
+148 -128
View File
@@ -20,7 +20,7 @@ pub const TREE_BASE: usize = 6;
pub trait Item: Clone { pub trait Item: Clone {
type Summary: Summary; type Summary: Summary;
fn summary(&self, cx: &<Self::Summary as Summary>::Context) -> Self::Summary; fn summary(&self, cx: <Self::Summary as Summary>::Context<'_>) -> Self::Summary;
} }
/// An [`Item`] whose summary has a specific key that can be used to identify it /// An [`Item`] whose summary has a specific key that can be used to identify it
@@ -35,23 +35,40 @@ pub trait KeyedItem: Item {
/// Each Summary type can have multiple [`Dimension`]s that it measures, /// Each Summary type can have multiple [`Dimension`]s that it measures,
/// which can be used to navigate the tree /// which can be used to navigate the tree
pub trait Summary: Clone { pub trait Summary: Clone {
type Context; type Context<'a>: Copy;
fn zero<'a>(cx: Self::Context<'a>) -> Self;
fn zero(cx: &Self::Context) -> Self; fn add_summary<'a>(&mut self, summary: &Self, cx: Self::Context<'a>);
fn add_summary(&mut self, summary: &Self, cx: &Self::Context);
} }
/// Catch-all implementation for when you need something that implements [`Summary`] without a specific type. pub trait ContextLessSummary: Clone {
/// We implement it on a &'static, as that avoids blanket impl collisions with `impl<T: Summary> Dimension for T` fn zero() -> Self;
/// (as we also need unit type to be a fill-in dimension) fn add_summary(&mut self, summary: &Self);
impl Summary for &'static () { }
type Context = ();
fn zero(_: &()) -> Self { impl<T: ContextLessSummary> Summary for T {
&() type Context<'a> = ();
fn zero<'a>((): ()) -> Self {
T::zero()
} }
fn add_summary(&mut self, _: &Self, _: &()) {} fn add_summary<'a>(&mut self, summary: &Self, (): ()) {
T::add_summary(self, summary)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct NoSummary;
/// Catch-all implementation for when you need something that implements [`Summary`] without a specific type.
/// We implement it on a `NoSummary` instead of re-using `()`, as that avoids blanket impl collisions with `impl<T: Summary> Dimension for T`
/// (as we also need unit type to be a fill-in dimension)
impl ContextLessSummary for NoSummary {
fn zero() -> Self {
NoSummary
}
fn add_summary(&mut self, _: &Self) {}
} }
/// Each [`Summary`] type can have more than one [`Dimension`] type that it measures. /// Each [`Summary`] type can have more than one [`Dimension`] type that it measures.
@@ -62,11 +79,11 @@ impl Summary for &'static () {
/// Zed's rope has a `TextSummary` type that summarizes lines, characters, and bytes. /// Zed's rope has a `TextSummary` type that summarizes lines, characters, and bytes.
/// Each of these are different dimensions we may want to seek to /// Each of these are different dimensions we may want to seek to
pub trait Dimension<'a, S: Summary>: Clone { pub trait Dimension<'a, S: Summary>: Clone {
fn zero(cx: &S::Context) -> Self; fn zero(cx: S::Context<'_>) -> Self;
fn add_summary(&mut self, summary: &'a S, cx: &S::Context); fn add_summary(&mut self, summary: &'a S, cx: S::Context<'_>);
fn from_summary(summary: &'a S, cx: &S::Context) -> Self { fn from_summary(summary: &'a S, cx: S::Context<'_>) -> Self {
let mut dimension = Self::zero(cx); let mut dimension = Self::zero(cx);
dimension.add_summary(summary, cx); dimension.add_summary(summary, cx);
dimension dimension
@@ -74,29 +91,29 @@ pub trait Dimension<'a, S: Summary>: Clone {
} }
impl<'a, T: Summary> Dimension<'a, T> for T { impl<'a, T: Summary> Dimension<'a, T> for T {
fn zero(cx: &T::Context) -> Self { fn zero(cx: T::Context<'_>) -> Self {
Summary::zero(cx) Summary::zero(cx)
} }
fn add_summary(&mut self, summary: &'a T, cx: &T::Context) { fn add_summary(&mut self, summary: &'a T, cx: T::Context<'_>) {
Summary::add_summary(self, summary, cx); Summary::add_summary(self, summary, cx);
} }
} }
pub trait SeekTarget<'a, S: Summary, D: Dimension<'a, S>> { pub trait SeekTarget<'a, S: Summary, D: Dimension<'a, S>> {
fn cmp(&self, cursor_location: &D, cx: &S::Context) -> Ordering; fn cmp(&self, cursor_location: &D, cx: S::Context<'_>) -> Ordering;
} }
impl<'a, S: Summary, D: Dimension<'a, S> + Ord> SeekTarget<'a, S, D> for D { impl<'a, S: Summary, D: Dimension<'a, S> + Ord> SeekTarget<'a, S, D> for D {
fn cmp(&self, cursor_location: &Self, _: &S::Context) -> Ordering { fn cmp(&self, cursor_location: &Self, _: S::Context<'_>) -> Ordering {
Ord::cmp(self, cursor_location) Ord::cmp(self, cursor_location)
} }
} }
impl<'a, T: Summary> Dimension<'a, T> for () { impl<'a, T: Summary> Dimension<'a, T> for () {
fn zero(_: &T::Context) -> Self {} fn zero(_: T::Context<'_>) -> Self {}
fn add_summary(&mut self, _: &'a T, _: &T::Context) {} fn add_summary(&mut self, _: &'a T, _: T::Context<'_>) {}
} }
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
@@ -105,11 +122,11 @@ pub struct Dimensions<D1, D2, D3 = ()>(pub D1, pub D2, pub D3);
impl<'a, T: Summary, D1: Dimension<'a, T>, D2: Dimension<'a, T>, D3: Dimension<'a, T>> impl<'a, T: Summary, D1: Dimension<'a, T>, D2: Dimension<'a, T>, D3: Dimension<'a, T>>
Dimension<'a, T> for Dimensions<D1, D2, D3> Dimension<'a, T> for Dimensions<D1, D2, D3>
{ {
fn zero(cx: &T::Context) -> Self { fn zero(cx: T::Context<'_>) -> Self {
Dimensions(D1::zero(cx), D2::zero(cx), D3::zero(cx)) Dimensions(D1::zero(cx), D2::zero(cx), D3::zero(cx))
} }
fn add_summary(&mut self, summary: &'a T, cx: &T::Context) { fn add_summary(&mut self, summary: &'a T, cx: T::Context<'_>) {
self.0.add_summary(summary, cx); self.0.add_summary(summary, cx);
self.1.add_summary(summary, cx); self.1.add_summary(summary, cx);
self.2.add_summary(summary, cx); self.2.add_summary(summary, cx);
@@ -123,7 +140,7 @@ where
D2: Dimension<'a, S>, D2: Dimension<'a, S>,
D3: Dimension<'a, S>, D3: Dimension<'a, S>,
{ {
fn cmp(&self, cursor_location: &Dimensions<D1, D2, D3>, cx: &S::Context) -> Ordering { fn cmp(&self, cursor_location: &Dimensions<D1, D2, D3>, cx: S::Context<'_>) -> Ordering {
self.cmp(&cursor_location.0, cx) self.cmp(&cursor_location.0, cx)
} }
} }
@@ -187,7 +204,7 @@ where
} }
impl<T: Item> SumTree<T> { impl<T: Item> SumTree<T> {
pub fn new(cx: &<T::Summary as Summary>::Context) -> Self { pub fn new(cx: <T::Summary as Summary>::Context<'_>) -> Self {
SumTree(Arc::new(Node::Leaf { SumTree(Arc::new(Node::Leaf {
summary: <T::Summary as Summary>::zero(cx), summary: <T::Summary as Summary>::zero(cx),
items: ArrayVec::new(), items: ArrayVec::new(),
@@ -204,7 +221,7 @@ impl<T: Item> SumTree<T> {
})) }))
} }
pub fn from_item(item: T, cx: &<T::Summary as Summary>::Context) -> Self { pub fn from_item(item: T, cx: <T::Summary as Summary>::Context<'_>) -> Self {
let mut tree = Self::new(cx); let mut tree = Self::new(cx);
tree.push(item, cx); tree.push(item, cx);
tree tree
@@ -212,7 +229,7 @@ impl<T: Item> SumTree<T> {
pub fn from_iter<I: IntoIterator<Item = T>>( pub fn from_iter<I: IntoIterator<Item = T>>(
iter: I, iter: I,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
) -> Self { ) -> Self {
let mut nodes = Vec::new(); let mut nodes = Vec::new();
@@ -276,13 +293,13 @@ impl<T: Item> SumTree<T> {
} }
} }
pub fn from_par_iter<I, Iter>(iter: I, cx: &<T::Summary as Summary>::Context) -> Self pub fn from_par_iter<I, Iter>(iter: I, cx: <T::Summary as Summary>::Context<'_>) -> Self
where where
I: IntoParallelIterator<Iter = Iter>, I: IntoParallelIterator<Iter = Iter>,
Iter: IndexedParallelIterator<Item = T>, Iter: IndexedParallelIterator<Item = T>,
T: Send + Sync, T: Send + Sync,
T::Summary: Send + Sync, T::Summary: Send + Sync,
<T::Summary as Summary>::Context: Sync, for<'a> <T::Summary as Summary>::Context<'a>: Sync,
{ {
let mut nodes = iter let mut nodes = iter
.into_par_iter() .into_par_iter()
@@ -339,7 +356,7 @@ impl<T: Item> SumTree<T> {
} }
#[allow(unused)] #[allow(unused)]
pub fn items(&self, cx: &<T::Summary as Summary>::Context) -> Vec<T> { pub fn items<'a>(&'a self, cx: <T::Summary as Summary>::Context<'a>) -> Vec<T> {
let mut items = Vec::new(); let mut items = Vec::new();
let mut cursor = self.cursor::<()>(cx); let mut cursor = self.cursor::<()>(cx);
cursor.next(); cursor.next();
@@ -354,7 +371,10 @@ impl<T: Item> SumTree<T> {
Iter::new(self) Iter::new(self)
} }
pub fn cursor<'a, S>(&'a self, cx: &'a <T::Summary as Summary>::Context) -> Cursor<'a, T, S> pub fn cursor<'a, 'b, S>(
&'a self,
cx: <T::Summary as Summary>::Context<'b>,
) -> Cursor<'a, 'b, T, S>
where where
S: Dimension<'a, T::Summary>, S: Dimension<'a, T::Summary>,
{ {
@@ -363,11 +383,11 @@ impl<T: Item> SumTree<T> {
/// Note: If the summary type requires a non `()` context, then the filter cursor /// Note: If the summary type requires a non `()` context, then the filter cursor
/// that is returned cannot be used with Rust's iterators. /// that is returned cannot be used with Rust's iterators.
pub fn filter<'a, F, U>( pub fn filter<'a, 'b, F, U>(
&'a self, &'a self,
cx: &'a <T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'b>,
filter_node: F, filter_node: F,
) -> FilterCursor<'a, F, T, U> ) -> FilterCursor<'a, 'b, F, T, U>
where where
F: FnMut(&T::Summary) -> bool, F: FnMut(&T::Summary) -> bool,
U: Dimension<'a, T::Summary>, U: Dimension<'a, T::Summary>,
@@ -384,14 +404,18 @@ impl<T: Item> SumTree<T> {
self.rightmost_leaf().0.items().last() self.rightmost_leaf().0.items().last()
} }
pub fn update_last(&mut self, f: impl FnOnce(&mut T), cx: &<T::Summary as Summary>::Context) { pub fn update_last(
&mut self,
f: impl FnOnce(&mut T),
cx: <T::Summary as Summary>::Context<'_>,
) {
self.update_last_recursive(f, cx); self.update_last_recursive(f, cx);
} }
fn update_last_recursive( fn update_last_recursive(
&mut self, &mut self,
f: impl FnOnce(&mut T), f: impl FnOnce(&mut T),
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
) -> Option<T::Summary> { ) -> Option<T::Summary> {
match Arc::make_mut(&mut self.0) { match Arc::make_mut(&mut self.0) {
Node::Internal { Node::Internal {
@@ -426,7 +450,7 @@ impl<T: Item> SumTree<T> {
pub fn extent<'a, D: Dimension<'a, T::Summary>>( pub fn extent<'a, D: Dimension<'a, T::Summary>>(
&'a self, &'a self,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
) -> D { ) -> D {
let mut extent = D::zero(cx); let mut extent = D::zero(cx);
match self.0.as_ref() { match self.0.as_ref() {
@@ -451,25 +475,25 @@ impl<T: Item> SumTree<T> {
} }
} }
pub fn extend<I>(&mut self, iter: I, cx: &<T::Summary as Summary>::Context) pub fn extend<I>(&mut self, iter: I, cx: <T::Summary as Summary>::Context<'_>)
where where
I: IntoIterator<Item = T>, I: IntoIterator<Item = T>,
{ {
self.append(Self::from_iter(iter, cx), cx); self.append(Self::from_iter(iter, cx), cx);
} }
pub fn par_extend<I, Iter>(&mut self, iter: I, cx: &<T::Summary as Summary>::Context) pub fn par_extend<I, Iter>(&mut self, iter: I, cx: <T::Summary as Summary>::Context<'_>)
where where
I: IntoParallelIterator<Iter = Iter>, I: IntoParallelIterator<Iter = Iter>,
Iter: IndexedParallelIterator<Item = T>, Iter: IndexedParallelIterator<Item = T>,
T: Send + Sync, T: Send + Sync,
T::Summary: Send + Sync, T::Summary: Send + Sync,
<T::Summary as Summary>::Context: Sync, for<'a> <T::Summary as Summary>::Context<'a>: Sync,
{ {
self.append(Self::from_par_iter(iter, cx), cx); self.append(Self::from_par_iter(iter, cx), cx);
} }
pub fn push(&mut self, item: T, cx: &<T::Summary as Summary>::Context) { pub fn push(&mut self, item: T, cx: <T::Summary as Summary>::Context<'_>) {
let summary = item.summary(cx); let summary = item.summary(cx);
self.append( self.append(
SumTree(Arc::new(Node::Leaf { SumTree(Arc::new(Node::Leaf {
@@ -481,7 +505,7 @@ impl<T: Item> SumTree<T> {
); );
} }
pub fn append(&mut self, other: Self, cx: &<T::Summary as Summary>::Context) { pub fn append(&mut self, other: Self, cx: <T::Summary as Summary>::Context<'_>) {
if self.is_empty() { if self.is_empty() {
*self = other; *self = other;
} else if !other.0.is_leaf() || !other.0.items().is_empty() { } else if !other.0.is_leaf() || !other.0.items().is_empty() {
@@ -498,7 +522,7 @@ impl<T: Item> SumTree<T> {
fn push_tree_recursive( fn push_tree_recursive(
&mut self, &mut self,
other: SumTree<T>, other: SumTree<T>,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
) -> Option<SumTree<T>> { ) -> Option<SumTree<T>> {
match Arc::make_mut(&mut self.0) { match Arc::make_mut(&mut self.0) {
Node::Internal { Node::Internal {
@@ -618,7 +642,7 @@ impl<T: Item> SumTree<T> {
fn from_child_trees( fn from_child_trees(
left: SumTree<T>, left: SumTree<T>,
right: SumTree<T>, right: SumTree<T>,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
) -> Self { ) -> Self {
let height = left.0.height() + 1; let height = left.0.height() + 1;
let mut child_summaries = ArrayVec::new(); let mut child_summaries = ArrayVec::new();
@@ -663,13 +687,13 @@ impl<T: Item + PartialEq> PartialEq for SumTree<T> {
impl<T: Item + Eq> Eq for SumTree<T> {} impl<T: Item + Eq> Eq for SumTree<T> {}
impl<T: KeyedItem> SumTree<T> { impl<T: KeyedItem> SumTree<T> {
pub fn insert_or_replace( pub fn insert_or_replace<'a, 'b>(
&mut self, &'a mut self,
item: T, item: T,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'b>,
) -> Option<T> { ) -> Option<T> {
let mut replaced = None; let mut replaced = None;
*self = { {
let mut cursor = self.cursor::<T::Key>(cx); let mut cursor = self.cursor::<T::Key>(cx);
let mut new_tree = cursor.slice(&item.key(), Bias::Left); let mut new_tree = cursor.slice(&item.key(), Bias::Left);
if let Some(cursor_item) = cursor.item() if let Some(cursor_item) = cursor.item()
@@ -680,12 +704,13 @@ impl<T: KeyedItem> SumTree<T> {
} }
new_tree.push(item, cx); new_tree.push(item, cx);
new_tree.append(cursor.suffix(), cx); new_tree.append(cursor.suffix(), cx);
new_tree drop(cursor);
*self = new_tree
}; };
replaced replaced
} }
pub fn remove(&mut self, key: &T::Key, cx: &<T::Summary as Summary>::Context) -> Option<T> { pub fn remove(&mut self, key: &T::Key, cx: <T::Summary as Summary>::Context<'_>) -> Option<T> {
let mut removed = None; let mut removed = None;
*self = { *self = {
let mut cursor = self.cursor::<T::Key>(cx); let mut cursor = self.cursor::<T::Key>(cx);
@@ -705,7 +730,7 @@ impl<T: KeyedItem> SumTree<T> {
pub fn edit( pub fn edit(
&mut self, &mut self,
mut edits: Vec<Edit<T>>, mut edits: Vec<Edit<T>>,
cx: &<T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'_>,
) -> Vec<T> { ) -> Vec<T> {
if edits.is_empty() { if edits.is_empty() {
return Vec::new(); return Vec::new();
@@ -760,7 +785,7 @@ impl<T: KeyedItem> SumTree<T> {
pub fn get<'a>( pub fn get<'a>(
&'a self, &'a self,
key: &T::Key, key: &T::Key,
cx: &'a <T::Summary as Summary>::Context, cx: <T::Summary as Summary>::Context<'a>,
) -> Option<&'a T> { ) -> Option<&'a T> {
let mut cursor = self.cursor::<T::Key>(cx); let mut cursor = self.cursor::<T::Key>(cx);
if cursor.seek(key, Bias::Left) { if cursor.seek(key, Bias::Left) {
@@ -774,10 +799,10 @@ impl<T: KeyedItem> SumTree<T> {
impl<T, S> Default for SumTree<T> impl<T, S> Default for SumTree<T>
where where
T: Item<Summary = S>, T: Item<Summary = S>,
S: Summary<Context = ()>, S: for<'a> Summary<Context<'a> = ()>,
{ {
fn default() -> Self { fn default() -> Self {
Self::new(&()) Self::new(())
} }
} }
@@ -894,7 +919,7 @@ impl<T: KeyedItem> Edit<T> {
} }
} }
fn sum<'a, T, I>(iter: I, cx: &T::Context) -> T fn sum<'a, T, I>(iter: I, cx: T::Context<'_>) -> T
where where
T: 'a + Summary, T: 'a + Summary,
I: Iterator<Item = &'a T>, I: Iterator<Item = &'a T>,
@@ -920,16 +945,13 @@ mod tests {
#[test] #[test]
fn test_extend_and_push_tree() { fn test_extend_and_push_tree() {
let mut tree1 = SumTree::default(); let mut tree1 = SumTree::default();
tree1.extend(0..20, &()); tree1.extend(0..20, ());
let mut tree2 = SumTree::default(); let mut tree2 = SumTree::default();
tree2.extend(50..100, &()); tree2.extend(50..100, ());
tree1.append(tree2, &()); tree1.append(tree2, ());
assert_eq!( assert_eq!(tree1.items(()), (0..20).chain(50..100).collect::<Vec<u8>>());
tree1.items(&()),
(0..20).chain(50..100).collect::<Vec<u8>>()
);
} }
#[test] #[test]
@@ -953,53 +975,53 @@ mod tests {
let mut tree = SumTree::<u8>::default(); let mut tree = SumTree::<u8>::default();
let count = rng.random_range(0..10); let count = rng.random_range(0..10);
if rng.random() { if rng.random() {
tree.extend(rng.sample_iter(StandardUniform).take(count), &()); tree.extend(rng.sample_iter(StandardUniform).take(count), ());
} else { } else {
let items = rng let items = rng
.sample_iter(StandardUniform) .sample_iter(StandardUniform)
.take(count) .take(count)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
tree.par_extend(items, &()); tree.par_extend(items, ());
} }
for _ in 0..num_operations { for _ in 0..num_operations {
let splice_end = rng.random_range(0..tree.extent::<Count>(&()).0 + 1); let splice_end = rng.random_range(0..tree.extent::<Count>(()).0 + 1);
let splice_start = rng.random_range(0..splice_end + 1); let splice_start = rng.random_range(0..splice_end + 1);
let count = rng.random_range(0..10); let count = rng.random_range(0..10);
let tree_end = tree.extent::<Count>(&()); let tree_end = tree.extent::<Count>(());
let new_items = rng let new_items = rng
.sample_iter(StandardUniform) .sample_iter(StandardUniform)
.take(count) .take(count)
.collect::<Vec<u8>>(); .collect::<Vec<u8>>();
let mut reference_items = tree.items(&()); let mut reference_items = tree.items(());
reference_items.splice(splice_start..splice_end, new_items.clone()); reference_items.splice(splice_start..splice_end, new_items.clone());
tree = { tree = {
let mut cursor = tree.cursor::<Count>(&()); let mut cursor = tree.cursor::<Count>(());
let mut new_tree = cursor.slice(&Count(splice_start), Bias::Right); let mut new_tree = cursor.slice(&Count(splice_start), Bias::Right);
if rng.random() { if rng.random() {
new_tree.extend(new_items, &()); new_tree.extend(new_items, ());
} else { } else {
new_tree.par_extend(new_items, &()); new_tree.par_extend(new_items, ());
} }
cursor.seek(&Count(splice_end), Bias::Right); cursor.seek(&Count(splice_end), Bias::Right);
new_tree.append(cursor.slice(&tree_end, Bias::Right), &()); new_tree.append(cursor.slice(&tree_end, Bias::Right), ());
new_tree new_tree
}; };
assert_eq!(tree.items(&()), reference_items); assert_eq!(tree.items(()), reference_items);
assert_eq!( assert_eq!(
tree.iter().collect::<Vec<_>>(), tree.iter().collect::<Vec<_>>(),
tree.cursor::<()>(&()).collect::<Vec<_>>() tree.cursor::<()>(()).collect::<Vec<_>>()
); );
log::info!("tree items: {:?}", tree.items(&())); log::info!("tree items: {:?}", tree.items(()));
let mut filter_cursor = let mut filter_cursor =
tree.filter::<_, Count>(&(), |summary| summary.contains_even); tree.filter::<_, Count>((), |summary| summary.contains_even);
let expected_filtered_items = tree let expected_filtered_items = tree
.items(&()) .items(())
.into_iter() .into_iter()
.enumerate() .enumerate()
.filter(|(_, item)| (item & 1) == 0) .filter(|(_, item)| (item & 1) == 0)
@@ -1038,7 +1060,7 @@ mod tests {
assert_eq!(filter_cursor.item(), None); assert_eq!(filter_cursor.item(), None);
let mut before_start = false; let mut before_start = false;
let mut cursor = tree.cursor::<Count>(&()); let mut cursor = tree.cursor::<Count>(());
let start_pos = rng.random_range(0..=reference_items.len()); let start_pos = rng.random_range(0..=reference_items.len());
cursor.seek(&Count(start_pos), Bias::Right); cursor.seek(&Count(start_pos), Bias::Right);
let mut pos = rng.random_range(start_pos..=reference_items.len()); let mut pos = rng.random_range(start_pos..=reference_items.len());
@@ -1084,7 +1106,7 @@ mod tests {
} }
for _ in 0..10 { for _ in 0..10 {
let end = rng.random_range(0..tree.extent::<Count>(&()).0 + 1); let end = rng.random_range(0..tree.extent::<Count>(()).0 + 1);
let start = rng.random_range(0..end + 1); let start = rng.random_range(0..end + 1);
let start_bias = if rng.random() { let start_bias = if rng.random() {
Bias::Left Bias::Left
@@ -1097,7 +1119,7 @@ mod tests {
Bias::Right Bias::Right
}; };
let mut cursor = tree.cursor::<Count>(&()); let mut cursor = tree.cursor::<Count>(());
cursor.seek(&Count(start), start_bias); cursor.seek(&Count(start), start_bias);
let slice = cursor.slice(&Count(end), end_bias); let slice = cursor.slice(&Count(end), end_bias);
@@ -1113,9 +1135,9 @@ mod tests {
fn test_cursor() { fn test_cursor() {
// Empty tree // Empty tree
let tree = SumTree::<u8>::default(); let tree = SumTree::<u8>::default();
let mut cursor = tree.cursor::<IntegersSummary>(&()); let mut cursor = tree.cursor::<IntegersSummary>(());
assert_eq!( assert_eq!(
cursor.slice(&Count(0), Bias::Right).items(&()), cursor.slice(&Count(0), Bias::Right).items(()),
Vec::<u8>::new() Vec::<u8>::new()
); );
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
@@ -1135,10 +1157,10 @@ mod tests {
// Single-element tree // Single-element tree
let mut tree = SumTree::<u8>::default(); let mut tree = SumTree::<u8>::default();
tree.extend(vec![1], &()); tree.extend(vec![1], ());
let mut cursor = tree.cursor::<IntegersSummary>(&()); let mut cursor = tree.cursor::<IntegersSummary>(());
assert_eq!( assert_eq!(
cursor.slice(&Count(0), Bias::Right).items(&()), cursor.slice(&Count(0), Bias::Right).items(()),
Vec::<u8>::new() Vec::<u8>::new()
); );
assert_eq!(cursor.item(), Some(&1)); assert_eq!(cursor.item(), Some(&1));
@@ -1158,8 +1180,8 @@ mod tests {
assert_eq!(cursor.next_item(), None); assert_eq!(cursor.next_item(), None);
assert_eq!(cursor.start().sum, 0); assert_eq!(cursor.start().sum, 0);
let mut cursor = tree.cursor::<IntegersSummary>(&()); let mut cursor = tree.cursor::<IntegersSummary>(());
assert_eq!(cursor.slice(&Count(1), Bias::Right).items(&()), [1]); assert_eq!(cursor.slice(&Count(1), Bias::Right).items(()), [1]);
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&1)); assert_eq!(cursor.prev_item(), Some(&1));
assert_eq!(cursor.next_item(), None); assert_eq!(cursor.next_item(), None);
@@ -1168,8 +1190,8 @@ mod tests {
cursor.seek(&Count(0), Bias::Right); cursor.seek(&Count(0), Bias::Right);
assert_eq!( assert_eq!(
cursor cursor
.slice(&tree.extent::<Count>(&()), Bias::Right) .slice(&tree.extent::<Count>(()), Bias::Right)
.items(&()), .items(()),
[1] [1]
); );
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
@@ -1179,10 +1201,10 @@ mod tests {
// Multiple-element tree // Multiple-element tree
let mut tree = SumTree::default(); let mut tree = SumTree::default();
tree.extend(vec![1, 2, 3, 4, 5, 6], &()); tree.extend(vec![1, 2, 3, 4, 5, 6], ());
let mut cursor = tree.cursor::<IntegersSummary>(&()); let mut cursor = tree.cursor::<IntegersSummary>(());
assert_eq!(cursor.slice(&Count(2), Bias::Right).items(&()), [1, 2]); assert_eq!(cursor.slice(&Count(2), Bias::Right).items(()), [1, 2]);
assert_eq!(cursor.item(), Some(&3)); assert_eq!(cursor.item(), Some(&3));
assert_eq!(cursor.prev_item(), Some(&2)); assert_eq!(cursor.prev_item(), Some(&2));
assert_eq!(cursor.next_item(), Some(&4)); assert_eq!(cursor.next_item(), Some(&4));
@@ -1261,12 +1283,12 @@ mod tests {
assert_eq!(cursor.next_item(), Some(&2)); assert_eq!(cursor.next_item(), Some(&2));
assert_eq!(cursor.start().sum, 0); assert_eq!(cursor.start().sum, 0);
let mut cursor = tree.cursor::<IntegersSummary>(&()); let mut cursor = tree.cursor::<IntegersSummary>(());
assert_eq!( assert_eq!(
cursor cursor
.slice(&tree.extent::<Count>(&()), Bias::Right) .slice(&tree.extent::<Count>(()), Bias::Right)
.items(&()), .items(()),
tree.items(&()) tree.items(())
); );
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
assert_eq!(cursor.prev_item(), Some(&6)); assert_eq!(cursor.prev_item(), Some(&6));
@@ -1276,8 +1298,8 @@ mod tests {
cursor.seek(&Count(3), Bias::Right); cursor.seek(&Count(3), Bias::Right);
assert_eq!( assert_eq!(
cursor cursor
.slice(&tree.extent::<Count>(&()), Bias::Right) .slice(&tree.extent::<Count>(()), Bias::Right)
.items(&()), .items(()),
[4, 5, 6] [4, 5, 6]
); );
assert_eq!(cursor.item(), None); assert_eq!(cursor.item(), None);
@@ -1293,36 +1315,36 @@ mod tests {
// Slicing without resetting starts from where the cursor is parked at. // Slicing without resetting starts from where the cursor is parked at.
cursor.seek(&Count(1), Bias::Right); cursor.seek(&Count(1), Bias::Right);
assert_eq!(cursor.slice(&Count(3), Bias::Right).items(&()), vec![2, 3]); assert_eq!(cursor.slice(&Count(3), Bias::Right).items(()), vec![2, 3]);
assert_eq!(cursor.slice(&Count(6), Bias::Left).items(&()), vec![4, 5]); assert_eq!(cursor.slice(&Count(6), Bias::Left).items(()), vec![4, 5]);
assert_eq!(cursor.slice(&Count(6), Bias::Right).items(&()), vec![6]); assert_eq!(cursor.slice(&Count(6), Bias::Right).items(()), vec![6]);
} }
#[test] #[test]
fn test_edit() { fn test_edit() {
let mut tree = SumTree::<u8>::default(); let mut tree = SumTree::<u8>::default();
let removed = tree.edit(vec![Edit::Insert(1), Edit::Insert(2), Edit::Insert(0)], &()); let removed = tree.edit(vec![Edit::Insert(1), Edit::Insert(2), Edit::Insert(0)], ());
assert_eq!(tree.items(&()), vec![0, 1, 2]); assert_eq!(tree.items(()), vec![0, 1, 2]);
assert_eq!(removed, Vec::<u8>::new()); assert_eq!(removed, Vec::<u8>::new());
assert_eq!(tree.get(&0, &()), Some(&0)); assert_eq!(tree.get(&0, ()), Some(&0));
assert_eq!(tree.get(&1, &()), Some(&1)); assert_eq!(tree.get(&1, ()), Some(&1));
assert_eq!(tree.get(&2, &()), Some(&2)); assert_eq!(tree.get(&2, ()), Some(&2));
assert_eq!(tree.get(&4, &()), None); assert_eq!(tree.get(&4, ()), None);
let removed = tree.edit(vec![Edit::Insert(2), Edit::Insert(4), Edit::Remove(0)], &()); let removed = tree.edit(vec![Edit::Insert(2), Edit::Insert(4), Edit::Remove(0)], ());
assert_eq!(tree.items(&()), vec![1, 2, 4]); assert_eq!(tree.items(()), vec![1, 2, 4]);
assert_eq!(removed, vec![0, 2]); assert_eq!(removed, vec![0, 2]);
assert_eq!(tree.get(&0, &()), None); assert_eq!(tree.get(&0, ()), None);
assert_eq!(tree.get(&1, &()), Some(&1)); assert_eq!(tree.get(&1, ()), Some(&1));
assert_eq!(tree.get(&2, &()), Some(&2)); assert_eq!(tree.get(&2, ()), Some(&2));
assert_eq!(tree.get(&4, &()), Some(&4)); assert_eq!(tree.get(&4, ()), Some(&4));
} }
#[test] #[test]
fn test_from_iter() { fn test_from_iter() {
assert_eq!( assert_eq!(
SumTree::from_iter(0..100, &()).items(&()), SumTree::from_iter(0..100, ()).items(()),
(0..100).collect::<Vec<_>>() (0..100).collect::<Vec<_>>()
); );
@@ -1333,7 +1355,7 @@ mod tests {
ix = (ix + 1) % 2; ix = (ix + 1) % 2;
if ix == 1 { Some(1) } else { None } if ix == 1 { Some(1) } else { None }
}); });
assert_eq!(SumTree::from_iter(iterator, &()).items(&()), vec![1]); assert_eq!(SumTree::from_iter(iterator, ()).items(()), vec![1]);
} }
#[derive(Clone, Default, Debug)] #[derive(Clone, Default, Debug)]
@@ -1353,7 +1375,7 @@ mod tests {
impl Item for u8 { impl Item for u8 {
type Summary = IntegersSummary; type Summary = IntegersSummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
IntegersSummary { IntegersSummary {
count: 1, count: 1,
sum: *self as usize, sum: *self as usize,
@@ -1371,14 +1393,12 @@ mod tests {
} }
} }
impl Summary for IntegersSummary { impl ContextLessSummary for IntegersSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self) {
self.count += other.count; self.count += other.count;
self.sum += other.sum; self.sum += other.sum;
self.contains_even |= other.contains_even; self.contains_even |= other.contains_even;
@@ -1387,37 +1407,37 @@ mod tests {
} }
impl Dimension<'_, IntegersSummary> for u8 { impl Dimension<'_, IntegersSummary> for u8 {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &IntegersSummary, _: &()) { fn add_summary(&mut self, summary: &IntegersSummary, _: ()) {
*self = summary.max; *self = summary.max;
} }
} }
impl Dimension<'_, IntegersSummary> for Count { impl Dimension<'_, IntegersSummary> for Count {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &IntegersSummary, _: &()) { fn add_summary(&mut self, summary: &IntegersSummary, _: ()) {
self.0 += summary.count; self.0 += summary.count;
} }
} }
impl SeekTarget<'_, IntegersSummary, IntegersSummary> for Count { impl SeekTarget<'_, IntegersSummary, IntegersSummary> for Count {
fn cmp(&self, cursor_location: &IntegersSummary, _: &()) -> Ordering { fn cmp(&self, cursor_location: &IntegersSummary, _: ()) -> Ordering {
self.0.cmp(&cursor_location.count) self.0.cmp(&cursor_location.count)
} }
} }
impl Dimension<'_, IntegersSummary> for Sum { impl Dimension<'_, IntegersSummary> for Sum {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &IntegersSummary, _: &()) { fn add_summary(&mut self, summary: &IntegersSummary, _: ()) {
self.0 += summary.sum; self.0 += summary.sum;
} }
} }
+27 -29
View File
@@ -1,6 +1,6 @@
use std::{cmp::Ordering, fmt::Debug}; use std::{cmp::Ordering, fmt::Debug};
use crate::{Bias, Dimension, Edit, Item, KeyedItem, SeekTarget, SumTree, Summary}; use crate::{Bias, ContextLessSummary, Dimension, Edit, Item, KeyedItem, SeekTarget, SumTree};
/// A cheaply-cloneable ordered map based on a [SumTree](crate::SumTree). /// A cheaply-cloneable ordered map based on a [SumTree](crate::SumTree).
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]
@@ -44,7 +44,7 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
entries entries
.into_iter() .into_iter()
.map(|(key, value)| MapEntry { key, value }), .map(|(key, value)| MapEntry { key, value }),
&(), (),
); );
Self(tree) Self(tree)
} }
@@ -54,7 +54,7 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
} }
pub fn get(&self, key: &K) -> Option<&V> { pub fn get(&self, key: &K) -> Option<&V> {
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&()); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(());
cursor.seek(&MapKeyRef(Some(key)), Bias::Left); cursor.seek(&MapKeyRef(Some(key)), Bias::Left);
if let Some(item) = cursor.item() { if let Some(item) = cursor.item() {
if Some(key) == item.key().0.as_ref() { if Some(key) == item.key().0.as_ref() {
@@ -68,7 +68,7 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
} }
pub fn insert(&mut self, key: K, value: V) { pub fn insert(&mut self, key: K, value: V) {
self.0.insert_or_replace(MapEntry { key, value }, &()); self.0.insert_or_replace(MapEntry { key, value }, ());
} }
pub fn extend(&mut self, iter: impl IntoIterator<Item = (K, V)>) { pub fn extend(&mut self, iter: impl IntoIterator<Item = (K, V)>) {
@@ -76,7 +76,7 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
.into_iter() .into_iter()
.map(|(key, value)| Edit::Insert(MapEntry { key, value })) .map(|(key, value)| Edit::Insert(MapEntry { key, value }))
.collect(); .collect();
self.0.edit(edits, &()); self.0.edit(edits, ());
} }
pub fn clear(&mut self) { pub fn clear(&mut self) {
@@ -85,14 +85,14 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
pub fn remove(&mut self, key: &K) -> Option<V> { pub fn remove(&mut self, key: &K) -> Option<V> {
let mut removed = None; let mut removed = None;
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&()); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(());
let key = MapKeyRef(Some(key)); let key = MapKeyRef(Some(key));
let mut new_tree = cursor.slice(&key, Bias::Left); let mut new_tree = cursor.slice(&key, Bias::Left);
if key.cmp(&cursor.end(), &()) == Ordering::Equal { if key.cmp(&cursor.end(), ()) == Ordering::Equal {
removed = Some(cursor.item().unwrap().value.clone()); removed = Some(cursor.item().unwrap().value.clone());
cursor.next(); cursor.next();
} }
new_tree.append(cursor.suffix(), &()); new_tree.append(cursor.suffix(), ());
drop(cursor); drop(cursor);
self.0 = new_tree; self.0 = new_tree;
removed removed
@@ -101,17 +101,17 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
pub fn remove_range(&mut self, start: &impl MapSeekTarget<K>, end: &impl MapSeekTarget<K>) { pub fn remove_range(&mut self, start: &impl MapSeekTarget<K>, end: &impl MapSeekTarget<K>) {
let start = MapSeekTargetAdaptor(start); let start = MapSeekTargetAdaptor(start);
let end = MapSeekTargetAdaptor(end); let end = MapSeekTargetAdaptor(end);
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&()); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(());
let mut new_tree = cursor.slice(&start, Bias::Left); let mut new_tree = cursor.slice(&start, Bias::Left);
cursor.seek(&end, Bias::Left); cursor.seek(&end, Bias::Left);
new_tree.append(cursor.suffix(), &()); new_tree.append(cursor.suffix(), ());
drop(cursor); drop(cursor);
self.0 = new_tree; self.0 = new_tree;
} }
/// Returns the key-value pair with the greatest key less than or equal to the given key. /// Returns the key-value pair with the greatest key less than or equal to the given key.
pub fn closest(&self, key: &K) -> Option<(&K, &V)> { pub fn closest(&self, key: &K) -> Option<(&K, &V)> {
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&()); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(());
let key = MapKeyRef(Some(key)); let key = MapKeyRef(Some(key));
cursor.seek(&key, Bias::Right); cursor.seek(&key, Bias::Right);
cursor.prev(); cursor.prev();
@@ -119,7 +119,7 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
} }
pub fn iter_from<'a>(&'a self, from: &K) -> impl Iterator<Item = (&'a K, &'a V)> + 'a { pub fn iter_from<'a>(&'a self, from: &K) -> impl Iterator<Item = (&'a K, &'a V)> + 'a {
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&()); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(());
let from_key = MapKeyRef(Some(from)); let from_key = MapKeyRef(Some(from));
cursor.seek(&from_key, Bias::Left); cursor.seek(&from_key, Bias::Left);
@@ -130,17 +130,17 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
where where
F: FnOnce(&mut V) -> T, F: FnOnce(&mut V) -> T,
{ {
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&()); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(());
let key = MapKeyRef(Some(key)); let key = MapKeyRef(Some(key));
let mut new_tree = cursor.slice(&key, Bias::Left); let mut new_tree = cursor.slice(&key, Bias::Left);
let mut result = None; let mut result = None;
if key.cmp(&cursor.end(), &()) == Ordering::Equal { if key.cmp(&cursor.end(), ()) == Ordering::Equal {
let mut updated = cursor.item().unwrap().clone(); let mut updated = cursor.item().unwrap().clone();
result = Some(f(&mut updated.value)); result = Some(f(&mut updated.value));
new_tree.push(updated, &()); new_tree.push(updated, ());
cursor.next(); cursor.next();
} }
new_tree.append(cursor.suffix(), &()); new_tree.append(cursor.suffix(), ());
drop(cursor); drop(cursor);
self.0 = new_tree; self.0 = new_tree;
result result
@@ -149,11 +149,11 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
pub fn retain<F: FnMut(&K, &V) -> bool>(&mut self, mut predicate: F) { pub fn retain<F: FnMut(&K, &V) -> bool>(&mut self, mut predicate: F) {
let mut new_map = SumTree::<MapEntry<K, V>>::default(); let mut new_map = SumTree::<MapEntry<K, V>>::default();
let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(&()); let mut cursor = self.0.cursor::<MapKeyRef<'_, K>>(());
cursor.next(); cursor.next();
while let Some(item) = cursor.item() { while let Some(item) = cursor.item() {
if predicate(&item.key, &item.value) { if predicate(&item.key, &item.value) {
new_map.push(item.clone(), &()); new_map.push(item.clone(), ());
} }
cursor.next(); cursor.next();
} }
@@ -189,7 +189,7 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
}) })
.collect(); .collect();
self.0.edit(edits, &()); self.0.edit(edits, ());
} }
} }
@@ -209,7 +209,7 @@ struct MapSeekTargetAdaptor<'a, T>(&'a T);
impl<'a, K: Clone + Ord, T: MapSeekTarget<K>> SeekTarget<'a, MapKey<K>, MapKeyRef<'a, K>> impl<'a, K: Clone + Ord, T: MapSeekTarget<K>> SeekTarget<'a, MapKey<K>, MapKeyRef<'a, K>>
for MapSeekTargetAdaptor<'_, T> for MapSeekTargetAdaptor<'_, T>
{ {
fn cmp(&self, cursor_location: &MapKeyRef<K>, _: &()) -> Ordering { fn cmp(&self, cursor_location: &MapKeyRef<K>, _: ()) -> Ordering {
if let Some(key) = &cursor_location.0 { if let Some(key) = &cursor_location.0 {
MapSeekTarget::cmp_cursor(self.0, key) MapSeekTarget::cmp_cursor(self.0, key)
} else { } else {
@@ -245,7 +245,7 @@ where
{ {
type Summary = MapKey<K>; type Summary = MapKey<K>;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
self.key() self.key()
} }
} }
@@ -262,17 +262,15 @@ where
} }
} }
impl<K> Summary for MapKey<K> impl<K> ContextLessSummary for MapKey<K>
where where
K: Clone, K: Clone,
{ {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self) {
*self = summary.clone() *self = summary.clone()
} }
} }
@@ -281,11 +279,11 @@ impl<'a, K> Dimension<'a, MapKey<K>> for MapKeyRef<'a, K>
where where
K: Clone + Ord, K: Clone + Ord,
{ {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a MapKey<K>, _: &()) { fn add_summary(&mut self, summary: &'a MapKey<K>, _: ()) {
self.0 = summary.0.as_ref(); self.0 = summary.0.as_ref();
} }
} }
@@ -294,7 +292,7 @@ impl<'a, K> SeekTarget<'a, MapKey<K>, MapKeyRef<'a, K>> for MapKeyRef<'_, K>
where where
K: Clone + Ord, K: Clone + Ord,
{ {
fn cmp(&self, cursor_location: &MapKeyRef<K>, _: &()) -> Ordering { fn cmp(&self, cursor_location: &MapKeyRef<K>, _: ()) -> Ordering {
Ord::cmp(&self.0, &cursor_location.0) Ord::cmp(&self.0, &cursor_location.0)
} }
} }
+4 -6
View File
@@ -67,7 +67,7 @@ impl Default for Locator {
impl sum_tree::Item for Locator { impl sum_tree::Item for Locator {
type Summary = Locator; type Summary = Locator;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
self.clone() self.clone()
} }
} }
@@ -80,14 +80,12 @@ impl sum_tree::KeyedItem for Locator {
} }
} }
impl sum_tree::Summary for Locator { impl sum_tree::ContextLessSummary for Locator {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self) {
self.assign(summary); self.assign(summary);
} }
} }
+8 -10
View File
@@ -1,5 +1,5 @@
use std::{fmt::Debug, ops::Add}; use std::{fmt::Debug, ops::Add};
use sum_tree::{Dimension, Edit, Item, KeyedItem, SumTree, Summary}; use sum_tree::{ContextLessSummary, Dimension, Edit, Item, KeyedItem, SumTree};
pub trait Operation: Clone + Debug { pub trait Operation: Clone + Debug {
fn lamport_timestamp(&self) -> clock::Lamport; fn lamport_timestamp(&self) -> clock::Lamport;
@@ -52,7 +52,7 @@ impl<T: Operation> OperationQueue<T> {
ops.into_iter() ops.into_iter()
.map(|op| Edit::Insert(OperationItem(op))) .map(|op| Edit::Insert(OperationItem(op)))
.collect(), .collect(),
&(), (),
); );
} }
@@ -67,14 +67,12 @@ impl<T: Operation> OperationQueue<T> {
} }
} }
impl Summary for OperationSummary { impl ContextLessSummary for OperationSummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, _: &()) { fn add_summary(&mut self, other: &Self) {
assert!(self.key < other.key); assert!(self.key < other.key);
self.key = other.key; self.key = other.key;
self.len += other.len; self.len += other.len;
@@ -94,11 +92,11 @@ impl Add<&Self> for OperationSummary {
} }
impl Dimension<'_, OperationSummary> for OperationKey { impl Dimension<'_, OperationSummary> for OperationKey {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &OperationSummary, _: &()) { fn add_summary(&mut self, summary: &OperationSummary, _: ()) {
assert!(*self <= summary.key); assert!(*self <= summary.key);
*self = summary.key; *self = summary.key;
} }
@@ -107,7 +105,7 @@ impl Dimension<'_, OperationSummary> for OperationKey {
impl<T: Operation> Item for OperationItem<T> { impl<T: Operation> Item for OperationItem<T> {
type Summary = OperationSummary; type Summary = OperationSummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
OperationSummary { OperationSummary {
key: OperationKey::new(self.0.lamport_timestamp()), key: OperationKey::new(self.0.lamport_timestamp()),
len: 1, len: 1,
+23 -25
View File
@@ -482,7 +482,7 @@ impl History {
struct Edits<'a, D: TextDimension, F: FnMut(&FragmentSummary) -> bool> { struct Edits<'a, D: TextDimension, F: FnMut(&FragmentSummary) -> bool> {
visible_cursor: rope::Cursor<'a>, visible_cursor: rope::Cursor<'a>,
deleted_cursor: rope::Cursor<'a>, deleted_cursor: rope::Cursor<'a>,
fragments_cursor: Option<FilterCursor<'a, F, Fragment, FragmentTextSummary>>, fragments_cursor: Option<FilterCursor<'a, 'static, F, Fragment, FragmentTextSummary>>,
undos: &'a UndoMap, undos: &'a UndoMap,
since: &'a clock::Global, since: &'a clock::Global,
old_end: D, old_end: D,
@@ -747,7 +747,7 @@ impl Buffer {
deletions: Default::default(), deletions: Default::default(),
max_undos: Default::default(), max_undos: Default::default(),
}; };
insertions.push(InsertionFragment::new(&fragment), &()); insertions.push(InsertionFragment::new(&fragment), ());
fragments.push(fragment, &None); fragments.push(fragment, &None);
} }
@@ -992,7 +992,7 @@ impl Buffer {
drop(old_fragments); drop(old_fragments);
self.snapshot.fragments = new_fragments; self.snapshot.fragments = new_fragments;
self.snapshot.insertions.edit(new_insertions, &()); self.snapshot.insertions.edit(new_insertions, ());
self.snapshot.visible_text = visible_text; self.snapshot.visible_text = visible_text;
self.snapshot.deleted_text = deleted_text; self.snapshot.deleted_text = deleted_text;
self.subscriptions.publish_mut(&edits_patch); self.subscriptions.publish_mut(&edits_patch);
@@ -1240,7 +1240,7 @@ impl Buffer {
self.snapshot.fragments = new_fragments; self.snapshot.fragments = new_fragments;
self.snapshot.visible_text = visible_text; self.snapshot.visible_text = visible_text;
self.snapshot.deleted_text = deleted_text; self.snapshot.deleted_text = deleted_text;
self.snapshot.insertions.edit(new_insertions, &()); self.snapshot.insertions.edit(new_insertions, ());
self.snapshot.insertion_slices.extend(insertion_slices); self.snapshot.insertion_slices.extend(insertion_slices);
self.subscriptions.publish_mut(&edits_patch) self.subscriptions.publish_mut(&edits_patch)
} }
@@ -1269,7 +1269,7 @@ impl Buffer {
// Get all of the fragments corresponding to these insertion slices. // Get all of the fragments corresponding to these insertion slices.
let mut fragment_ids = Vec::new(); let mut fragment_ids = Vec::new();
let mut insertions_cursor = self.insertions.cursor::<InsertionFragmentKey>(&()); let mut insertions_cursor = self.insertions.cursor::<InsertionFragmentKey>(());
for insertion_slice in &insertion_slices { for insertion_slice in &insertion_slices {
if insertion_slice.insertion_id != insertions_cursor.start().timestamp if insertion_slice.insertion_id != insertions_cursor.start().timestamp
|| insertion_slice.range.start > insertions_cursor.start().split_offset || insertion_slice.range.start > insertions_cursor.start().split_offset
@@ -1597,7 +1597,7 @@ impl Buffer {
}); });
// convert to the desired text dimension. // convert to the desired text dimension.
let mut position = D::zero(&()); let mut position = D::zero(());
let mut rope_cursor = self.visible_text.cursor(0); let mut rope_cursor = self.visible_text.cursor(0);
disjoint_ranges.map(move |range| { disjoint_ranges.map(move |range| {
position.add_assign(&rope_cursor.summary(range.start)); position.add_assign(&rope_cursor.summary(range.start));
@@ -1782,7 +1782,7 @@ impl Buffer {
timestamp: fragment.timestamp, timestamp: fragment.timestamp,
split_offset: fragment.insertion_offset, split_offset: fragment.insertion_offset,
}, },
&(), (),
) )
.unwrap(); .unwrap();
assert_eq!( assert_eq!(
@@ -1793,7 +1793,7 @@ impl Buffer {
} }
let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>(&None); let mut cursor = self.snapshot.fragments.cursor::<Option<&Locator>>(&None);
for insertion_fragment in self.snapshot.insertions.cursor::<()>(&()) { for insertion_fragment in self.snapshot.insertions.cursor::<()>(()) {
cursor.seek(&Some(&insertion_fragment.fragment_id), Bias::Left); cursor.seek(&Some(&insertion_fragment.fragment_id), Bias::Left);
let fragment = cursor.item().unwrap(); let fragment = cursor.item().unwrap();
assert_eq!(insertion_fragment.fragment_id, fragment.id); assert_eq!(insertion_fragment.fragment_id, fragment.id);
@@ -2237,16 +2237,16 @@ impl BufferSnapshot {
A: 'a + IntoIterator<Item = (&'a Anchor, T)>, A: 'a + IntoIterator<Item = (&'a Anchor, T)>,
{ {
let anchors = anchors.into_iter(); let anchors = anchors.into_iter();
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&()); let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(());
let mut fragment_cursor = self let mut fragment_cursor = self
.fragments .fragments
.cursor::<Dimensions<Option<&Locator>, usize>>(&None); .cursor::<Dimensions<Option<&Locator>, usize>>(&None);
let mut text_cursor = self.visible_text.cursor(0); let mut text_cursor = self.visible_text.cursor(0);
let mut position = D::zero(&()); let mut position = D::zero(());
anchors.map(move |(anchor, payload)| { anchors.map(move |(anchor, payload)| {
if *anchor == Anchor::MIN { if *anchor == Anchor::MIN {
return (D::zero(&()), payload); return (D::zero(()), payload);
} else if *anchor == Anchor::MAX { } else if *anchor == Anchor::MAX {
return (D::from_text_summary(&self.visible_text.summary()), payload); return (D::from_text_summary(&self.visible_text.summary()), payload);
} }
@@ -2301,7 +2301,7 @@ impl BufferSnapshot {
timestamp: anchor.timestamp, timestamp: anchor.timestamp,
split_offset: anchor.offset, split_offset: anchor.offset,
}; };
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&()); let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(());
insertion_cursor.seek(&anchor_key, anchor.bias); insertion_cursor.seek(&anchor_key, anchor.bias);
if let Some(insertion) = insertion_cursor.item() { if let Some(insertion) = insertion_cursor.item() {
let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key); let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
@@ -2358,7 +2358,7 @@ impl BufferSnapshot {
timestamp: anchor.timestamp, timestamp: anchor.timestamp,
split_offset: anchor.offset, split_offset: anchor.offset,
}; };
let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(&()); let mut insertion_cursor = self.insertions.cursor::<InsertionFragmentKey>(());
insertion_cursor.seek(&anchor_key, anchor.bias); insertion_cursor.seek(&anchor_key, anchor.bias);
if let Some(insertion) = insertion_cursor.item() { if let Some(insertion) = insertion_cursor.item() {
let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key); let comparison = sum_tree::KeyedItem::key(insertion).cmp(&anchor_key);
@@ -2519,8 +2519,8 @@ impl BufferSnapshot {
fragments_cursor, fragments_cursor,
undos: &self.undo_map, undos: &self.undo_map,
since, since,
old_end: D::zero(&()), old_end: D::zero(()),
new_end: D::zero(&()), new_end: D::zero(()),
range: (start_fragment_id, range.start.offset)..(end_fragment_id, range.end.offset), range: (start_fragment_id, range.start.offset)..(end_fragment_id, range.end.offset),
buffer_id: self.remote_id, buffer_id: self.remote_id,
} }
@@ -2851,13 +2851,13 @@ impl sum_tree::Item for Fragment {
} }
impl sum_tree::Summary for FragmentSummary { impl sum_tree::Summary for FragmentSummary {
type Context = Option<clock::Global>; type Context<'a> = &'a Option<clock::Global>;
fn zero(_cx: &Self::Context) -> Self { fn zero(_cx: Self::Context<'_>) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, other: &Self, _: &Self::Context) { fn add_summary(&mut self, other: &Self, _: Self::Context<'_>) {
self.max_id.assign(&other.max_id); self.max_id.assign(&other.max_id);
self.text.visible += &other.text.visible; self.text.visible += &other.text.visible;
self.text.deleted += &other.text.deleted; self.text.deleted += &other.text.deleted;
@@ -2884,7 +2884,7 @@ impl Default for FragmentSummary {
impl sum_tree::Item for InsertionFragment { impl sum_tree::Item for InsertionFragment {
type Summary = InsertionFragmentKey; type Summary = InsertionFragmentKey;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
InsertionFragmentKey { InsertionFragmentKey {
timestamp: self.timestamp, timestamp: self.timestamp,
split_offset: self.split_offset, split_offset: self.split_offset,
@@ -2896,7 +2896,7 @@ impl sum_tree::KeyedItem for InsertionFragment {
type Key = InsertionFragmentKey; type Key = InsertionFragmentKey;
fn key(&self) -> Self::Key { fn key(&self) -> Self::Key {
sum_tree::Item::summary(self, &()) sum_tree::Item::summary(self, ())
} }
} }
@@ -2914,14 +2914,12 @@ impl InsertionFragment {
} }
} }
impl sum_tree::Summary for InsertionFragmentKey { impl sum_tree::ContextLessSummary for InsertionFragmentKey {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &()) { fn add_summary(&mut self, summary: &Self) {
*self = *summary; *self = *summary;
} }
} }
+7 -9
View File
@@ -11,7 +11,7 @@ struct UndoMapEntry {
impl sum_tree::Item for UndoMapEntry { impl sum_tree::Item for UndoMapEntry {
type Summary = UndoMapKey; type Summary = UndoMapKey;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
self.key self.key
} }
} }
@@ -30,14 +30,12 @@ struct UndoMapKey {
undo_id: clock::Lamport, undo_id: clock::Lamport,
} }
impl sum_tree::Summary for UndoMapKey { impl sum_tree::ContextLessSummary for UndoMapKey {
type Context = (); fn zero() -> Self {
fn zero(_cx: &Self::Context) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &Self::Context) { fn add_summary(&mut self, summary: &Self) {
*self = cmp::max(*self, *summary); *self = cmp::max(*self, *summary);
} }
} }
@@ -60,14 +58,14 @@ impl UndoMap {
}) })
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
self.0.edit(edits, &()); self.0.edit(edits, ());
} }
pub fn is_undone(&self, edit_id: clock::Lamport) -> bool { pub fn is_undone(&self, edit_id: clock::Lamport) -> bool {
self.undo_count(edit_id) % 2 == 1 self.undo_count(edit_id) % 2 == 1
} }
pub fn was_undone(&self, edit_id: clock::Lamport, version: &clock::Global) -> bool { pub fn was_undone(&self, edit_id: clock::Lamport, version: &clock::Global) -> bool {
let mut cursor = self.0.cursor::<UndoMapKey>(&()); let mut cursor = self.0.cursor::<UndoMapKey>(());
cursor.seek( cursor.seek(
&UndoMapKey { &UndoMapKey {
edit_id, edit_id,
@@ -91,7 +89,7 @@ impl UndoMap {
} }
pub fn undo_count(&self, edit_id: clock::Lamport) -> u32 { pub fn undo_count(&self, edit_id: clock::Lamport) -> u32 {
let mut cursor = self.0.cursor::<UndoMapKey>(&()); let mut cursor = self.0.cursor::<UndoMapKey>(());
cursor.seek( cursor.seek(
&UndoMapKey { &UndoMapKey {
edit_id, edit_id,
+78 -82
View File
@@ -391,12 +391,12 @@ struct LocalRepositoryEntry {
} }
impl sum_tree::Item for LocalRepositoryEntry { impl sum_tree::Item for LocalRepositoryEntry {
type Summary = PathSummary<&'static ()>; type Summary = PathSummary<sum_tree::NoSummary>;
fn summary(&self, _: &<Self::Summary as Summary>::Context) -> Self::Summary { fn summary(&self, _: <Self::Summary as Summary>::Context<'_>) -> Self::Summary {
PathSummary { PathSummary {
max_path: self.work_directory.path_key().0, max_path: self.work_directory.path_key().0,
item_summary: &(), item_summary: sum_tree::NoSummary,
} }
} }
} }
@@ -2429,7 +2429,7 @@ impl Snapshot {
} }
pub fn contains_entry(&self, entry_id: ProjectEntryId) -> bool { pub fn contains_entry(&self, entry_id: ProjectEntryId) -> bool {
self.entries_by_id.get(&entry_id, &()).is_some() self.entries_by_id.get(&entry_id, ()).is_some()
} }
fn insert_entry( fn insert_entry(
@@ -2445,30 +2445,30 @@ impl Snapshot {
is_ignored: entry.is_ignored, is_ignored: entry.is_ignored,
scan_id: 0, scan_id: 0,
}, },
&(), (),
); );
if let Some(old_entry) = old_entry { if let Some(old_entry) = old_entry {
self.entries_by_path.remove(&PathKey(old_entry.path), &()); self.entries_by_path.remove(&PathKey(old_entry.path), ());
} }
self.entries_by_path.insert_or_replace(entry.clone(), &()); self.entries_by_path.insert_or_replace(entry.clone(), ());
Ok(entry) Ok(entry)
} }
fn delete_entry(&mut self, entry_id: ProjectEntryId) -> Option<Arc<Path>> { fn delete_entry(&mut self, entry_id: ProjectEntryId) -> Option<Arc<Path>> {
let removed_entry = self.entries_by_id.remove(&entry_id, &())?; let removed_entry = self.entries_by_id.remove(&entry_id, ())?;
self.entries_by_path = { self.entries_by_path = {
let mut cursor = self.entries_by_path.cursor::<TraversalProgress>(&()); let mut cursor = self.entries_by_path.cursor::<TraversalProgress>(());
let mut new_entries_by_path = let mut new_entries_by_path =
cursor.slice(&TraversalTarget::path(&removed_entry.path), Bias::Left); cursor.slice(&TraversalTarget::path(&removed_entry.path), Bias::Left);
while let Some(entry) = cursor.item() { while let Some(entry) = cursor.item() {
if entry.path.starts_with(&removed_entry.path) { if entry.path.starts_with(&removed_entry.path) {
self.entries_by_id.remove(&entry.id, &()); self.entries_by_id.remove(&entry.id, ());
cursor.next(); cursor.next();
} else { } else {
break; break;
} }
} }
new_entries_by_path.append(cursor.suffix(), &()); new_entries_by_path.append(cursor.suffix(), ());
new_entries_by_path new_entries_by_path
}; };
@@ -2511,10 +2511,10 @@ impl Snapshot {
for entry in update.updated_entries { for entry in update.updated_entries {
let entry = Entry::from((&self.root_char_bag, always_included_paths, entry)); let entry = Entry::from((&self.root_char_bag, always_included_paths, entry));
if let Some(PathEntry { path, .. }) = self.entries_by_id.get(&entry.id, &()) { if let Some(PathEntry { path, .. }) = self.entries_by_id.get(&entry.id, ()) {
entries_by_path_edits.push(Edit::Remove(PathKey(path.clone()))); entries_by_path_edits.push(Edit::Remove(PathKey(path.clone())));
} }
if let Some(old_entry) = self.entries_by_path.get(&PathKey(entry.path.clone()), &()) if let Some(old_entry) = self.entries_by_path.get(&PathKey(entry.path.clone()), ())
&& old_entry.id != entry.id && old_entry.id != entry.id
{ {
entries_by_id_edits.push(Edit::Remove(old_entry.id)); entries_by_id_edits.push(Edit::Remove(old_entry.id));
@@ -2528,8 +2528,8 @@ impl Snapshot {
entries_by_path_edits.push(Edit::Insert(entry)); entries_by_path_edits.push(Edit::Insert(entry));
} }
self.entries_by_path.edit(entries_by_path_edits, &()); self.entries_by_path.edit(entries_by_path_edits, ());
self.entries_by_id.edit(entries_by_id_edits, &()); self.entries_by_id.edit(entries_by_id_edits, ());
self.scan_id = update.scan_id as usize; self.scan_id = update.scan_id as usize;
if update.is_last_update { if update.is_last_update {
@@ -2570,7 +2570,7 @@ impl Snapshot {
include_ignored: bool, include_ignored: bool,
start_offset: usize, start_offset: usize,
) -> Traversal<'_> { ) -> Traversal<'_> {
let mut cursor = self.entries_by_path.cursor(&()); let mut cursor = self.entries_by_path.cursor(());
cursor.seek( cursor.seek(
&TraversalTarget::Count { &TraversalTarget::Count {
count: start_offset, count: start_offset,
@@ -2614,7 +2614,7 @@ impl Snapshot {
pub fn paths(&self) -> impl Iterator<Item = &Arc<Path>> { pub fn paths(&self) -> impl Iterator<Item = &Arc<Path>> {
let empty_path = Path::new(""); let empty_path = Path::new("");
self.entries_by_path self.entries_by_path
.cursor::<()>(&()) .cursor::<()>(())
.filter(move |entry| entry.path.as_ref() != empty_path) .filter(move |entry| entry.path.as_ref() != empty_path)
.map(|entry| &entry.path) .map(|entry| &entry.path)
} }
@@ -2633,7 +2633,7 @@ impl Snapshot {
parent_path: &'a Path, parent_path: &'a Path,
options: ChildEntriesOptions, options: ChildEntriesOptions,
) -> ChildEntriesIter<'a> { ) -> ChildEntriesIter<'a> {
let mut cursor = self.entries_by_path.cursor(&()); let mut cursor = self.entries_by_path.cursor(());
cursor.seek(&TraversalTarget::path(parent_path), Bias::Right); cursor.seek(&TraversalTarget::path(parent_path), Bias::Right);
let traversal = Traversal { let traversal = Traversal {
snapshot: self, snapshot: self,
@@ -2683,7 +2683,7 @@ impl Snapshot {
} }
pub fn entry_for_id(&self, id: ProjectEntryId) -> Option<&Entry> { pub fn entry_for_id(&self, id: ProjectEntryId) -> Option<&Entry> {
let entry = self.entries_by_id.get(&id, &())?; let entry = self.entries_by_id.get(&id, ())?;
self.entry_for_path(&entry.path) self.entry_for_path(&entry.path)
} }
@@ -2757,18 +2757,17 @@ impl LocalSnapshot {
} }
if entry.kind == EntryKind::PendingDir if entry.kind == EntryKind::PendingDir
&& let Some(existing_entry) = && let Some(existing_entry) = self.entries_by_path.get(&PathKey(entry.path.clone()), ())
self.entries_by_path.get(&PathKey(entry.path.clone()), &())
{ {
entry.kind = existing_entry.kind; entry.kind = existing_entry.kind;
} }
let scan_id = self.scan_id; let scan_id = self.scan_id;
let removed = self.entries_by_path.insert_or_replace(entry.clone(), &()); let removed = self.entries_by_path.insert_or_replace(entry.clone(), ());
if let Some(removed) = removed if let Some(removed) = removed
&& removed.id != entry.id && removed.id != entry.id
{ {
self.entries_by_id.remove(&removed.id, &()); self.entries_by_id.remove(&removed.id, ());
} }
self.entries_by_id.insert_or_replace( self.entries_by_id.insert_or_replace(
PathEntry { PathEntry {
@@ -2777,7 +2776,7 @@ impl LocalSnapshot {
is_ignored: entry.is_ignored, is_ignored: entry.is_ignored,
scan_id, scan_id,
}, },
&(), (),
); );
entry entry
@@ -2838,7 +2837,7 @@ impl LocalSnapshot {
#[cfg(test)] #[cfg(test)]
fn expanded_entries(&self) -> impl Iterator<Item = &Entry> { fn expanded_entries(&self) -> impl Iterator<Item = &Entry> {
self.entries_by_path self.entries_by_path
.cursor::<()>(&()) .cursor::<()>(())
.filter(|entry| entry.kind == EntryKind::Dir && (entry.is_external || entry.is_ignored)) .filter(|entry| entry.kind == EntryKind::Dir && (entry.is_external || entry.is_ignored))
} }
@@ -2848,11 +2847,11 @@ impl LocalSnapshot {
assert_eq!( assert_eq!(
self.entries_by_path self.entries_by_path
.cursor::<()>(&()) .cursor::<()>(())
.map(|e| (&e.path, e.id)) .map(|e| (&e.path, e.id))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
self.entries_by_id self.entries_by_id
.cursor::<()>(&()) .cursor::<()>(())
.map(|e| (&e.path, e.id)) .map(|e| (&e.path, e.id))
.collect::<collections::BTreeSet<_>>() .collect::<collections::BTreeSet<_>>()
.into_iter() .into_iter()
@@ -2862,7 +2861,7 @@ impl LocalSnapshot {
let mut files = self.files(true, 0); let mut files = self.files(true, 0);
let mut visible_files = self.files(false, 0); let mut visible_files = self.files(false, 0);
for entry in self.entries_by_path.cursor::<()>(&()) { for entry in self.entries_by_path.cursor::<()>(()) {
if entry.is_file() { if entry.is_file() {
assert_eq!(files.next().unwrap().inode, entry.inode); assert_eq!(files.next().unwrap().inode, entry.inode);
if (!entry.is_ignored && !entry.is_external) || entry.is_always_included { if (!entry.is_ignored && !entry.is_external) || entry.is_always_included {
@@ -2890,7 +2889,7 @@ impl LocalSnapshot {
let dfs_paths_via_iter = self let dfs_paths_via_iter = self
.entries_by_path .entries_by_path
.cursor::<()>(&()) .cursor::<()>(())
.map(|e| e.path.as_ref()) .map(|e| e.path.as_ref())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert_eq!(bfs_paths, dfs_paths_via_iter); assert_eq!(bfs_paths, dfs_paths_via_iter);
@@ -2918,7 +2917,7 @@ impl LocalSnapshot {
#[cfg(test)] #[cfg(test)]
pub fn entries_without_ids(&self, include_ignored: bool) -> Vec<(&Path, u64, bool)> { pub fn entries_without_ids(&self, include_ignored: bool) -> Vec<(&Path, u64, bool)> {
let mut paths = Vec::new(); let mut paths = Vec::new();
for entry in self.entries_by_path.cursor::<()>(&()) { for entry in self.entries_by_path.cursor::<()>(()) {
if include_ignored || !entry.is_ignored { if include_ignored || !entry.is_ignored {
paths.push((entry.path.as_ref(), entry.inode, entry.is_ignored)); paths.push((entry.path.as_ref(), entry.inode, entry.is_ignored));
} }
@@ -3012,7 +3011,7 @@ impl BackgroundScannerState {
let mut parent_entry = if let Some(parent_entry) = self let mut parent_entry = if let Some(parent_entry) = self
.snapshot .snapshot
.entries_by_path .entries_by_path
.get(&PathKey(parent_path.clone()), &()) .get(&PathKey(parent_path.clone()), ())
{ {
parent_entry.clone() parent_entry.clone()
} else { } else {
@@ -3053,8 +3052,8 @@ impl BackgroundScannerState {
self.snapshot self.snapshot
.entries_by_path .entries_by_path
.edit(entries_by_path_edits, &()); .edit(entries_by_path_edits, ());
self.snapshot.entries_by_id.edit(entries_by_id_edits, &()); self.snapshot.entries_by_id.edit(entries_by_id_edits, ());
if let Err(ix) = self.changed_paths.binary_search(parent_path) { if let Err(ix) = self.changed_paths.binary_search(parent_path) {
self.changed_paths.insert(ix, parent_path.clone()); self.changed_paths.insert(ix, parent_path.clone());
@@ -3072,15 +3071,15 @@ impl BackgroundScannerState {
let mut cursor = self let mut cursor = self
.snapshot .snapshot
.entries_by_path .entries_by_path
.cursor::<TraversalProgress>(&()); .cursor::<TraversalProgress>(());
new_entries = cursor.slice(&TraversalTarget::path(path), Bias::Left); new_entries = cursor.slice(&TraversalTarget::path(path), Bias::Left);
removed_entries = cursor.slice(&TraversalTarget::successor(path), Bias::Left); removed_entries = cursor.slice(&TraversalTarget::successor(path), Bias::Left);
new_entries.append(cursor.suffix(), &()); new_entries.append(cursor.suffix(), ());
} }
self.snapshot.entries_by_path = new_entries; self.snapshot.entries_by_path = new_entries;
let mut removed_ids = Vec::with_capacity(removed_entries.summary().count); let mut removed_ids = Vec::with_capacity(removed_entries.summary().count);
for entry in removed_entries.cursor::<()>(&()) { for entry in removed_entries.cursor::<()>(()) {
match self.removed_entries.entry(entry.inode) { match self.removed_entries.entry(entry.inode) {
hash_map::Entry::Occupied(mut e) => { hash_map::Entry::Occupied(mut e) => {
let prev_removed_entry = e.get_mut(); let prev_removed_entry = e.get_mut();
@@ -3113,10 +3112,9 @@ impl BackgroundScannerState {
} }
} }
self.snapshot.entries_by_id.edit( self.snapshot
removed_ids.iter().map(|&id| Edit::Remove(id)).collect(), .entries_by_id
&(), .edit(removed_ids.iter().map(|&id| Edit::Remove(id)).collect(), ());
);
self.snapshot self.snapshot
.git_repositories .git_repositories
.retain(|id, _| removed_ids.binary_search(id).is_err()); .retain(|id, _| removed_ids.binary_search(id).is_err());
@@ -3560,23 +3558,23 @@ pub struct PathSummary<S> {
} }
impl<S: Summary> Summary for PathSummary<S> { impl<S: Summary> Summary for PathSummary<S> {
type Context = S::Context; type Context<'a> = S::Context<'a>;
fn zero(cx: &Self::Context) -> Self { fn zero(cx: Self::Context<'_>) -> Self {
Self { Self {
max_path: Path::new("").into(), max_path: Path::new("").into(),
item_summary: S::zero(cx), item_summary: S::zero(cx),
} }
} }
fn add_summary(&mut self, rhs: &Self, cx: &Self::Context) { fn add_summary(&mut self, rhs: &Self, cx: Self::Context<'_>) {
self.max_path = rhs.max_path.clone(); self.max_path = rhs.max_path.clone();
self.item_summary.add_summary(&rhs.item_summary, cx); self.item_summary.add_summary(&rhs.item_summary, cx);
} }
} }
impl<'a, S: Summary> sum_tree::Dimension<'a, PathSummary<S>> for PathProgress<'a> { impl<'a, S: Summary> sum_tree::Dimension<'a, PathSummary<S>> for PathProgress<'a> {
fn zero(_: &<PathSummary<S> as Summary>::Context) -> Self { fn zero(_: <PathSummary<S> as Summary>::Context<'_>) -> Self {
Self { Self {
max_path: Path::new(""), max_path: Path::new(""),
} }
@@ -3585,18 +3583,18 @@ impl<'a, S: Summary> sum_tree::Dimension<'a, PathSummary<S>> for PathProgress<'a
fn add_summary( fn add_summary(
&mut self, &mut self,
summary: &'a PathSummary<S>, summary: &'a PathSummary<S>,
_: &<PathSummary<S> as Summary>::Context, _: <PathSummary<S> as Summary>::Context<'_>,
) { ) {
self.max_path = summary.max_path.as_ref() self.max_path = summary.max_path.as_ref()
} }
} }
impl<'a> sum_tree::Dimension<'a, PathSummary<GitSummary>> for GitSummary { impl<'a> sum_tree::Dimension<'a, PathSummary<GitSummary>> for GitSummary {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a PathSummary<GitSummary>, _: &()) { fn add_summary(&mut self, summary: &'a PathSummary<GitSummary>, _: ()) {
*self += summary.item_summary *self += summary.item_summary
} }
} }
@@ -3608,28 +3606,28 @@ impl<'a>
fn cmp( fn cmp(
&self, &self,
cursor_location: &Dimensions<TraversalProgress<'a>, GitSummary>, cursor_location: &Dimensions<TraversalProgress<'a>, GitSummary>,
_: &(), _: (),
) -> Ordering { ) -> Ordering {
self.cmp_path(cursor_location.0.max_path) self.cmp_path(cursor_location.0.max_path)
} }
} }
impl<'a, S: Summary> sum_tree::Dimension<'a, PathSummary<S>> for PathKey { impl<'a, S: Summary> sum_tree::Dimension<'a, PathSummary<S>> for PathKey {
fn zero(_: &S::Context) -> Self { fn zero(_: S::Context<'_>) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a PathSummary<S>, _: &S::Context) { fn add_summary(&mut self, summary: &'a PathSummary<S>, _: S::Context<'_>) {
self.0 = summary.max_path.clone(); self.0 = summary.max_path.clone();
} }
} }
impl<'a, S: Summary> sum_tree::Dimension<'a, PathSummary<S>> for TraversalProgress<'a> { impl<'a, S: Summary> sum_tree::Dimension<'a, PathSummary<S>> for TraversalProgress<'a> {
fn zero(_cx: &S::Context) -> Self { fn zero(_cx: S::Context<'_>) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a PathSummary<S>, _: &S::Context) { fn add_summary(&mut self, summary: &'a PathSummary<S>, _: S::Context<'_>) {
self.max_path = summary.max_path.as_ref(); self.max_path = summary.max_path.as_ref();
} }
} }
@@ -3697,7 +3695,7 @@ impl EntryKind {
impl sum_tree::Item for Entry { impl sum_tree::Item for Entry {
type Summary = EntrySummary; type Summary = EntrySummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
let non_ignored_count = if (self.is_ignored || self.is_external) && !self.is_always_included let non_ignored_count = if (self.is_ignored || self.is_external) && !self.is_always_included
{ {
0 0
@@ -3753,14 +3751,12 @@ impl Default for EntrySummary {
} }
} }
impl sum_tree::Summary for EntrySummary { impl sum_tree::ContextLessSummary for EntrySummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, rhs: &Self, _: &()) { fn add_summary(&mut self, rhs: &Self) {
self.max_path = rhs.max_path.clone(); self.max_path = rhs.max_path.clone();
self.count += rhs.count; self.count += rhs.count;
self.non_ignored_count += rhs.non_ignored_count; self.non_ignored_count += rhs.non_ignored_count;
@@ -3780,7 +3776,7 @@ struct PathEntry {
impl sum_tree::Item for PathEntry { impl sum_tree::Item for PathEntry {
type Summary = PathEntrySummary; type Summary = PathEntrySummary;
fn summary(&self, _cx: &()) -> Self::Summary { fn summary(&self, _cx: ()) -> Self::Summary {
PathEntrySummary { max_id: self.id } PathEntrySummary { max_id: self.id }
} }
} }
@@ -3798,24 +3794,22 @@ struct PathEntrySummary {
max_id: ProjectEntryId, max_id: ProjectEntryId,
} }
impl sum_tree::Summary for PathEntrySummary { impl sum_tree::ContextLessSummary for PathEntrySummary {
type Context = (); fn zero() -> Self {
fn zero(_cx: &Self::Context) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &Self, _: &Self::Context) { fn add_summary(&mut self, summary: &Self) {
self.max_id = summary.max_id; self.max_id = summary.max_id;
} }
} }
impl<'a> sum_tree::Dimension<'a, PathEntrySummary> for ProjectEntryId { impl<'a> sum_tree::Dimension<'a, PathEntrySummary> for ProjectEntryId {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a PathEntrySummary, _: &()) { fn add_summary(&mut self, summary: &'a PathEntrySummary, _: ()) {
*self = summary.max_id; *self = summary.max_id;
} }
} }
@@ -3830,11 +3824,11 @@ impl Default for PathKey {
} }
impl<'a> sum_tree::Dimension<'a, EntrySummary> for PathKey { impl<'a> sum_tree::Dimension<'a, EntrySummary> for PathKey {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) { fn add_summary(&mut self, summary: &'a EntrySummary, _: ()) {
self.0 = summary.max_path.clone(); self.0 = summary.max_path.clone();
} }
} }
@@ -4889,7 +4883,7 @@ impl BackgroundScanner {
} }
if entry.is_ignored != was_ignored { if entry.is_ignored != was_ignored {
let mut path_entry = snapshot.entries_by_id.get(&entry.id, &()).unwrap().clone(); let mut path_entry = snapshot.entries_by_id.get(&entry.id, ()).unwrap().clone();
path_entry.scan_id = snapshot.scan_id; path_entry.scan_id = snapshot.scan_id;
path_entry.is_ignored = entry.is_ignored; path_entry.is_ignored = entry.is_ignored;
entries_by_id_edits.push(Edit::Insert(path_entry)); entries_by_id_edits.push(Edit::Insert(path_entry));
@@ -4909,8 +4903,8 @@ impl BackgroundScanner {
state state
.snapshot .snapshot
.entries_by_path .entries_by_path
.edit(entries_by_path_edits, &()); .edit(entries_by_path_edits, ());
state.snapshot.entries_by_id.edit(entries_by_id_edits, &()); state.snapshot.entries_by_id.edit(entries_by_id_edits, ());
} }
fn update_git_repositories(&self, dot_git_paths: Vec<PathBuf>) -> Vec<Arc<Path>> { fn update_git_repositories(&self, dot_git_paths: Vec<PathBuf>) -> Vec<Arc<Path>> {
@@ -5094,8 +5088,8 @@ fn build_diff(
// Identify which paths have changed. Use the known set of changed // Identify which paths have changed. Use the known set of changed
// parent paths to optimize the search. // parent paths to optimize the search.
let mut changes = Vec::new(); let mut changes = Vec::new();
let mut old_paths = old_snapshot.entries_by_path.cursor::<PathKey>(&()); let mut old_paths = old_snapshot.entries_by_path.cursor::<PathKey>(());
let mut new_paths = new_snapshot.entries_by_path.cursor::<PathKey>(&()); let mut new_paths = new_snapshot.entries_by_path.cursor::<PathKey>(());
let mut last_newly_loaded_dir_path = None; let mut last_newly_loaded_dir_path = None;
old_paths.next(); old_paths.next();
new_paths.next(); new_paths.next();
@@ -5384,11 +5378,11 @@ impl TraversalProgress<'_> {
} }
impl<'a> sum_tree::Dimension<'a, EntrySummary> for TraversalProgress<'a> { impl<'a> sum_tree::Dimension<'a, EntrySummary> for TraversalProgress<'a> {
fn zero(_cx: &()) -> Self { fn zero(_cx: ()) -> Self {
Default::default() Default::default()
} }
fn add_summary(&mut self, summary: &'a EntrySummary, _: &()) { fn add_summary(&mut self, summary: &'a EntrySummary, _: ()) {
self.max_path = summary.max_path.as_ref(); self.max_path = summary.max_path.as_ref();
self.count += summary.count; self.count += summary.count;
self.non_ignored_count += summary.non_ignored_count; self.non_ignored_count += summary.non_ignored_count;
@@ -5412,7 +5406,7 @@ impl Default for TraversalProgress<'_> {
#[derive(Debug)] #[derive(Debug)]
pub struct Traversal<'a> { pub struct Traversal<'a> {
snapshot: &'a Snapshot, snapshot: &'a Snapshot,
cursor: sum_tree::Cursor<'a, Entry, TraversalProgress<'a>>, cursor: sum_tree::Cursor<'a, 'static, Entry, TraversalProgress<'a>>,
include_ignored: bool, include_ignored: bool,
include_files: bool, include_files: bool,
include_dirs: bool, include_dirs: bool,
@@ -5426,7 +5420,7 @@ impl<'a> Traversal<'a> {
include_ignored: bool, include_ignored: bool,
start_path: &Path, start_path: &Path,
) -> Self { ) -> Self {
let mut cursor = snapshot.entries_by_path.cursor(&()); let mut cursor = snapshot.entries_by_path.cursor(());
cursor.seek(&TraversalTarget::path(start_path), Bias::Left); cursor.seek(&TraversalTarget::path(start_path), Bias::Left);
let mut traversal = Self { let mut traversal = Self {
snapshot, snapshot,
@@ -5536,13 +5530,13 @@ impl PathTarget<'_> {
} }
impl<'a, S: Summary> SeekTarget<'a, PathSummary<S>, PathProgress<'a>> for PathTarget<'_> { impl<'a, S: Summary> SeekTarget<'a, PathSummary<S>, PathProgress<'a>> for PathTarget<'_> {
fn cmp(&self, cursor_location: &PathProgress<'a>, _: &S::Context) -> Ordering { fn cmp(&self, cursor_location: &PathProgress<'a>, _: S::Context<'_>) -> Ordering {
self.cmp_path(cursor_location.max_path) self.cmp_path(cursor_location.max_path)
} }
} }
impl<'a, S: Summary> SeekTarget<'a, PathSummary<S>, TraversalProgress<'a>> for PathTarget<'_> { impl<'a, S: Summary> SeekTarget<'a, PathSummary<S>, TraversalProgress<'a>> for PathTarget<'_> {
fn cmp(&self, cursor_location: &TraversalProgress<'a>, _: &S::Context) -> Ordering { fn cmp(&self, cursor_location: &TraversalProgress<'a>, _: S::Context<'_>) -> Ordering {
self.cmp_path(cursor_location.max_path) self.cmp_path(cursor_location.max_path)
} }
} }
@@ -5584,13 +5578,15 @@ impl<'a> TraversalTarget<'a> {
} }
impl<'a> SeekTarget<'a, EntrySummary, TraversalProgress<'a>> for TraversalTarget<'_> { impl<'a> SeekTarget<'a, EntrySummary, TraversalProgress<'a>> for TraversalTarget<'_> {
fn cmp(&self, cursor_location: &TraversalProgress<'a>, _: &()) -> Ordering { fn cmp(&self, cursor_location: &TraversalProgress<'a>, _: ()) -> Ordering {
self.cmp_progress(cursor_location) self.cmp_progress(cursor_location)
} }
} }
impl<'a> SeekTarget<'a, PathSummary<&'static ()>, TraversalProgress<'a>> for TraversalTarget<'_> { impl<'a> SeekTarget<'a, PathSummary<sum_tree::NoSummary>, TraversalProgress<'a>>
fn cmp(&self, cursor_location: &TraversalProgress<'a>, _: &()) -> Ordering { for TraversalTarget<'_>
{
fn cmp(&self, cursor_location: &TraversalProgress<'a>, _: ()) -> Ordering {
self.cmp_progress(cursor_location) self.cmp_progress(cursor_location)
} }
} }