Skip to content

Commit 4972caf

Browse files
committed
perf: add size_hint for rope CharIndices
1 parent 739d6a7 commit 4972caf

File tree

1 file changed

+44
-3
lines changed

1 file changed

+44
-3
lines changed

src/rope.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ impl<'a> Rope<'a> {
509509
Lines {
510510
iter: match &self.repr {
511511
Repr::Light(s) => LinesEnum::Light(s),
512-
Repr::Full(data) => LinesEnum::Complex {
512+
Repr::Full(data) => LinesEnum::Full {
513513
iter: data,
514514
in_chunk_byte_idx: 0,
515515
chunk_idx: 0,
@@ -554,7 +554,7 @@ impl Hash for Rope<'_> {
554554

555555
enum LinesEnum<'a, 'b> {
556556
Light(&'b str),
557-
Complex {
557+
Full {
558558
iter: &'a Vec<(&'b str, usize)>,
559559
in_chunk_byte_idx: usize,
560560
chunk_idx: usize,
@@ -605,7 +605,7 @@ impl<'a> Iterator for Lines<'_, 'a> {
605605
}
606606
Lines {
607607
iter:
608-
LinesEnum::Complex {
608+
LinesEnum::Full {
609609
iter: chunks,
610610
ref mut in_chunk_byte_idx,
611611
ref mut chunk_idx,
@@ -777,6 +777,34 @@ impl Iterator for CharIndices<'_, '_> {
777777
}
778778
}
779779
}
780+
781+
fn size_hint(&self) -> (usize, Option<usize>) {
782+
(0, None)
783+
// match &self.iter {
784+
// CharIndicesEnum::Light { iter } => iter.size_hint(),
785+
// CharIndicesEnum::Full {
786+
// chunks,
787+
// chunk_index,
788+
// ..
789+
// } => {
790+
// if *chunk_index >= chunks.len() {
791+
// return (0, None);
792+
// }
793+
//
794+
// let Some(total) = chunks.last().map(|(s, l)| *l + s.len()) else {
795+
// return (0, None);
796+
// };
797+
//
798+
// let prev = chunks[chunk_index.saturating_sub(1)].1;
799+
//
800+
// // SAFETY: The previous length is guaranteed be less than or equal to the latter one.
801+
// let remaining = total - prev;
802+
//
803+
// // Uses the same algorihm as `char_indices().size_hint()` to calculate the lower bounds.
804+
// ((remaining + 3) / 4, Some(remaining))
805+
// }
806+
// }
807+
}
780808
}
781809

782810
impl Default for Rope<'_> {
@@ -1226,25 +1254,38 @@ mod tests {
12261254

12271255
#[test]
12281256
fn char_indices() {
1257+
// The algorithm is the same as the one used in `std::str::CharIndices::size_hint`.
1258+
macro_rules! lo {
1259+
($expr:expr) => {
1260+
($expr + 3) / 4
1261+
};
1262+
}
1263+
12291264
let mut a = Rope::new();
12301265
a.add("abc");
12311266
a.add("def");
12321267
assert_eq!(
12331268
a.char_indices().collect::<Vec<_>>(),
12341269
"abcdef".char_indices().collect::<Vec<_>>()
12351270
);
1271+
let len = "abcdef".char_indices().size_hint().1.unwrap();
1272+
assert_eq!(a.char_indices().size_hint(), (lo!(len), Some(len)));
12361273

12371274
let mut a = Rope::new();
12381275
a.add("こんにちは");
12391276
assert_eq!(
12401277
a.char_indices().collect::<Vec<_>>(),
12411278
"こんにちは".char_indices().collect::<Vec<_>>()
12421279
);
1280+
let len = "こんにちは".char_indices().size_hint().1.unwrap();
1281+
assert_eq!(a.char_indices().size_hint(), (lo!(len), Some(len)));
12431282
a.add("世界");
12441283
assert_eq!(
12451284
a.char_indices().collect::<Vec<_>>(),
12461285
"こんにちは世界".char_indices().collect::<Vec<_>>()
12471286
);
1287+
let len = "こんにちは世界".char_indices().size_hint().1.unwrap();
1288+
assert_eq!(a.char_indices().size_hint(), (lo!(len), Some(len)));
12481289
}
12491290

12501291
#[test]

0 commit comments

Comments
 (0)