From 41d9972538d49ffa3964e3a94109619ce053ef36 Mon Sep 17 00:00:00 2001 From: Arthur Silva Date: Fri, 16 Oct 2020 19:17:48 +0200 Subject: [PATCH] Fix btree::Node::path_{next/prev} --- src/nodes/btree.rs | 36 +++++++++++++++++++++++++++--------- src/ord/map.rs | 24 ++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/nodes/btree.rs b/src/nodes/btree.rs index b5a27a7..da74b6f 100644 --- a/src/nodes/btree.rs +++ b/src/nodes/btree.rs @@ -16,7 +16,7 @@ use crate::util::{Pool, PoolClone, PoolDefault, PoolRef}; use self::Insert::*; use self::InsertAction::*; -const NODE_SIZE: usize = NodeSize::USIZE; +pub(crate) const NODE_SIZE: usize = NodeSize::USIZE; const MEDIAN: usize = (NODE_SIZE + 1) >> 1; pub trait BTreeValue { @@ -395,7 +395,17 @@ impl Node { path.push((self, index)); path } - None => Vec::new(), + None => { + // go back up to find next + while let Some((node, idx)) = path.last() { + if node.keys.len() == *idx { + path.pop(); + } else { + break; + } + } + path + } }, Some(ref node) => { path.push((self, index)); @@ -424,14 +434,22 @@ impl Node { path } Err(index) => match self.children[index] { - None if index == 0 => Vec::new(), - None => match self.keys.get(index - 1) { - Some(_) => { - path.push((self, index - 1)); - path + None if index == 0 => { + // go back up to find prev + while let Some((_, idx)) = path.last_mut() { + if *idx == 0 { + path.pop(); + } else { + *idx -= 1; + break; + } } - None => Vec::new(), - }, + path + } + None => { + path.push((self, index - 1)); + path + } Some(ref node) => { path.push((self, index)); node.path_prev(key, path) diff --git a/src/ord/map.rs b/src/ord/map.rs index 14931f7..55294d8 100644 --- a/src/ord/map.rs +++ b/src/ord/map.rs @@ -2381,6 +2381,30 @@ mod test { assert_eq!(vec![(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)], range); } + #[test] + fn range_iter_big() { + use crate::nodes::btree::NODE_SIZE; + use std::ops::Bound::Included; + const N: usize = NODE_SIZE * NODE_SIZE * 5; // enough for a sizeable 3 level tree + + let data = (1usize..N).filter(|i| i % 2 == 0).map(|i| (i, ())); + let bmap = data + .clone() + .collect::>(); + let omap = data.collect::>(); + + for i in (0..NODE_SIZE * 5).chain(N - NODE_SIZE * 5..=N + 1) { + assert_eq!(omap.range(i..).count(), bmap.range(i..).count()); + assert_eq!(omap.range(..i).count(), bmap.range(..i).count()); + assert_eq!(omap.range(i..i + 7).count(), bmap.range(i..i + 7).count()); + assert_eq!(omap.range(i..=i + 7).count(), bmap.range(i..=i + 7).count()); + assert_eq!( + omap.range((Included(i), Included(i + 7))).count(), + bmap.range((Included(i), Included(i + 7))).count(), + ); + } + } + #[test] fn issue_124() { let mut map = OrdMap::new();