Skip to content

Commit b65821b

Browse files
committed
Add ManagedMap::range.
1 parent 2da4c59 commit b65821b

File tree

1 file changed

+277
-2
lines changed

1 file changed

+277
-2
lines changed

src/map.rs

Lines changed: 277 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@ use core::borrow::Borrow;
66
#[cfg(feature = "std")]
77
use std::collections::BTreeMap;
88
#[cfg(feature = "std")]
9-
use std::collections::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut};
9+
use std::collections::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut, Range as BTreeRange};
10+
#[cfg(feature = "std")]
11+
use std::collections::Bound::{Included, Excluded};
1012
#[cfg(all(feature = "alloc", not(feature = "std")))]
1113
use alloc::btree_map::BTreeMap;
1214
#[cfg(all(feature = "alloc", not(feature = "std")))]
13-
use alloc::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut};
15+
use alloc::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut, Range as BTreeRange};
16+
#[cfg(all(feature = "alloc", not(feature = "std")))]
17+
use alloc::Bound::{Included,Excluded};
1418

1519
/// A managed map.
1620
///
@@ -90,6 +94,102 @@ impl<T> Into<Option<T>> for RevOption<T> {
9094
}
9195
}
9296

97+
pub enum Range<'a, 'b, K: 'a, V: 'a> where 'a: 'b {
98+
/// Borrowed variant.
99+
Borrowed(&'b [Option<(K, V)>], usize),
100+
/// Owned variant, only available with the `std` or `alloc` feature enabled.
101+
#[cfg(any(feature = "std", feature = "alloc"))]
102+
Owned(BTreeRange<'b, K, V>),
103+
_Phantom(&'a K),
104+
}
105+
106+
impl<'b, 'a: 'b, K: 'a, V: 'a> Iterator for Range<'a, 'b, K, V> {
107+
type Item = (&'b K, &'b V);
108+
109+
fn next(&mut self) -> Option<Self::Item> {
110+
match *self {
111+
Range::Borrowed(ref slice, ref mut index) => {
112+
*index += 1;
113+
if *index-1 >= slice.len() {
114+
None
115+
}
116+
else {
117+
match slice[*index-1] {
118+
None => None,
119+
Some((ref k, ref v)) => Some((k, v))
120+
}
121+
}
122+
},
123+
Range::Owned(ref mut range) => range.next(),
124+
Range::_Phantom(_) => unreachable!(),
125+
}
126+
}
127+
}
128+
129+
fn binary_search_by_key_range<K, V, Q>(slice: &[Option<(K, V)>], key_begin: &Q, key_end: &Q) -> Result<(usize, usize), ()>
130+
where K: Ord + Borrow<Q>, Q: Ord + ?Sized
131+
{
132+
if slice.len() == 0 {
133+
return Err(())
134+
}
135+
let (mut left, mut right) = (0, slice.len()-1);
136+
137+
//let key = |entry: Option<(K, V)>| { entry.as_ref().map(|&(ref key, _)| key.borrow()) };
138+
macro_rules! key {
139+
( $e:expr) => { $e.as_ref().map(|&(ref key, _)| key.borrow()) }
140+
}
141+
142+
// We cannot use slice.binary_search_by_key instead of each of the
143+
// two loops here, because we need the left-most match (for begin) and
144+
// the right-most match (for end), and the stdlib does not provide
145+
// any of these guarantees.
146+
147+
// Find the beginning
148+
while left < right {
149+
let middle = left + (right-left)/2;
150+
if key!(slice[middle]) < Some(key_begin) {
151+
left = middle+1;
152+
}
153+
else if middle > 0 && key!(slice[middle-1]) >= Some(key_begin) {
154+
right = middle-1;
155+
}
156+
else {
157+
left = middle;
158+
right = middle;
159+
break;
160+
}
161+
}
162+
assert_eq!(left, right);
163+
let begin = left;
164+
if key!(slice[begin]) < Some(key_begin) {
165+
return Err(())
166+
}
167+
168+
// Find the ending
169+
right = slice.len(); // no need to reset left
170+
while left < right {
171+
let middle = left + (right-left+1)/2;
172+
if key!(slice[middle-1]) >= Some(key_end) {
173+
right = middle-1;
174+
}
175+
else if middle < slice.len() && key!(slice[middle]) < Some(key_end) {
176+
left = middle+1;
177+
}
178+
else {
179+
left = middle;
180+
right = middle;
181+
break;
182+
}
183+
}
184+
assert_eq!(left, right);
185+
let end = right;
186+
if end == 0 || key!(slice[end-1]) > Some(key_end) {
187+
return Err(())
188+
}
189+
190+
Ok((begin, end))
191+
}
192+
93193
fn binary_search_by_key<K, V, Q>(slice: &[Option<(K, V)>], key: &Q) -> Result<usize, usize>
94194
where K: Ord + Borrow<Q>, Q: Ord + ?Sized
95195
{
@@ -155,6 +255,23 @@ impl<'a, K: Ord + 'a, V: 'a> ManagedMap<'a, K, V> {
155255
}
156256
}
157257

258+
pub fn range<'b, 'c, Q>(&'c self, key_begin: &Q, key_end: &Q) -> Range<'a, 'b, K, V>
259+
where K: Borrow<Q>, Q: Ord + ?Sized, 'a: 'b, 'c: 'a
260+
{
261+
match self {
262+
&ManagedMap::Borrowed(ref pairs) => {
263+
match binary_search_by_key_range(&pairs[0..self.len()], key_begin, key_end) {
264+
Ok((begin, end)) => Range::Borrowed(&pairs[begin..end], 0),
265+
Err(()) => Range::Borrowed(&[], 0),
266+
}
267+
},
268+
#[cfg(any(feature = "std", feature = "alloc"))]
269+
&ManagedMap::Owned(ref map) => {
270+
Range::Owned(map.range((Included(key_begin), Excluded(key_end))))
271+
},
272+
}
273+
}
274+
158275
pub fn insert(&mut self, key: K, new_value: V) -> Result<Option<V>, (K, V)> {
159276
match self {
160277
&mut ManagedMap::Borrowed(ref mut pairs) if pairs.len() < 1 =>
@@ -379,6 +496,164 @@ mod test {
379496
assert_eq!(map.get("q"), None);
380497
}
381498

499+
#[test]
500+
fn test_get_none_empty() {
501+
let mut pairs = all_pairs_empty();
502+
let map = ManagedMap::Borrowed(&mut pairs);
503+
assert_eq!(map.len(), 0);
504+
assert!(map.is_empty());
505+
assert_eq!(map.get("q"), None);
506+
}
507+
508+
#[test]
509+
fn test_range_full() {
510+
let mut pairs = all_pairs_full();
511+
let map = ManagedMap::Borrowed(&mut pairs);
512+
assert_eq!(map.len(), 4);
513+
514+
let mut range = map.range("0", "a");
515+
assert_eq!(range.next(), None);
516+
let mut range = map.range("0", "b");
517+
assert_eq!(range.next(), Some((&"a", &1)));
518+
assert_eq!(range.next(), None);
519+
let mut range = map.range("0", "c");
520+
assert_eq!(range.next(), Some((&"a", &1)));
521+
assert_eq!(range.next(), Some((&"b", &2)));
522+
assert_eq!(range.next(), None);
523+
let mut range = map.range("0", "d");
524+
assert_eq!(range.next(), Some((&"a", &1)));
525+
assert_eq!(range.next(), Some((&"b", &2)));
526+
assert_eq!(range.next(), Some((&"c", &3)));
527+
assert_eq!(range.next(), None);
528+
let mut range = map.range("0", "e");
529+
assert_eq!(range.next(), Some((&"a", &1)));
530+
assert_eq!(range.next(), Some((&"b", &2)));
531+
assert_eq!(range.next(), Some((&"c", &3)));
532+
assert_eq!(range.next(), Some((&"d", &4)));
533+
assert_eq!(range.next(), None);
534+
535+
let mut range = map.range("a", "a");
536+
assert_eq!(range.next(), None);
537+
let mut range = map.range("a", "b");
538+
assert_eq!(range.next(), Some((&"a", &1)));
539+
assert_eq!(range.next(), None);
540+
let mut range = map.range("a", "c");
541+
assert_eq!(range.next(), Some((&"a", &1)));
542+
assert_eq!(range.next(), Some((&"b", &2)));
543+
assert_eq!(range.next(), None);
544+
let mut range = map.range("a", "d");
545+
assert_eq!(range.next(), Some((&"a", &1)));
546+
assert_eq!(range.next(), Some((&"b", &2)));
547+
assert_eq!(range.next(), Some((&"c", &3)));
548+
assert_eq!(range.next(), None);
549+
let mut range = map.range("a", "e");
550+
assert_eq!(range.next(), Some((&"a", &1)));
551+
assert_eq!(range.next(), Some((&"b", &2)));
552+
assert_eq!(range.next(), Some((&"c", &3)));
553+
assert_eq!(range.next(), Some((&"d", &4)));
554+
assert_eq!(range.next(), None);
555+
556+
let mut range = map.range("b", "a");
557+
assert_eq!(range.next(), None);
558+
let mut range = map.range("b", "b");
559+
assert_eq!(range.next(), None);
560+
let mut range = map.range("b", "c");
561+
assert_eq!(range.next(), Some((&"b", &2)));
562+
assert_eq!(range.next(), None);
563+
let mut range = map.range("b", "d");
564+
assert_eq!(range.next(), Some((&"b", &2)));
565+
assert_eq!(range.next(), Some((&"c", &3)));
566+
assert_eq!(range.next(), None);
567+
let mut range = map.range("b", "e");
568+
assert_eq!(range.next(), Some((&"b", &2)));
569+
assert_eq!(range.next(), Some((&"c", &3)));
570+
assert_eq!(range.next(), Some((&"d", &4)));
571+
assert_eq!(range.next(), None);
572+
573+
let mut range = map.range("c", "a");
574+
assert_eq!(range.next(), None);
575+
let mut range = map.range("c", "b");
576+
assert_eq!(range.next(), None);
577+
let mut range = map.range("c", "c");
578+
assert_eq!(range.next(), None);
579+
let mut range = map.range("c", "d");
580+
assert_eq!(range.next(), Some((&"c", &3)));
581+
assert_eq!(range.next(), None);
582+
let mut range = map.range("c", "e");
583+
assert_eq!(range.next(), Some((&"c", &3)));
584+
assert_eq!(range.next(), Some((&"d", &4)));
585+
assert_eq!(range.next(), None);
586+
587+
let mut range = map.range("d", "a");
588+
assert_eq!(range.next(), None);
589+
let mut range = map.range("d", "b");
590+
assert_eq!(range.next(), None);
591+
let mut range = map.range("d", "c");
592+
assert_eq!(range.next(), None);
593+
let mut range = map.range("d", "d");
594+
assert_eq!(range.next(), None);
595+
let mut range = map.range("d", "e");
596+
assert_eq!(range.next(), Some((&"d", &4)));
597+
assert_eq!(range.next(), None);
598+
599+
let mut range = map.range("e", "a");
600+
assert_eq!(range.next(), None);
601+
let mut range = map.range("e", "b");
602+
assert_eq!(range.next(), None);
603+
let mut range = map.range("e", "c");
604+
assert_eq!(range.next(), None);
605+
let mut range = map.range("e", "d");
606+
assert_eq!(range.next(), None);
607+
let mut range = map.range("e", "e");
608+
assert_eq!(range.next(), None);
609+
}
610+
611+
#[test]
612+
fn test_range_one_pair() {
613+
let mut pairs = one_pair_full();
614+
let map = ManagedMap::Borrowed(&mut pairs);
615+
assert_eq!(map.len(), 1);
616+
617+
let mut range = map.range("0", "a");
618+
assert_eq!(range.next(), None);
619+
let mut range = map.range("0", "b");
620+
assert_eq!(range.next(), Some((&"a", &1)));
621+
assert_eq!(range.next(), None);
622+
let mut range = map.range("0", "c");
623+
assert_eq!(range.next(), Some((&"a", &1)));
624+
assert_eq!(range.next(), None);
625+
626+
let mut range = map.range("a", "a");
627+
assert_eq!(range.next(), None);
628+
let mut range = map.range("a", "b");
629+
assert_eq!(range.next(), Some((&"a", &1)));
630+
assert_eq!(range.next(), None);
631+
let mut range = map.range("a", "c");
632+
assert_eq!(range.next(), Some((&"a", &1)));
633+
assert_eq!(range.next(), None);
634+
635+
let mut range = map.range("b", "a");
636+
assert_eq!(range.next(), None);
637+
let mut range = map.range("b", "b");
638+
assert_eq!(range.next(), None);
639+
let mut range = map.range("b", "c");
640+
assert_eq!(range.next(), None);
641+
}
642+
643+
#[test]
644+
fn test_range_empty() {
645+
let mut pairs = all_pairs_empty();
646+
let map = ManagedMap::Borrowed(&mut pairs);
647+
assert_eq!(map.len(), 0);
648+
649+
let mut range = map.range("b", "a");
650+
assert_eq!(range.next(), None);
651+
let mut range = map.range("b", "b");
652+
assert_eq!(range.next(), None);
653+
let mut range = map.range("b", "c");
654+
assert_eq!(range.next(), None);
655+
}
656+
382657
#[test]
383658
fn test_get_mut_some() {
384659
let mut pairs = all_pairs_full();

0 commit comments

Comments
 (0)