traitgraph_algo/dijkstra/
epoch_array_dijkstra_node_weight_array.rs1use crate::dijkstra::{DijkstraWeight, NodeWeightArray};
2
3pub struct EpochArray {
8 epochs: Vec<u32>,
9 current_epoch: u32,
10}
11
12impl EpochArray {
13 pub fn new(len: usize) -> Self {
15 Self {
16 epochs: vec![0; len],
17 current_epoch: 1,
18 }
19 }
20
21 pub fn clear(&mut self) {
23 if self.current_epoch == u32::MAX {
24 for epoch in self.epochs.iter_mut() {
25 *epoch = 0;
26 }
27 self.current_epoch = 1;
28 } else {
29 self.current_epoch += 1;
30 }
31 }
32
33 #[inline]
37 pub fn update(&mut self, index: usize) -> bool {
38 unsafe {
39 let result = *self.epochs.get_unchecked(index) == self.current_epoch;
40 *self.epochs.get_unchecked_mut(index) = self.current_epoch;
41 result
42 }
43 }
45
46 #[inline]
50 pub fn get(&self, index: usize) -> bool {
51 unsafe { *self.epochs.get_unchecked(index) == self.current_epoch }
52 }
53
54 #[inline]
58 pub fn get_and_update(&mut self, index: usize) -> bool {
59 let epoch = unsafe { self.epochs.get_unchecked_mut(index) };
60 if *epoch == self.current_epoch {
61 true
62 } else {
63 *epoch = self.current_epoch;
64 false
65 }
66 }
67}
68
69pub struct EpochNodeWeightArray<WeightType> {
72 weights: Vec<WeightType>,
73 epochs: EpochArray,
74 size: usize,
75}
76
77impl<WeightType: DijkstraWeight> EpochNodeWeightArray<WeightType> {
78 #[inline]
79 fn make_current(&mut self, node_index: usize) {
80 if !self.epochs.get_and_update(node_index) {
81 self.weights[node_index] = WeightType::infinity();
82 self.size += 1;
83 }
84 }
85}
86
87impl<WeightType: DijkstraWeight + Copy> NodeWeightArray<WeightType>
88 for EpochNodeWeightArray<WeightType>
89{
90 fn new(len: usize) -> Self {
91 Self {
92 weights: vec![WeightType::infinity(); len],
93 epochs: EpochArray::new(len),
94 size: 0,
95 }
96 }
97
98 #[inline]
99 fn get(&self, node_index: usize) -> WeightType {
100 if self.epochs.get(node_index) {
101 self.weights[node_index]
102 } else {
103 WeightType::infinity()
104 }
105 }
106
107 #[inline]
108 fn get_mut<'this: 'result, 'result>(
109 &'this mut self,
110 node_index: usize,
111 ) -> &'result mut WeightType {
112 self.make_current(node_index);
113 &mut self.weights[node_index]
114 }
115
116 #[inline]
117 fn set(&mut self, node_index: usize, weight: WeightType) {
118 self.weights[node_index] = weight;
119 if !self.epochs.update(node_index) {
120 self.size += 1;
121 }
122 }
123
124 fn clear(&mut self) {
125 self.epochs.clear();
126 self.size = 0;
127 }
128
129 fn size(&self) -> usize {
130 self.size
131 }
132}