Skip to content

Commit d02c6ff

Browse files
authored
Merge pull request #23 from ing-systems/fix/iter-proper-elem-cache
Fix element caching at iterating
2 parents e6c937a + ad4ef19 commit d02c6ff

File tree

1 file changed

+27
-30
lines changed

1 file changed

+27
-30
lines changed

src/lib.rs

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -515,41 +515,38 @@ impl QueueFile {
515515
return;
516516
}
517517

518-
let need_to_cache = self.offset_cache_kind.map_or(false, |kind| {
519-
let last_index = self.elem_cnt - 1;
518+
self.cache_elem_if_needed(self.elem_cnt - 1, self.last, affected_items);
519+
}
520520

521-
match kind {
522-
OffsetCacheKind::Linear { offset } => {
523-
let last_cached_index = self.cached_offsets.back().map_or(0, |(idx, _)| *idx);
524-
last_index - last_cached_index >= offset
525-
}
526-
OffsetCacheKind::Quadratic => {
527-
let x = (last_index as f64).sqrt() as usize;
528-
x > 1 && (self.elem_cnt - affected_items..=last_index).contains(&(x * x))
529-
}
521+
fn cache_elem_if_needed(&mut self, index: usize, elem: Element, affected_items: usize) {
522+
debug_assert!(index <= self.elem_cnt);
523+
debug_assert!(index + 1 >= affected_items);
524+
525+
let need_to_cache = self.offset_cache_kind.map_or(false, |kind| match kind {
526+
OffsetCacheKind::Linear { offset } => {
527+
let last_cached_index = self.cached_offsets.back().map_or(0, |(idx, _)| *idx);
528+
index.saturating_sub(last_cached_index) >= offset
529+
}
530+
OffsetCacheKind::Quadratic => {
531+
let x = (index as f64).sqrt() as usize;
532+
x > 1 && (index + 1 - affected_items..=index).contains(&(x * x))
530533
}
531534
});
532535

533536
if need_to_cache {
534-
self.cache_last_offset();
535-
}
536-
}
537-
538-
fn cache_last_offset(&mut self) {
539-
debug_assert!(self.elem_cnt != 0);
540-
541-
let index = self.elem_cnt - 1;
542-
543-
if let Some((last_cached_index, last_cached_elem)) = self.cached_offsets.back() {
544-
if *last_cached_index == index {
545-
debug_assert_eq!(last_cached_elem.pos, self.last.pos);
546-
debug_assert_eq!(last_cached_elem.len, self.last.len);
537+
if let Some((last_cached_index, last_cached_elem)) = self.cached_offsets.back() {
538+
if *last_cached_index >= index {
539+
if *last_cached_index == index {
540+
debug_assert_eq!(last_cached_elem.pos, elem.pos);
541+
debug_assert_eq!(last_cached_elem.len, elem.len);
542+
}
547543

548-
return;
544+
return;
545+
}
549546
}
550-
}
551547

552-
self.cached_offsets.push_back((index, self.last));
548+
self.cached_offsets.push_back((index, elem));
549+
}
553550
}
554551

555552
#[inline]
@@ -1270,7 +1267,7 @@ impl<'a> Iterator for Iter<'a> {
12701267
};
12711268

12721269
for _ in 0..left {
1273-
self.next();
1270+
self.borrowed_next();
12741271
}
12751272

12761273
self.next()
@@ -1297,9 +1294,9 @@ impl Iter<'_> {
12971294
self.next_elem_pos = self
12981295
.queue_file
12991296
.wrap_pos(current.pos + Element::HEADER_LENGTH as u64 + current.len as u64);
1300-
self.next_elem_index += 1;
13011297

1302-
self.queue_file.cache_last_offset_if_needed(1);
1298+
self.queue_file.cache_elem_if_needed(self.next_elem_index, current, 1);
1299+
self.next_elem_index += 1;
13031300

13041301
Some(&self.buffer[..current.len])
13051302
}

0 commit comments

Comments
 (0)