Skip to content

Commit 3845cbc

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

File tree

1 file changed

+278
-2
lines changed

1 file changed

+278
-2
lines changed

src/map.rs

+278-2
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,103 @@ 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+
#[cfg(any(feature = "std", feature = "alloc"))]
124+
Range::Owned(ref mut range) => range.next(),
125+
Range::_Phantom(_) => unreachable!(),
126+
}
127+
}
128+
}
129+
130+
fn binary_search_by_key_range<K, V, Q>(slice: &[Option<(K, V)>], key_begin: &Q, key_end: &Q) -> Result<(usize, usize), ()>
131+
where K: Ord + Borrow<Q>, Q: Ord + ?Sized
132+
{
133+
if slice.len() == 0 {
134+
return Err(())
135+
}
136+
let (mut left, mut right) = (0, slice.len()-1);
137+
138+
//let key = |entry: Option<(K, V)>| { entry.as_ref().map(|&(ref key, _)| key.borrow()) };
139+
macro_rules! key {
140+
( $e:expr) => { $e.as_ref().map(|&(ref key, _)| key.borrow()) }
141+
}
142+
143+
// We cannot use slice.binary_search_by_key instead of each of the
144+
// two loops here, because we need the left-most match (for begin) and
145+
// the right-most match (for end), and the stdlib does not provide
146+
// any of these guarantees.
147+
148+
// Find the beginning
149+
while left < right {
150+
let middle = left + (right-left)/2;
151+
if key!(slice[middle]) < Some(key_begin) {
152+
left = middle+1;
153+
}
154+
else if middle > 0 && key!(slice[middle-1]) >= Some(key_begin) {
155+
right = middle-1;
156+
}
157+
else {
158+
left = middle;
159+
right = middle;
160+
break;
161+
}
162+
}
163+
assert_eq!(left, right);
164+
let begin = left;
165+
if key!(slice[begin]) < Some(key_begin) {
166+
return Err(())
167+
}
168+
169+
// Find the ending
170+
right = slice.len(); // no need to reset left
171+
while left < right {
172+
let middle = left + (right-left+1)/2;
173+
if key!(slice[middle-1]) >= Some(key_end) {
174+
right = middle-1;
175+
}
176+
else if middle < slice.len() && key!(slice[middle]) < Some(key_end) {
177+
left = middle+1;
178+
}
179+
else {
180+
left = middle;
181+
right = middle;
182+
break;
183+
}
184+
}
185+
assert_eq!(left, right);
186+
let end = right;
187+
if end == 0 || key!(slice[end-1]) > Some(key_end) {
188+
return Err(())
189+
}
190+
191+
Ok((begin, end))
192+
}
193+
93194
fn binary_search_by_key<K, V, Q>(slice: &[Option<(K, V)>], key: &Q) -> Result<usize, usize>
94195
where K: Ord + Borrow<Q>, Q: Ord + ?Sized
95196
{
@@ -155,6 +256,23 @@ impl<'a, K: Ord + 'a, V: 'a> ManagedMap<'a, K, V> {
155256
}
156257
}
157258

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

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

0 commit comments

Comments
 (0)