Skip to content

Commit 7849e64

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

File tree

1 file changed

+267
-2
lines changed

1 file changed

+267
-2
lines changed

src/map.rs

+267-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,19 @@ use core::mem;
22
use core::fmt;
33
use core::slice;
44
use core::borrow::Borrow;
5+
#[cfg(all(feature = "alloc", not(feature = "std")))]
6+
use core::ops::Bound::{Included,Excluded};
57

68
#[cfg(feature = "std")]
79
use std::collections::BTreeMap;
810
#[cfg(feature = "std")]
9-
use std::collections::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut};
11+
use std::collections::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut, Range as BTreeRange};
12+
#[cfg(feature = "std")]
13+
use std::collections::Bound::{Included, Excluded};
1014
#[cfg(all(feature = "alloc", not(feature = "std")))]
1115
use alloc::btree_map::BTreeMap;
1216
#[cfg(all(feature = "alloc", not(feature = "std")))]
13-
use alloc::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut};
17+
use alloc::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut, Range as BTreeRange};
1418

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

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

248+
pub fn range<'b, Q>(&'b self, key_begin: &Q, key_end: &Q) -> Range<'a, K, V>
249+
where K: Borrow<Q>, Q: Ord + ?Sized, 'b: 'a
250+
{
251+
match self {
252+
&ManagedMap::Borrowed(ref pairs) => {
253+
match binary_search_by_key_range(&pairs[0..self.len()], key_begin, key_end) {
254+
Ok((begin, end)) => Range::Borrowed(&pairs[begin..end], 0),
255+
Err(()) => Range::Borrowed(&[], 0),
256+
}
257+
},
258+
#[cfg(any(feature = "std", feature = "alloc"))]
259+
&ManagedMap::Owned(ref map) => {
260+
Range::Owned(map.range((Included(key_begin), Excluded(key_end))))
261+
},
262+
}
263+
}
264+
158265
pub fn insert(&mut self, key: K, new_value: V) -> Result<Option<V>, (K, V)> {
159266
match self {
160267
&mut ManagedMap::Borrowed(ref mut pairs) if pairs.len() < 1 =>
@@ -379,6 +486,164 @@ mod test {
379486
assert_eq!(map.get("q"), None);
380487
}
381488

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

0 commit comments

Comments
 (0)