@@ -2030,22 +2030,28 @@ impl Buffer {
}
}
- fn fragment_ix_for_anchor(&self, anchor: &Anchor) -> usize {
+ fn fragment_ix_for_anchor(&self, anchor: &Anchor) -> (usize, usize) {
match anchor {
- Anchor::Start => 0,
- Anchor::End => self.fragments.extent::<FragmentCount>(&None).0,
+ Anchor::Start => (0, 0),
+ Anchor::End => (
+ self.fragments.extent::<FragmentCount>(&None).0,
+ self.fragments.last().map_or(0, |f| f.visible_len()),
+ ),
Anchor::Middle {
offset,
bias,
version,
} => {
- let mut cursor = self.fragments.cursor::<VersionedOffset, FragmentCount>();
+ let mut cursor = self
+ .fragments
+ .cursor::<VersionedOffset, (VersionedOffset, FragmentCount)>();
cursor.seek(
&VersionedOffset::Offset(*offset),
bias.to_seek_bias(),
&Some(version.clone()),
);
- cursor.start().0
+ let count = cursor.start().1;
+ (count.0, offset - cursor.start().0.offset())
}
}
}
@@ -2666,6 +2672,13 @@ impl<'a> sum_tree::Dimension<'a, FragmentSummary> for (VersionedOffset, usize) {
}
}
+impl<'a> sum_tree::Dimension<'a, FragmentSummary> for (VersionedOffset, FragmentCount) {
+ fn add_summary(&mut self, summary: &'a FragmentSummary, cx: &Option<time::Global>) {
+ self.0.add_summary(summary, cx);
+ self.1 .0 += summary.count;
+ }
+}
+
#[derive(Copy, Clone, Default, Debug, Eq, PartialEq, Ord, PartialOrd)]
struct FragmentCount(usize);
@@ -1,4 +1,4 @@
-use super::{Buffer, ToOffset};
+use super::Buffer;
use crate::{sum_tree, time};
use anyhow::Result;
use std::{cmp::Ordering, ops::Range};
@@ -61,30 +61,15 @@ impl Anchor {
(Anchor::End, _) | (_, Anchor::Start) => Ordering::Greater,
(
Anchor::Middle {
- offset: self_offset,
- bias: self_bias,
- ..
+ bias: self_bias, ..
},
Anchor::Middle {
- offset: other_offset,
- bias: other_bias,
- ..
+ bias: other_bias, ..
},
- ) => {
- dbg!(
- self,
- other,
- self_offset,
- other_offset,
- buffer.fragment_ix_for_anchor(self),
- buffer.fragment_ix_for_anchor(other)
- );
- buffer
- .fragment_ix_for_anchor(self)
- .cmp(&buffer.fragment_ix_for_anchor(other))
- .then_with(|| self_offset.cmp(&other_offset))
- .then_with(|| self_bias.cmp(other_bias))
- }
+ ) => buffer
+ .fragment_ix_for_anchor(self)
+ .cmp(&buffer.fragment_ix_for_anchor(other))
+ .then_with(|| self_bias.cmp(&other_bias)),
})
}