1use std::sync::Arc;
7
8#[derive(Clone, Debug, PartialEq)]
13pub enum OrderedSet {
14 Interval { start: u32, end: u32 },
16 Sorted(Arc<[u32]>),
18}
19
20impl OrderedSet {
21 pub fn interval(start: u32, end: u32) -> Self {
26 assert!(start <= end, "interval start must be <= end");
27 OrderedSet::Interval { start, end }
28 }
29
30 pub fn from_sorted(indices: Vec<u32>) -> Self {
45 for window in indices.windows(2) {
47 assert!(
48 window[0] < window[1],
49 "from_sorted requires strictly sorted (no duplicates) input; \
50 found {} >= {}",
51 window[0],
52 window[1]
53 );
54 }
55 OrderedSet::Sorted(indices.into())
56 }
57
58 pub fn len(&self) -> usize {
60 match self {
61 OrderedSet::Interval { start, end } => (end - start) as usize,
62 OrderedSet::Sorted(v) => v.len(),
63 }
64 }
65
66 pub fn is_empty(&self) -> bool {
68 self.len() == 0
69 }
70
71 pub fn contains(&self, idx: u32) -> bool {
73 match self {
74 OrderedSet::Interval { start, end } => idx >= *start && idx < *end,
75 OrderedSet::Sorted(v) => v.binary_search(&idx).is_ok(),
76 }
77 }
78
79 pub fn iter(&self) -> impl Iterator<Item = u32> + '_ {
81 match self {
82 OrderedSet::Interval { start, end } => {
83 let iter: Box<dyn Iterator<Item = u32> + '_> =
85 Box::new(*start..*end);
86 iter
87 }
88 OrderedSet::Sorted(v) => {
89 let iter: Box<dyn Iterator<Item = u32> + '_> =
90 Box::new(v.iter().copied());
91 iter
92 }
93 }
94 }
95
96 pub fn union(&self, other: &Self) -> Self {
101 let mut result = Vec::with_capacity(self.len() + other.len());
102 let mut left = self.iter().peekable();
103 let mut right = other.iter().peekable();
104
105 loop {
106 match (left.peek(), right.peek()) {
107 (None, None) => break,
108 (Some(_), None) => {
109 result.extend(left);
110 break;
111 }
112 (None, Some(_)) => {
113 result.extend(right);
114 break;
115 }
116 (Some(&l), Some(&r)) => {
117 if l < r {
118 result.push(l);
119 left.next();
120 } else if r < l {
121 result.push(r);
122 right.next();
123 } else {
124 result.push(l);
126 left.next();
127 right.next();
128 }
129 }
130 }
131 }
132
133 OrderedSet::Sorted(result.into())
134 }
135
136 pub fn intersection(&self, other: &Self) -> Self {
141 let mut result = Vec::new();
142 let mut left = self.iter().peekable();
143 let mut right = other.iter().peekable();
144
145 loop {
146 match (left.peek(), right.peek()) {
147 (None, _) | (_, None) => break,
148 (Some(&l), Some(&r)) => {
149 if l == r {
150 result.push(l);
151 left.next();
152 right.next();
153 } else if l < r {
154 left.next();
155 } else {
156 right.next();
157 }
158 }
159 }
160 }
161
162 OrderedSet::Sorted(result.into())
163 }
164
165 pub fn difference(&self, other: &Self) -> Self {
170 let mut result = Vec::new();
171 let mut left = self.iter().peekable();
172 let mut right = other.iter().peekable();
173
174 loop {
175 match left.peek() {
176 None => break,
177 Some(&l) => match right.peek() {
178 None => {
179 result.extend(left);
180 break;
181 }
182 Some(&r) => {
183 if l < r {
184 result.push(l);
185 left.next();
186 } else if l == r {
187 left.next();
188 right.next();
189 } else {
190 right.next();
191 }
192 }
193 },
194 }
195 }
196
197 OrderedSet::Sorted(result.into())
198 }
199}
200
201#[cfg(test)]
202mod tests {
203 use super::*;
204
205 #[test]
206 fn test_interval_contains() {
207 let s = OrderedSet::interval(5, 10);
208 assert!(s.contains(5));
209 assert!(s.contains(9));
210 assert!(!s.contains(4));
211 assert!(!s.contains(10));
212 }
213
214 #[test]
215 fn test_interval_len() {
216 let s = OrderedSet::interval(3, 8);
217 assert_eq!(s.len(), 5);
218
219 let empty = OrderedSet::interval(4, 4);
220 assert_eq!(empty.len(), 0);
221 assert!(empty.is_empty());
222 }
223
224 #[test]
225 fn test_sorted_contains() {
226 let s = OrderedSet::from_sorted(vec![1, 3, 5, 7, 9]);
227 assert!(s.contains(1));
228 assert!(s.contains(5));
229 assert!(s.contains(9));
230 assert!(!s.contains(0));
231 assert!(!s.contains(2));
232 assert!(!s.contains(10));
233 }
234
235 #[test]
236 fn test_ordered_set_intersection() {
237 let a = OrderedSet::from_sorted(vec![1, 3, 5, 7, 9]);
238 let b = OrderedSet::from_sorted(vec![2, 3, 5, 8]);
239 let result = a.intersection(&b);
240 assert_eq!(result, OrderedSet::from_sorted(vec![3, 5]));
241 }
242
243 #[test]
244 fn test_ordered_set_union() {
245 let a = OrderedSet::from_sorted(vec![1, 3, 5]);
246 let b = OrderedSet::from_sorted(vec![2, 4, 6]);
247 let result = a.union(&b);
248 assert_eq!(result, OrderedSet::from_sorted(vec![1, 2, 3, 4, 5, 6]));
249 }
250
251 #[test]
252 fn test_ordered_set_difference() {
253 let a = OrderedSet::from_sorted(vec![1, 3, 5, 7, 9]);
254 let b = OrderedSet::from_sorted(vec![3, 5]);
255 let result = a.difference(&b);
256 assert_eq!(result, OrderedSet::from_sorted(vec![1, 7, 9]));
257 }
258
259 #[test]
260 fn test_interval_iter() {
261 let s = OrderedSet::interval(2, 6);
262 let collected: Vec<u32> = s.iter().collect();
263 assert_eq!(collected, vec![2, 3, 4, 5]);
264 }
265
266 #[test]
267 fn test_sorted_iter() {
268 let s = OrderedSet::from_sorted(vec![10, 20, 30]);
269 let collected: Vec<u32> = s.iter().collect();
270 assert_eq!(collected, vec![10, 20, 30]);
271 }
272
273 #[test]
274 fn test_empty_intersection() {
275 let a = OrderedSet::from_sorted(vec![1, 3, 5]);
276 let b = OrderedSet::from_sorted(vec![2, 4, 6]);
277 let result = a.intersection(&b);
278 assert!(result.is_empty());
279 }
280
281 #[test]
282 #[should_panic(expected = "from_sorted requires strictly sorted")]
283 fn test_from_sorted_panics_on_duplicate() {
284 OrderedSet::from_sorted(vec![1, 2, 2, 3]);
287 }
288
289 #[test]
290 #[should_panic(expected = "from_sorted requires strictly sorted")]
291 fn test_from_sorted_panics_on_unsorted() {
292 OrderedSet::from_sorted(vec![3, 1, 2]);
293 }
294
295 #[test]
297 fn test_from_sorted_sort_dedup_pattern() {
298 let mut v = vec![3u32, 1, 2, 1, 3];
299 v.sort_unstable();
300 v.dedup();
301 let s = OrderedSet::from_sorted(v);
302 assert_eq!(s.len(), 3);
303 assert!(s.contains(1));
304 assert!(s.contains(2));
305 assert!(s.contains(3));
306 }
307
308 #[test]
309 fn test_union_with_overlap() {
310 let a = OrderedSet::from_sorted(vec![1, 2, 3]);
311 let b = OrderedSet::from_sorted(vec![2, 3, 4]);
312 let result = a.union(&b);
313 assert_eq!(result, OrderedSet::from_sorted(vec![1, 2, 3, 4]));
314 }
315
316 #[test]
317 fn test_interval_and_sorted_intersection() {
318 let a = OrderedSet::interval(3, 8); let b = OrderedSet::from_sorted(vec![1, 5, 7, 9]);
321 let result = a.intersection(&b);
322 assert_eq!(result, OrderedSet::from_sorted(vec![5, 7]));
323 }
324}