1use crate::routing::Token;
2
3#[derive(Debug, Clone)]
11pub struct TokenRing<ElemT> {
12 ring: Vec<(Token, ElemT)>,
13}
14
15impl<ElemT> TokenRing<ElemT> {
16 pub(crate) const fn new_empty() -> TokenRing<ElemT> {
17 Self { ring: Vec::new() }
18 }
19
20 pub(crate) fn new(ring_iter: impl Iterator<Item = (Token, ElemT)>) -> TokenRing<ElemT> {
21 let mut ring: Vec<(Token, ElemT)> = ring_iter.collect();
22 ring.sort_by(|a, b| a.0.cmp(&b.0));
23 TokenRing { ring }
24 }
25
26 pub fn iter(&self) -> impl Iterator<Item = &(Token, ElemT)> {
28 self.ring.iter()
29 }
30
31 pub fn ring_range_full(&self, token: Token) -> impl Iterator<Item = &(Token, ElemT)> {
36 let binary_search_index: usize = match self.ring.binary_search_by(|e| e.0.cmp(&token)) {
37 Ok(exact_match_index) => exact_match_index,
38 Err(first_greater_index) => first_greater_index,
39 };
40
41 self.ring[binary_search_index..]
42 .iter()
43 .chain(self.ring.iter())
44 .take(self.ring.len())
45 }
46
47 pub fn ring_range(&self, token: Token) -> impl Iterator<Item = &ElemT> {
53 self.ring_range_full(token).map(|(_t, e)| e)
54 }
55
56 pub fn get_elem_for_token(&self, token: Token) -> Option<&ElemT> {
58 self.ring_range(token).next()
59 }
60
61 pub fn len(&self) -> usize {
63 self.ring.len()
64 }
65
66 pub fn is_empty(&self) -> bool {
68 self.ring.is_empty()
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::TokenRing;
75 use crate::{routing::Token, test_utils::setup_tracing};
76
77 #[test]
78 fn test_token_ring() {
79 setup_tracing();
80 let ring_data = [
81 (Token::new(-30), -3),
82 (Token::new(-20), -2),
83 (Token::new(-10), -1),
84 (Token::new(0), 0),
85 (Token::new(10), 1),
86 (Token::new(20), 2),
87 (Token::new(30), 3),
88 ];
89
90 let ring: TokenRing<i32> = TokenRing::new(ring_data.into_iter());
91
92 assert_eq!(
93 ring.ring_range(Token::new(-35))
94 .cloned()
95 .collect::<Vec<i32>>(),
96 vec![-3, -2, -1, 0, 1, 2, 3]
97 );
98
99 assert_eq!(
100 ring.ring_range(Token::new(-30))
101 .cloned()
102 .collect::<Vec<i32>>(),
103 vec![-3, -2, -1, 0, 1, 2, 3]
104 );
105
106 assert_eq!(
107 ring.ring_range(Token::new(-25))
108 .cloned()
109 .collect::<Vec<i32>>(),
110 vec![-2, -1, 0, 1, 2, 3, -3]
111 );
112
113 assert_eq!(
114 ring.ring_range(Token::new(-20))
115 .cloned()
116 .collect::<Vec<i32>>(),
117 vec![-2, -1, 0, 1, 2, 3, -3]
118 );
119
120 assert_eq!(
121 ring.ring_range(Token::new(-15))
122 .cloned()
123 .collect::<Vec<i32>>(),
124 vec![-1, 0, 1, 2, 3, -3, -2]
125 );
126
127 assert_eq!(
128 ring.ring_range(Token::new(-10))
129 .cloned()
130 .collect::<Vec<i32>>(),
131 vec![-1, 0, 1, 2, 3, -3, -2]
132 );
133
134 assert_eq!(
135 ring.ring_range(Token::new(-5))
136 .cloned()
137 .collect::<Vec<i32>>(),
138 vec![0, 1, 2, 3, -3, -2, -1]
139 );
140
141 assert_eq!(
142 ring.ring_range(Token::new(0))
143 .cloned()
144 .collect::<Vec<i32>>(),
145 vec![0, 1, 2, 3, -3, -2, -1]
146 );
147
148 assert_eq!(
149 ring.ring_range(Token::new(5))
150 .cloned()
151 .collect::<Vec<i32>>(),
152 vec![1, 2, 3, -3, -2, -1, 0]
153 );
154
155 assert_eq!(
156 ring.ring_range(Token::new(10))
157 .cloned()
158 .collect::<Vec<i32>>(),
159 vec![1, 2, 3, -3, -2, -1, 0]
160 );
161
162 assert_eq!(
163 ring.ring_range(Token::new(15))
164 .cloned()
165 .collect::<Vec<i32>>(),
166 vec![2, 3, -3, -2, -1, 0, 1]
167 );
168
169 assert_eq!(
170 ring.ring_range(Token::new(20))
171 .cloned()
172 .collect::<Vec<i32>>(),
173 vec![2, 3, -3, -2, -1, 0, 1]
174 );
175
176 assert_eq!(
177 ring.ring_range(Token::new(25))
178 .cloned()
179 .collect::<Vec<i32>>(),
180 vec![3, -3, -2, -1, 0, 1, 2]
181 );
182
183 assert_eq!(
184 ring.ring_range(Token::new(30))
185 .cloned()
186 .collect::<Vec<i32>>(),
187 vec![3, -3, -2, -1, 0, 1, 2]
188 );
189
190 assert_eq!(
191 ring.ring_range(Token::new(35))
192 .cloned()
193 .collect::<Vec<i32>>(),
194 vec![-3, -2, -1, 0, 1, 2, 3]
195 );
196 }
197}