From 8e1bd225781115bec738d8d13b7e71c4f942833e Mon Sep 17 00:00:00 2001 From: Shanin Roman <40040452+Erigara@users.noreply.github.com> Date: Wed, 26 Jun 2024 04:55:23 +0300 Subject: [PATCH] Fix BptreeMap range iter adjacent leaves (#120) --- src/bptree/mod.rs | 11 +++++++++++ src/internals/bptree/iter.rs | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/bptree/mod.rs b/src/bptree/mod.rs index a84c893..d0dd49e 100644 --- a/src/bptree/mod.rs +++ b/src/bptree/mod.rs @@ -96,6 +96,8 @@ where #[cfg(test)] mod tests { + use std::ops::Bound; + use super::BptreeMap; use crate::internals::bptree::node::{assert_released, L_CAPACITY}; // use rand::prelude::*; @@ -363,6 +365,15 @@ mod tests { assert!(r.range(1..=2).count() == 0); } + #[test] + fn test_bptree2_map_rangeiter_3() { + let map = BptreeMap::from_iter([0, 1, 2, 3, 4, 5, 6, 8].map(|v| (v, ()))); + + let r = map.read(); + assert!(r.range((Bound::Excluded(6), Bound::Included(7))).count() == 0); + assert!(r.range((Bound::Excluded(6), Bound::Excluded(8))).count() == 0); + } + /* #[test] fn test_bptree2_map_write_compact() { diff --git a/src/internals/bptree/iter.rs b/src/internals/bptree/iter.rs index ee94bda..df18ddb 100644 --- a/src/internals/bptree/iter.rs +++ b/src/internals/bptree/iter.rs @@ -487,6 +487,14 @@ where // eprintln!("Excluding Using, {}", fidx); *idx = fidx + 1; if *idx >= leaf.count() { + if let Some((rnode, _)) = right_iter.get_mut() { + // If the leaf iterators were in the same node before advancing left iterator + // means that left iterator would be ahead of right iter so no elements left + if rnode == node { + left_iter.clear(); + right_iter.clear(); + } + } // Okay, this means we overflowed to the next leaf, so just // advanced the leaf iter to the start of the next left_iter.next(); @@ -521,6 +529,14 @@ where // eprintln!("Using, {}", fidx); let (nidx, oflow) = fidx.overflowing_sub(1); if oflow { + if let Some((lnode, _)) = left_iter.get_mut() { + // If the leaf iterators were in the same node before advancing right iterator + // means that left iterator would be ahead of right iter so no elements left + if lnode == node { + left_iter.clear(); + right_iter.clear(); + } + } right_iter.next(); } else { *idx = nidx; @@ -541,6 +557,14 @@ where // eprintln!("Using, {}", fidx); let (nidx, oflow) = fidx.overflowing_sub(1); if oflow { + if let Some((lnode, _)) = left_iter.get_mut() { + // If the leaf iterators were in the same node before advancing right iterator + // means that left iterator would be ahead of right iter so no elements left + if lnode == node { + left_iter.clear(); + right_iter.clear(); + } + } right_iter.next(); } else { *idx = nidx;