File tree 1 file changed +40
-20
lines changed
src/librustc_data_structures/binary_search_util
1 file changed +40
-20
lines changed Original file line number Diff line number Diff line change @@ -14,35 +14,55 @@ where
14
14
Ok ( mid) => mid,
15
15
Err ( _) => return & [ ] ,
16
16
} ;
17
+ let size = data. len ( ) ;
17
18
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.)
19
+ // We get back *some* element with the given key -- so do
20
+ // a galloping search backwards to find the *first* one.
24
21
let mut start = mid;
25
- while start > 0 {
26
- if key_fn ( & data[ start - 1 ] ) == * key {
27
- start -= 1 ;
28
- } else {
22
+ let mut previous = mid;
23
+ let mut step = 1 ;
24
+ loop {
25
+ start = start. saturating_sub ( step) ;
26
+ if start == 0 || key_fn ( & data[ start] ) != * key {
29
27
break ;
30
28
}
29
+ previous = start;
30
+ step *= 2 ;
31
+ }
32
+ step = previous - start;
33
+ while step > 1 {
34
+ let half = step / 2 ;
35
+ let mid = start + half;
36
+ if key_fn ( & data[ mid] ) != * key {
37
+ start = mid;
38
+ }
39
+ step -= half;
40
+ }
41
+ // adjust by one if we have overshot
42
+ if start < size && key_fn ( & data[ start] ) != * key {
43
+ start += 1 ;
31
44
}
32
45
33
46
// 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 {
47
+ let mut end = mid;
48
+ let mut previous = mid;
49
+ let mut step = 1 ;
50
+ loop {
51
+ end = end. saturating_add ( step) . min ( size) ;
52
+ if end == size || key_fn ( & data[ end] ) != * key {
44
53
break ;
45
54
}
55
+ previous = end;
56
+ step *= 2 ;
57
+ }
58
+ step = end - previous;
59
+ while step > 1 {
60
+ let half = step / 2 ;
61
+ let mid = end - half;
62
+ if key_fn ( & data[ mid] ) != * key {
63
+ end = mid;
64
+ }
65
+ step -= half;
46
66
}
47
67
48
68
& data[ start..end]
You can’t perform that action at this time.
0 commit comments