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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#[cfg(feature = "serde-impl")]
use serde::{Serialize, Deserialize};
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serde-impl", derive(Serialize, Deserialize))]
pub struct Candidates {
candidates: Vec<(u32, u32)>,
}
impl Candidates {
pub fn clear(&mut self) {
self.candidates.clear();
}
pub fn push(&mut self, distance: u32, node: u32) {
let pos = self
.candidates
.binary_search_by_key(&distance, |&(d, _)| d)
.unwrap_or_else(|e| e);
self.candidates.insert(pos, (distance, node));
}
pub fn pop(&mut self) -> Option<(u32, u32)> {
self.candidates.pop()
}
}
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serde-impl", derive(Serialize, Deserialize))]
pub struct FixedCandidates {
candidates: Vec<(u32, u32)>,
cap: usize,
}
impl FixedCandidates {
pub fn clear(&mut self) {
self.candidates.clear();
self.cap = 0;
}
pub fn len(&self) -> usize {
self.candidates.len()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn push(&mut self, distance: u32, node: u32) -> bool {
let better = self
.candidates
.last()
.map(|&(df, _)| distance < df)
.unwrap_or(self.cap != 0);
let full = self.len() == self.cap;
let will_add = better | !full;
if will_add {
let pos = self
.candidates
.binary_search_by(|&(d, _)| d.cmp(&distance))
.unwrap_or_else(|e| e);
self.candidates.insert(pos, (distance, node));
if full {
self.pop();
}
}
will_add
}
pub fn pop(&mut self) -> Option<(u32, u32)> {
self.candidates.pop()
}
pub fn set_cap(&mut self, cap: usize) {
self.cap = cap;
if self.candidates.len() > cap {
self.candidates.drain(0..self.candidates.len() - cap);
}
}
pub fn fill_slice<'a>(&self, s: &'a mut [u32]) -> &'a mut [u32] {
let total_fill = std::cmp::min(s.len(), self.len());
for (ix, node) in self
.candidates
.iter()
.map(|(_, n)| n)
.cloned()
.take(total_fill)
.enumerate()
{
s[ix] = node;
}
&mut s[0..total_fill]
}
}
#[cfg(test)]
#[test]
fn test_candidates() {
let mut candidates = FixedCandidates::default();
candidates.set_cap(3);
assert!(candidates.push(1.0f32.to_bits(), 0));
assert!(candidates.push(0.5f32.to_bits(), 1));
assert!(candidates.push(0.000_000_01f32.to_bits(), 2));
assert!(!candidates.push(1.1f32.to_bits(), 3));
assert!(!candidates.push(2.0f32.to_bits(), 4));
assert!(candidates.push(0.000_000_000_1f32.to_bits(), 5));
assert!(!candidates.push(1_000_000.0f32.to_bits(), 6));
assert!(!candidates.push(0.6f32.to_bits(), 7));
assert!(!candidates.push(0.5f32.to_bits(), 8));
assert!(candidates.push(0.000_000_01f32.to_bits(), 9));
assert!(!candidates.push(0.000_000_01f32.to_bits(), 10));
let mut arr = [0; 3];
candidates.fill_slice(&mut arr);
arr[0..2].sort_unstable();
assert_eq!(arr, [5, 9, 2]);
}