1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use memmap::Mmap;
pub fn binary_search_file(map: &Mmap, word: &str) -> Option<String> {
let mut start = 0_usize;
let mut end = map.len();
let mut iword = String::new();
while start < end {
iword.clear();
let mut mid = (start + end) / 2;
// scan forwards to a newline
while mid < end && map[mid] != b'\n' {
mid += 1;
}
let line_end = mid;
mid -= 1;
while mid > start && map[mid] != b'\n' {
mid -= 1;
}
let line_start = mid;
// mid now points to a newline character so bump it by one to get the start of the line
mid += 1;
// now we extract the word from the line
while mid < end && map[mid] != b' ' {
iword.push(map[mid] as char);
mid += 1;
}
if mid == end {
// gone too far
end = line_start;
continue;
}
if iword.is_empty() {
// may have been a license line
start = line_end;
continue;
}
// and check how this word compares to the one we are searching for
match word.cmp(&iword) {
std::cmp::Ordering::Less => {
end = line_start;
}
std::cmp::Ordering::Equal => {
// read the rest of the line into iword
while map[mid] != b'\n' {
iword.push(map[mid] as char);
mid += 1;
}
// and return the parsed parts
return Some(iword);
}
std::cmp::Ordering::Greater => {
start = line_end;
}
}
}
None
}