1
2
3#[derive(Debug, Clone)]
7pub struct IWRRSelector<const LEN: usize> {
8 pos: usize, round: u8, max_weight: u8, weights: [u8; LEN], }
13
14impl<const LEN: usize> Default for IWRRSelector<LEN> {
15 fn default() -> Self {
17 Self::new([1; LEN])
18 }
19}
20
21impl<const LEN: usize> IWRRSelector<LEN> {
22 pub fn new(weights: [u8; LEN]) -> Self {
24 let mut max_weight = 0;
25 for weight in weights {
26 if weight >= u8::MAX {
27 panic!("Create IWRRSelector failed, weight: {}, reason: invalid weight",
28 weight);
29 }
30
31 if max_weight < weight {
32 max_weight = weight;
34 }
35 }
36
37 IWRRSelector {
38 round: 0,
39 max_weight,
40 pos: 0,
41 weights,
42 }
43 }
44
45 pub const fn len(&self) -> usize {
47 LEN
48 }
49
50 pub fn round(&self) -> u8 {
52 self.round
53 }
54
55 pub fn max_weight(&self) -> u8 {
57 self.max_weight
58 }
59
60 pub fn try_weight(&self, index: usize) -> Option<u8> {
62 if index >= self.len() {
63 None
64 } else {
65 Some(self.weights[index])
66 }
67 }
68
69 pub fn change_weight(&mut self,
71 index: usize,
72 weight: u8) -> Option<u8> {
73 if weight >= u8::MAX {
74 return None;
75 }
76
77 if let Some(old) = self.try_weight(index) {
78 self.weights[index] = weight;
79 Some(old)
80 } else {
81 None
82 }
83 }
84
85 pub fn pos(&self) -> usize {
87 self.pos
88 }
89
90 pub fn select(&mut self) -> usize {
92 loop {
93 for pos in self.pos..self.len() {
94 let weight = self.weights[pos];
95 if weight == 0 || weight < self.round {
96 self.pos += 1;
98 continue;
99 }
100
101 self.pos += 1;
103 return pos;
104 }
105
106 if self.round > self.max_weight {
107 self.reset();
109 } else {
110 self.pos = 0;
112 self.round += 1;
113 }
114 }
115 }
116
117 pub fn reset(&mut self) {
119 self.round = 0;
120 self.pos = 0;
121 }
122}
123
124#[derive(Debug, Clone)]
128pub struct IWRRSelectorByWider<const LEN: usize> {
129 pos: usize, round: usize, max_weight: usize, weights: [usize; LEN], }
134
135impl<const LEN: usize> Default for IWRRSelectorByWider<LEN> {
136 fn default() -> Self {
138 Self::new([1; LEN])
139 }
140}
141
142impl<const LEN: usize> IWRRSelectorByWider<LEN> {
143 pub fn new(weights: [usize; LEN]) -> Self {
145 let mut max_weight = 0;
146 for weight in weights {
147 if weight >= usize::MAX {
148 panic!("Create IWRRSelector failed, weight: {}, reason: invalid weight",
149 weight);
150 }
151
152 if max_weight < weight {
153 max_weight = weight;
155 }
156 }
157
158 IWRRSelectorByWider {
159 round: 0,
160 max_weight,
161 pos: 0,
162 weights,
163 }
164 }
165
166 pub const fn len(&self) -> usize {
168 LEN
169 }
170
171 pub fn round(&self) -> usize {
173 self.round
174 }
175
176 pub fn max_weight(&self) -> usize {
178 self.max_weight
179 }
180
181 pub fn try_weight(&self, index: usize) -> Option<usize> {
183 if index >= self.len() {
184 None
185 } else {
186 Some(self.weights[index])
187 }
188 }
189
190 pub fn change_weight(&mut self,
192 index: usize,
193 weight: usize) -> Option<usize> {
194 if weight >= usize::MAX {
195 return None;
196 }
197
198 if let Some(old) = self.try_weight(index) {
199 self.weights[index] = weight;
200 Some(old)
201 } else {
202 None
203 }
204 }
205
206 pub fn pos(&self) -> usize {
208 self.pos
209 }
210
211 pub fn select(&mut self) -> usize {
213 loop {
214 for pos in self.pos..self.len() {
215 let weight = self.weights[pos];
216 if weight == 0 || weight < self.round {
217 self.pos += 1;
219 continue;
220 }
221
222 self.pos += 1;
224 return pos;
225 }
226
227 if self.round > self.max_weight {
228 self.reset();
230 } else {
231 self.pos = 0;
233 self.round += 1;
234 }
235 }
236 }
237
238 pub fn reset(&mut self) {
240 self.round = 0;
241 self.pos = 0;
242 }
243}