Skip to content

Commit 3e01c74

Browse files
committed
just create a binary search slice helper fn
1 parent 89a205b commit 3e01c74

File tree

5 files changed

+72
-114
lines changed

5 files changed

+72
-114
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#[cfg(test)]
2+
mod test;
3+
4+
/// Uses a sorted slice `data: &[E]` as a kind of "multi-map". The
5+
/// `key_fn` extracts a key of type `K` from the data, and this
6+
/// function finds the range of elements that match the key. `data`
7+
/// must have been sorted as if by a call to `sort_by_key` for this to
8+
/// work.
9+
pub fn binary_search_slice<E, K>(data: &'d [E], key_fn: impl Fn(&E) -> K, key: &K) -> &'d [E]
10+
where
11+
K: Ord,
12+
{
13+
let mid = match data.binary_search_by_key(key, &key_fn) {
14+
Ok(mid) => mid,
15+
Err(_) => return &[],
16+
};
17+
18+
// We get back *some* element with the given key -- so
19+
// search backwards to find the *first* one.
20+
//
21+
// (It'd be more efficient to use a "galloping" search
22+
// here, but it's not really worth it for small-ish
23+
// amounts of data.)
24+
let mut start = mid;
25+
while start > 0 {
26+
if key_fn(&data[start - 1]) == *key {
27+
start -= 1;
28+
} else {
29+
break;
30+
}
31+
}
32+
33+
// Now search forward to find the *last* one.
34+
//
35+
// (It'd be more efficient to use a "galloping" search
36+
// here, but it's not really worth it for small-ish
37+
// amounts of data.)
38+
let mut end = mid + 1;
39+
let max = data.len();
40+
while end < max {
41+
if key_fn(&data[end]) == *key {
42+
end += 1;
43+
} else {
44+
break;
45+
}
46+
}
47+
48+
&data[start..end]
49+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use super::*;
2+
3+
type Element = (usize, &'static str);
4+
5+
fn test_map() -> Vec<Element> {
6+
let mut data = vec![(3, "three-a"), (0, "zero"), (3, "three-b"), (22, "twenty-two")];
7+
data.sort_by_key(get_key)
8+
}
9+
10+
fn get_key(data: &Element) -> usize {
11+
data.0
12+
}
13+
14+
#[test]
15+
fn binary_search_slice() {
16+
let map = test_map();
17+
assert_eq!(binary_search_slice(&map, get_key, &0), &[(0, "zero")]);
18+
assert_eq!(binary_search_slice(&map, get_key, &1), &[]);
19+
assert_eq!(binary_search_slice(&map, get_key, &3), &[(3, "three-a"), (3, "three-b")]);
20+
assert_eq!(binary_search_slice(&map, get_key, &22), &[(22, "twenty-two")]);
21+
assert_eq!(binary_search_slice(&map, get_key, &23), &[]);
22+
}

src/librustc_data_structures/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ macro_rules! unlikely {
7272
pub mod macros;
7373
pub mod svh;
7474
pub mod base_n;
75+
pub mod binary_search_util;
7576
pub mod bit_set;
7677
pub mod box_region;
7778
pub mod const_cstr;
@@ -95,7 +96,6 @@ pub mod tiny_list;
9596
pub mod thin_vec;
9697
pub mod transitive_relation;
9798
pub use ena::unify;
98-
pub mod vec_map;
9999
pub mod vec_linked_list;
100100
pub mod work_queue;
101101
pub mod fingerprint;

src/librustc_data_structures/vec_map/mod.rs

Lines changed: 0 additions & 85 deletions
This file was deleted.

src/librustc_data_structures/vec_map/test.rs

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)