sum_tree: Store context on cursor (#34904)
This gets rid of the need to pass context to all cursor functions. In practice context is always immutable when interacting with cursors. A nicety of this is in the follow-up PR we will be able to implement Iterator for all Cursors/filter cursors (hell, we may be able to get rid of filter cursor altogether, as it is just a custom `filter` impl on iterator trait). Release Notes: - N/A
This commit is contained in:
parent
fa3e1ccc37
commit
64d0fec699
23 changed files with 749 additions and 876 deletions
|
@ -41,9 +41,9 @@ impl Rope {
|
|||
self.push_chunk(chunk.as_slice());
|
||||
|
||||
let mut chunks = rope.chunks.cursor::<()>(&());
|
||||
chunks.next(&());
|
||||
chunks.next(&());
|
||||
self.chunks.append(chunks.suffix(&()), &());
|
||||
chunks.next();
|
||||
chunks.next();
|
||||
self.chunks.append(chunks.suffix(), &());
|
||||
self.check_invariants();
|
||||
return;
|
||||
}
|
||||
|
@ -283,7 +283,7 @@ impl Rope {
|
|||
return self.summary().len_utf16;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<(usize, OffsetUtf16)>(&());
|
||||
cursor.seek(&offset, Bias::Left, &());
|
||||
cursor.seek(&offset, Bias::Left);
|
||||
let overshoot = offset - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(Default::default(), |chunk| {
|
||||
|
@ -296,7 +296,7 @@ impl Rope {
|
|||
return self.summary().len;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<(OffsetUtf16, usize)>(&());
|
||||
cursor.seek(&offset, Bias::Left, &());
|
||||
cursor.seek(&offset, Bias::Left);
|
||||
let overshoot = offset - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(Default::default(), |chunk| {
|
||||
|
@ -309,7 +309,7 @@ impl Rope {
|
|||
return self.summary().lines;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<(usize, Point)>(&());
|
||||
cursor.seek(&offset, Bias::Left, &());
|
||||
cursor.seek(&offset, Bias::Left);
|
||||
let overshoot = offset - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(Point::zero(), |chunk| {
|
||||
|
@ -322,7 +322,7 @@ impl Rope {
|
|||
return self.summary().lines_utf16();
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<(usize, PointUtf16)>(&());
|
||||
cursor.seek(&offset, Bias::Left, &());
|
||||
cursor.seek(&offset, Bias::Left);
|
||||
let overshoot = offset - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(PointUtf16::zero(), |chunk| {
|
||||
|
@ -335,7 +335,7 @@ impl Rope {
|
|||
return self.summary().lines_utf16();
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<(Point, PointUtf16)>(&());
|
||||
cursor.seek(&point, Bias::Left, &());
|
||||
cursor.seek(&point, Bias::Left);
|
||||
let overshoot = point - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(PointUtf16::zero(), |chunk| {
|
||||
|
@ -348,7 +348,7 @@ impl Rope {
|
|||
return self.summary().len;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<(Point, usize)>(&());
|
||||
cursor.seek(&point, Bias::Left, &());
|
||||
cursor.seek(&point, Bias::Left);
|
||||
let overshoot = point - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor
|
||||
|
@ -369,7 +369,7 @@ impl Rope {
|
|||
return self.summary().len;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<(PointUtf16, usize)>(&());
|
||||
cursor.seek(&point, Bias::Left, &());
|
||||
cursor.seek(&point, Bias::Left);
|
||||
let overshoot = point - cursor.start().0;
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(0, |chunk| {
|
||||
|
@ -382,7 +382,7 @@ impl Rope {
|
|||
return self.summary().lines;
|
||||
}
|
||||
let mut cursor = self.chunks.cursor::<(PointUtf16, Point)>(&());
|
||||
cursor.seek(&point.0, Bias::Left, &());
|
||||
cursor.seek(&point.0, Bias::Left);
|
||||
let overshoot = Unclipped(point.0 - cursor.start().0);
|
||||
cursor.start().1
|
||||
+ cursor.item().map_or(Point::zero(), |chunk| {
|
||||
|
@ -392,7 +392,7 @@ impl Rope {
|
|||
|
||||
pub fn clip_offset(&self, mut offset: usize, bias: Bias) -> usize {
|
||||
let mut cursor = self.chunks.cursor::<usize>(&());
|
||||
cursor.seek(&offset, Bias::Left, &());
|
||||
cursor.seek(&offset, Bias::Left);
|
||||
if let Some(chunk) = cursor.item() {
|
||||
let mut ix = offset - cursor.start();
|
||||
while !chunk.text.is_char_boundary(ix) {
|
||||
|
@ -415,7 +415,7 @@ impl Rope {
|
|||
|
||||
pub fn clip_offset_utf16(&self, offset: OffsetUtf16, bias: Bias) -> OffsetUtf16 {
|
||||
let mut cursor = self.chunks.cursor::<OffsetUtf16>(&());
|
||||
cursor.seek(&offset, Bias::Right, &());
|
||||
cursor.seek(&offset, Bias::Right);
|
||||
if let Some(chunk) = cursor.item() {
|
||||
let overshoot = offset - cursor.start();
|
||||
*cursor.start() + chunk.as_slice().clip_offset_utf16(overshoot, bias)
|
||||
|
@ -426,7 +426,7 @@ impl Rope {
|
|||
|
||||
pub fn clip_point(&self, point: Point, bias: Bias) -> Point {
|
||||
let mut cursor = self.chunks.cursor::<Point>(&());
|
||||
cursor.seek(&point, Bias::Right, &());
|
||||
cursor.seek(&point, Bias::Right);
|
||||
if let Some(chunk) = cursor.item() {
|
||||
let overshoot = point - cursor.start();
|
||||
*cursor.start() + chunk.as_slice().clip_point(overshoot, bias)
|
||||
|
@ -437,7 +437,7 @@ impl Rope {
|
|||
|
||||
pub fn clip_point_utf16(&self, point: Unclipped<PointUtf16>, bias: Bias) -> 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() {
|
||||
let overshoot = Unclipped(point.0 - cursor.start());
|
||||
*cursor.start() + chunk.as_slice().clip_point_utf16(overshoot, bias)
|
||||
|
@ -450,10 +450,6 @@ impl Rope {
|
|||
self.clip_point(Point::new(row, u32::MAX), Bias::Left)
|
||||
.column
|
||||
}
|
||||
|
||||
pub fn ptr_eq(&self, other: &Self) -> bool {
|
||||
self.chunks.ptr_eq(&other.chunks)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for Rope {
|
||||
|
@ -514,7 +510,7 @@ pub struct Cursor<'a> {
|
|||
impl<'a> Cursor<'a> {
|
||||
pub fn new(rope: &'a Rope, offset: usize) -> Self {
|
||||
let mut chunks = rope.chunks.cursor(&());
|
||||
chunks.seek(&offset, Bias::Right, &());
|
||||
chunks.seek(&offset, Bias::Right);
|
||||
Self {
|
||||
rope,
|
||||
chunks,
|
||||
|
@ -525,7 +521,7 @@ impl<'a> Cursor<'a> {
|
|||
pub fn seek_forward(&mut self, end_offset: usize) {
|
||||
debug_assert!(end_offset >= self.offset);
|
||||
|
||||
self.chunks.seek_forward(&end_offset, Bias::Right, &());
|
||||
self.chunks.seek_forward(&end_offset, Bias::Right);
|
||||
self.offset = end_offset;
|
||||
}
|
||||
|
||||
|
@ -540,14 +536,14 @@ impl<'a> Cursor<'a> {
|
|||
let mut slice = Rope::new();
|
||||
if let Some(start_chunk) = self.chunks.item() {
|
||||
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();
|
||||
slice.push_chunk(start_chunk.slice(start_ix..end_ix));
|
||||
}
|
||||
|
||||
if end_offset > self.chunks.end(&()) {
|
||||
self.chunks.next(&());
|
||||
if end_offset > self.chunks.end() {
|
||||
self.chunks.next();
|
||||
slice.append(Rope {
|
||||
chunks: self.chunks.slice(&end_offset, Bias::Right, &()),
|
||||
chunks: self.chunks.slice(&end_offset, Bias::Right),
|
||||
});
|
||||
if let Some(end_chunk) = self.chunks.item() {
|
||||
let end_ix = end_offset - self.chunks.start();
|
||||
|
@ -565,13 +561,13 @@ impl<'a> Cursor<'a> {
|
|||
let mut summary = D::zero(&());
|
||||
if let Some(start_chunk) = self.chunks.item() {
|
||||
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();
|
||||
summary.add_assign(&D::from_chunk(start_chunk.slice(start_ix..end_ix)));
|
||||
}
|
||||
|
||||
if end_offset > self.chunks.end(&()) {
|
||||
self.chunks.next(&());
|
||||
summary.add_assign(&self.chunks.summary(&end_offset, Bias::Right, &()));
|
||||
if end_offset > self.chunks.end() {
|
||||
self.chunks.next();
|
||||
summary.add_assign(&self.chunks.summary(&end_offset, Bias::Right));
|
||||
if let Some(end_chunk) = self.chunks.item() {
|
||||
let end_ix = end_offset - self.chunks.start();
|
||||
summary.add_assign(&D::from_chunk(end_chunk.slice(0..end_ix)));
|
||||
|
@ -603,10 +599,10 @@ impl<'a> Chunks<'a> {
|
|||
pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self {
|
||||
let mut chunks = rope.chunks.cursor(&());
|
||||
let offset = if reversed {
|
||||
chunks.seek(&range.end, Bias::Left, &());
|
||||
chunks.seek(&range.end, Bias::Left);
|
||||
range.end
|
||||
} else {
|
||||
chunks.seek(&range.start, Bias::Right, &());
|
||||
chunks.seek(&range.start, Bias::Right);
|
||||
range.start
|
||||
};
|
||||
Self {
|
||||
|
@ -642,10 +638,10 @@ impl<'a> Chunks<'a> {
|
|||
Bias::Right
|
||||
};
|
||||
|
||||
if offset >= self.chunks.end(&()) {
|
||||
self.chunks.seek_forward(&offset, bias, &());
|
||||
if offset >= self.chunks.end() {
|
||||
self.chunks.seek_forward(&offset, bias);
|
||||
} else {
|
||||
self.chunks.seek(&offset, bias, &());
|
||||
self.chunks.seek(&offset, bias);
|
||||
}
|
||||
|
||||
self.offset = offset;
|
||||
|
@ -674,25 +670,25 @@ impl<'a> Chunks<'a> {
|
|||
found = self.offset <= self.range.end;
|
||||
} else {
|
||||
self.chunks
|
||||
.search_forward(|summary| summary.text.lines.row > 0, &());
|
||||
.search_forward(|summary| summary.text.lines.row > 0);
|
||||
self.offset = *self.chunks.start();
|
||||
|
||||
if let Some(newline_ix) = self.peek().and_then(|chunk| chunk.find('\n')) {
|
||||
self.offset += newline_ix + 1;
|
||||
found = self.offset <= self.range.end;
|
||||
} else {
|
||||
self.offset = self.chunks.end(&());
|
||||
self.offset = self.chunks.end();
|
||||
}
|
||||
}
|
||||
|
||||
if self.offset == self.chunks.end(&()) {
|
||||
if self.offset == self.chunks.end() {
|
||||
self.next();
|
||||
}
|
||||
}
|
||||
|
||||
if self.offset > self.range.end {
|
||||
self.offset = cmp::min(self.offset, self.range.end);
|
||||
self.chunks.seek(&self.offset, Bias::Right, &());
|
||||
self.chunks.seek(&self.offset, Bias::Right);
|
||||
}
|
||||
|
||||
found
|
||||
|
@ -711,7 +707,7 @@ impl<'a> Chunks<'a> {
|
|||
let initial_offset = self.offset;
|
||||
|
||||
if self.offset == *self.chunks.start() {
|
||||
self.chunks.prev(&());
|
||||
self.chunks.prev();
|
||||
}
|
||||
|
||||
if let Some(chunk) = self.chunks.item() {
|
||||
|
@ -729,14 +725,14 @@ impl<'a> Chunks<'a> {
|
|||
}
|
||||
|
||||
self.chunks
|
||||
.search_backward(|summary| summary.text.lines.row > 0, &());
|
||||
.search_backward(|summary| summary.text.lines.row > 0);
|
||||
self.offset = *self.chunks.start();
|
||||
if let Some(chunk) = self.chunks.item() {
|
||||
if let Some(newline_ix) = chunk.text.rfind('\n') {
|
||||
self.offset += newline_ix + 1;
|
||||
if self.offset_is_valid() {
|
||||
if self.offset == self.chunks.end(&()) {
|
||||
self.chunks.next(&());
|
||||
if self.offset == self.chunks.end() {
|
||||
self.chunks.next();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -746,7 +742,7 @@ impl<'a> Chunks<'a> {
|
|||
|
||||
if !self.offset_is_valid() || self.chunks.item().is_none() {
|
||||
self.offset = self.range.start;
|
||||
self.chunks.seek(&self.offset, Bias::Right, &());
|
||||
self.chunks.seek(&self.offset, Bias::Right);
|
||||
}
|
||||
|
||||
self.offset < initial_offset && self.offset == 0
|
||||
|
@ -765,7 +761,7 @@ impl<'a> Chunks<'a> {
|
|||
slice_start..slice_end
|
||||
} else {
|
||||
let slice_start = self.offset - chunk_start;
|
||||
let slice_end = cmp::min(self.chunks.end(&()), self.range.end) - chunk_start;
|
||||
let slice_end = cmp::min(self.chunks.end(), self.range.end) - chunk_start;
|
||||
slice_start..slice_end
|
||||
};
|
||||
|
||||
|
@ -825,12 +821,12 @@ impl<'a> Iterator for Chunks<'a> {
|
|||
if self.reversed {
|
||||
self.offset -= chunk.len();
|
||||
if self.offset <= *self.chunks.start() {
|
||||
self.chunks.prev(&());
|
||||
self.chunks.prev();
|
||||
}
|
||||
} else {
|
||||
self.offset += chunk.len();
|
||||
if self.offset >= self.chunks.end(&()) {
|
||||
self.chunks.next(&());
|
||||
if self.offset >= self.chunks.end() {
|
||||
self.chunks.next();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -848,9 +844,9 @@ impl<'a> Bytes<'a> {
|
|||
pub fn new(rope: &'a Rope, range: Range<usize>, reversed: bool) -> Self {
|
||||
let mut chunks = rope.chunks.cursor(&());
|
||||
if reversed {
|
||||
chunks.seek(&range.end, Bias::Left, &());
|
||||
chunks.seek(&range.end, Bias::Left);
|
||||
} else {
|
||||
chunks.seek(&range.start, Bias::Right, &());
|
||||
chunks.seek(&range.start, Bias::Right);
|
||||
}
|
||||
Self {
|
||||
chunks,
|
||||
|
@ -861,7 +857,7 @@ impl<'a> Bytes<'a> {
|
|||
|
||||
pub fn peek(&self) -> Option<&'a [u8]> {
|
||||
let chunk = self.chunks.item()?;
|
||||
if self.reversed && self.range.start >= self.chunks.end(&()) {
|
||||
if self.reversed && self.range.start >= self.chunks.end() {
|
||||
return None;
|
||||
}
|
||||
let chunk_start = *self.chunks.start();
|
||||
|
@ -881,9 +877,9 @@ impl<'a> Iterator for Bytes<'a> {
|
|||
let result = self.peek();
|
||||
if result.is_some() {
|
||||
if self.reversed {
|
||||
self.chunks.prev(&());
|
||||
self.chunks.prev();
|
||||
} else {
|
||||
self.chunks.next(&());
|
||||
self.chunks.next();
|
||||
}
|
||||
}
|
||||
result
|
||||
|
@ -905,9 +901,9 @@ impl io::Read for Bytes<'_> {
|
|||
|
||||
if len == chunk.len() {
|
||||
if self.reversed {
|
||||
self.chunks.prev(&());
|
||||
self.chunks.prev();
|
||||
} else {
|
||||
self.chunks.next(&());
|
||||
self.chunks.next();
|
||||
}
|
||||
}
|
||||
Ok(len)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue