1use core::mem::MaybeUninit;
4
5pub struct FrodoRing<T, const N: usize> {
13 buffer: [MaybeUninit<T>; N],
15 occupied: [bool; N],
17 head: usize,
19 cap: usize,
23}
24
25impl<T: std::fmt::Debug, const N: usize> std::fmt::Debug for FrodoRing<T, N> {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 writeln!(
28 f,
29 "Ring: occupied = {}, head = {}, capacity = {}",
30 self.occupied.iter().filter(|v| **v).count(),
31 self.head,
32 self.cap
33 )?;
34 writeln!(f, "Elements: [")?;
35 for i in 0..N {
36 if self.occupied[i] {
37 writeln!(f, "\t{:?},", unsafe { self.buffer[i].assume_init_ref() })?;
38 } else {
39 writeln!(f, "\tNone,")?;
40 }
41 }
42 writeln!(f, "]")?;
43
44 Ok(())
45 }
46}
47
48impl<T, const N: usize> Default for FrodoRing<T, N> {
49 fn default() -> Self {
50 Self {
51 buffer: unsafe { MaybeUninit::uninit().assume_init() },
52 occupied: [false; N],
53 head: 0,
54 cap: 0,
55 }
56 }
57}
58
59impl<T, const N: usize> FrodoRing<T, N> {
60 fn real_pos(&self, naive_pos: usize) -> usize {
62 (self.head + naive_pos) % N
63 }
64
65 fn neg_pos(&self, naive_pos: usize) -> usize {
67 (self.head + N - naive_pos) % N
68 }
69
70 pub fn new() -> Self {
72 Self::default()
73 }
74
75 pub fn used(&self) -> usize {
77 self.cap
78 }
79
80 pub fn len(&self) -> usize {
82 self.occupied.iter().filter(|v| **v).count()
83 }
84
85 pub fn is_empty(&self) -> bool {
87 self.cap == 0
88 }
89
90 pub fn at(&self, naive_pos: isize) -> Option<&T> {
99 if self.cap == 0 || naive_pos >= self.cap as isize || naive_pos < -(self.cap as isize) {
100 return None;
101 }
102
103 let real_pos = if naive_pos >= 0 {
104 self.real_pos(naive_pos as usize)
105 } else {
106 self.neg_pos((-naive_pos) as usize)
107 };
108
109 if self.occupied[real_pos] {
110 Some(unsafe { self.buffer[real_pos].assume_init_ref() })
111 } else {
112 None
113 }
114 }
115
116 pub fn get(&self, pos: usize) -> Option<&T> {
124 if pos >= self.cap || self.cap == 0 {
125 return None;
126 }
127
128 let mut cntr = 0usize;
129 let mut real_pos = self.head;
130 let max_cntr = self.len();
131
132 while cntr < max_cntr {
133 if self.occupied[real_pos] {
134 if cntr == pos {
135 return Some(unsafe { self.buffer[real_pos].assume_init_ref() });
136 } else {
137 cntr += 1;
138 }
139 }
140 real_pos = (real_pos + 1) % N;
141 }
142
143 None
144 }
145
146 pub fn iter(&self) -> FrodoRingIterator<'_, T, N> {
148 FrodoRingIterator {
149 ring: self,
150 naive_pos: 0,
151 }
152 }
153
154 pub fn position<F: Fn(&T) -> bool>(&self, f: F) -> Option<isize> {
158 let mut real_pos = self.head;
159 let last_pos = self.neg_pos(1);
160
161 while real_pos <= last_pos {
162 if self.occupied[real_pos] && f(unsafe { self.buffer[real_pos].assume_init_ref() }) {
163 return Some(real_pos as isize);
164 }
165 real_pos = (real_pos + 1) % N;
166 }
167
168 None
169 }
170
171 pub fn push(&mut self, item: T) -> Result<(), T> {
176 let real_pos = if self.cap == N {
177 if self.occupied.iter().all(|o| *o) {
178 return Err(item);
179 } else if let Some(tail) = self.compact() {
180 tail
181 } else {
182 return Err(item);
183 }
184 } else {
185 self.real_pos(self.cap)
186 };
187
188 self.buffer[real_pos].write(item);
189 self.occupied[real_pos] = true;
190 self.cap += 1;
191 Ok(())
192 }
193
194 pub fn pick(&mut self) -> Option<T> {
196 self.remove_at(0)
197 }
198
199 pub fn remove_at(&mut self, naive_pos: isize) -> Option<T> {
201 if self.cap == 0 || naive_pos >= self.cap as isize || naive_pos < -(self.cap as isize) {
202 return None;
203 }
204
205 let real_pos = if naive_pos >= 0 {
206 self.real_pos(naive_pos as usize)
207 } else {
208 self.neg_pos((-naive_pos) as usize)
209 };
210
211 if self.occupied[real_pos] {
212 self.occupied[real_pos] = false;
213
214 if real_pos == self.head {
215 loop {
216 self.head = (self.head + 1) % N;
217 self.cap -= 1;
218 if self.occupied[self.head] || self.cap == 0 {
219 break;
220 }
221 }
222 } else if real_pos == self.neg_pos(1) {
223 loop {
224 if self.occupied[self.real_pos(self.cap - 1)] || self.cap == 1 {
225 break;
226 }
227 self.cap -= 1;
228 }
229 }
230
231 Some(unsafe { self.buffer[real_pos].assume_init_read() })
232 } else {
233 None
234 }
235 }
236
237 pub fn remove(&mut self, pos: usize) -> Option<T> {
239 if pos >= self.cap || self.cap == 0 {
240 return None;
241 }
242
243 let mut cntr = 0usize;
244 let mut real_pos = self.head;
245 let max_cntr = self.len();
246
247 while cntr < max_cntr {
248 if self.occupied[real_pos] {
249 if cntr == pos {
250 self.occupied[real_pos] = false;
251
252 if real_pos == self.head {
253 loop {
254 self.head = (self.head + 1) % N;
255 self.cap -= 1;
256 if self.occupied[self.head] || self.cap == 0 {
257 break;
258 }
259 }
260 } else if real_pos == self.neg_pos(1) {
261 loop {
262 if self.occupied[self.real_pos(self.cap - 1)] || self.cap == 1 {
263 break;
264 }
265 self.cap -= 1;
266 }
267 }
268
269 return Some(unsafe { self.buffer[real_pos].assume_init_read() });
270 } else {
271 cntr += 1;
272 }
273 }
274 real_pos = (real_pos + 1) % N;
275 }
276
277 None
278 }
279
280 fn compact(&mut self) -> Option<usize> {
286 assert_eq!(self.cap, N);
287
288 let mut read_pos = 0usize;
289 let mut read_real_pos = self.real_pos(read_pos);
290
291 let mut write_pos = 0usize;
292 let mut write_real_pos = self.real_pos(write_pos);
293 let mut moved = 0usize;
294
295 let last_pos = self.cap - 1;
296
297 while read_pos <= last_pos {
298 if read_pos == write_pos && self.occupied[read_real_pos] {
300 read_pos += 1;
301 read_real_pos = self.real_pos(read_pos);
302 write_pos = read_pos;
303 write_real_pos = read_real_pos;
304 continue;
305 }
306
307 if !self.occupied[read_real_pos] {
309 read_pos += 1;
310 read_real_pos = self.real_pos(read_pos);
311 moved += 1;
312 } else {
313 self.occupied[read_real_pos] = false;
314 self.occupied[write_real_pos] = true;
315 let item = unsafe { self.buffer[read_real_pos].assume_init_read() };
316 self.buffer[write_real_pos].write(item);
317
318 read_pos += 1;
319 read_real_pos = self.real_pos(read_pos);
320 write_pos += 1;
321 write_real_pos = self.real_pos(write_pos);
322 }
323 }
324
325 if moved > 0 {
326 self.cap -= moved;
327 Some(self.real_pos(self.cap))
328 } else {
329 None
330 }
331 }
332}
333
334pub struct FrodoRingIterator<'ring, T, const N: usize> {
338 ring: &'ring FrodoRing<T, N>,
339 naive_pos: usize,
340}
341
342impl<'ring, T: std::fmt::Debug, const N: usize> Iterator for FrodoRingIterator<'ring, T, N> {
343 type Item = &'ring T;
344
345 fn next(&mut self) -> Option<Self::Item> {
346 loop {
347 if self.naive_pos == self.ring.cap {
348 return None;
349 }
350 let res = self.ring.at(self.naive_pos as isize);
351 self.naive_pos += 1;
352 if res.is_some() {
353 return res;
354 }
355 }
356 }
357}
358
359#[cfg(test)]
360mod tests {
361 use super::*;
362
363 #[test]
364 fn test_1() {
365 let mut ring = FrodoRing::<u8, 4>::new();
366
367 assert!(ring.push(0x1).is_ok());
368 assert!(ring.push(0x2).is_ok());
369 assert!(ring.push(0x3).is_ok());
370 assert!(ring.push(0x4).is_ok());
371
372 assert!(ring.push(0x5).is_err());
373 }
374
375 #[test]
376 fn test_2() {
377 let mut ring = FrodoRing::<u8, 4>::new();
378
379 assert!(ring.push(0x1).is_ok());
380 assert!(ring.push(0x2).is_ok());
381 assert!(ring.push(0x3).is_ok());
382 assert!(ring.push(0x4).is_ok());
383
384 assert_eq!(ring.at(0), Some(&0x1));
385 assert_eq!(ring.at(1), Some(&0x2));
386 assert_eq!(ring.at(2), Some(&0x3));
387 assert_eq!(ring.at(3), Some(&0x4));
388 assert_eq!(ring.at(-1), Some(&0x4));
389 assert_eq!(ring.at(-2), Some(&0x3));
390 assert_eq!(ring.at(-3), Some(&0x2));
391 assert_eq!(ring.at(-4), Some(&0x1));
392
393 assert_eq!(ring.at(4), None);
394 assert_eq!(ring.at(-5), None);
395 }
396
397 #[test]
398 fn test_3() {
399 let mut ring = FrodoRing::<u8, 4>::new();
400
401 assert!(ring.push(0x1).is_ok());
402 assert!(ring.push(0x2).is_ok());
403 assert!(ring.push(0x3).is_ok());
404 assert!(ring.push(0x4).is_ok());
405
406 assert_eq!(ring.remove_at(1), Some(0x2));
407 assert_eq!(ring.at(0), Some(&0x1));
408 assert_eq!(ring.at(1), None);
409 assert_eq!(ring.at(2), Some(&0x3));
410 assert_eq!(ring.at(3), Some(&0x4));
411 }
412
413 #[test]
414 fn test_4() {
415 let mut ring = FrodoRing::<u8, 4>::new();
416
417 assert!(ring.push(0x1).is_ok());
418 assert!(ring.push(0x2).is_ok());
419 assert!(ring.push(0x3).is_ok());
420 assert!(ring.push(0x4).is_ok());
421
422 assert_eq!(ring.remove_at(1), Some(0x2));
423 assert_eq!(ring.at(0), Some(&0x1));
424 assert_eq!(ring.at(1), None);
425 assert_eq!(ring.at(2), Some(&0x3));
426 assert_eq!(ring.at(3), Some(&0x4));
427
428 assert!(ring.push(0x5).is_ok());
429 assert_eq!(ring.at(0), Some(&0x1));
430 assert_eq!(ring.at(1), Some(&0x3));
431 assert_eq!(ring.at(2), Some(&0x4));
432 assert_eq!(ring.at(3), Some(&0x5));
433 }
434
435 #[test]
436 fn massive() {
437 let mut ring = FrodoRing::<u8, 4>::new();
438
439 assert!(ring.push(0x1).is_ok());
440 assert!(ring.push(0x2).is_ok());
441 assert!(ring.push(0x3).is_ok());
442 assert!(ring.push(0x4).is_ok());
443
444 assert_eq!(ring.remove_at(1), Some(0x2));
445 assert_eq!(ring.used(), 4);
446 assert_eq!(ring.at(0), Some(&0x1));
447 assert_eq!(ring.at(1), None);
448 assert_eq!(ring.at(2), Some(&0x3));
449 assert_eq!(ring.at(3), Some(&0x4));
450
451 assert!(ring.push(0x5).is_ok());
452 assert_eq!(ring.used(), 4);
453 assert_eq!(ring.at(0), Some(&0x1));
454 assert_eq!(ring.at(1), Some(&0x3));
455 assert_eq!(ring.at(2), Some(&0x4));
456 assert_eq!(ring.at(3), Some(&0x5));
457
458 assert_eq!(ring.remove_at(0), Some(0x1));
459 assert_eq!(ring.used(), 3);
460 assert_eq!(ring.at(0), Some(&0x3));
461 assert_eq!(ring.at(1), Some(&0x4));
462 assert_eq!(ring.at(2), Some(&0x5));
463 assert_eq!(ring.at(3), None);
464
465 assert_eq!(ring.remove_at(1), Some(0x4));
466 assert_eq!(ring.used(), 3);
467 assert_eq!(ring.at(0), Some(&0x3));
468 assert_eq!(ring.at(1), None);
469 assert_eq!(ring.at(2), Some(&0x5));
470 assert_eq!(ring.at(3), None);
471
472 assert!(ring.push(0x6).is_ok());
473 assert_eq!(ring.used(), 4);
474 assert_eq!(ring.at(0), Some(&0x3));
475 assert_eq!(ring.at(1), None);
476 assert_eq!(ring.at(2), Some(&0x5));
477 assert_eq!(ring.at(3), Some(&0x6));
478
479 assert!(ring.push(0x7).is_ok());
480 assert_eq!(ring.used(), 4);
481 assert_eq!(ring.at(0), Some(&0x3));
482 assert_eq!(ring.at(1), Some(&0x5));
483 assert_eq!(ring.at(2), Some(&0x6));
484 assert_eq!(ring.at(3), Some(&0x7));
485
486 assert!(ring.push(0x8).is_err());
487 }
488
489 #[test]
490 fn iter() {
491 let mut ring = FrodoRing::<u8, 4>::new();
492
493 assert!(ring.push(0x1).is_ok());
494 assert!(ring.push(0x2).is_ok());
495 assert!(ring.push(0x3).is_ok());
496 assert!(ring.push(0x4).is_ok());
497
498 assert_eq!(ring.remove_at(1), Some(0x2));
499 let mut it = ring.iter();
500 assert_eq!(it.next(), Some(&0x1));
501 assert_eq!(it.next(), Some(&0x3));
502 assert_eq!(it.next(), Some(&0x4));
503 assert_eq!(it.next(), None);
504
505 assert!(ring.push(0x5).is_ok());
506 let mut it = ring.iter();
507 assert_eq!(it.next(), Some(&0x1));
508 assert_eq!(it.next(), Some(&0x3));
509 assert_eq!(it.next(), Some(&0x4));
510 assert_eq!(it.next(), Some(&0x5));
511 assert_eq!(it.next(), None);
512
513 assert_eq!(ring.remove_at(0), Some(0x1));
514 let mut it = ring.iter();
515 assert_eq!(it.next(), Some(&0x3));
516 assert_eq!(it.next(), Some(&0x4));
517 assert_eq!(it.next(), Some(&0x5));
518 assert_eq!(it.next(), None);
519
520 assert_eq!(ring.remove_at(1), Some(0x4));
521 let mut it = ring.iter();
522 assert_eq!(it.next(), Some(&0x3));
523 assert_eq!(it.next(), Some(&0x5));
524 assert_eq!(ring.at(3), None);
525
526 assert!(ring.push(0x6).is_ok());
527 let mut it = ring.iter();
528 assert_eq!(it.next(), Some(&0x3));
529 assert_eq!(it.next(), Some(&0x5));
530 assert_eq!(it.next(), Some(&0x6));
531 assert_eq!(it.next(), None);
532 assert_eq!(it.next(), None);
533 assert_eq!(it.next(), None);
534
535 assert!(ring.push(0x7).is_ok());
536 let mut it = ring.iter();
537 assert_eq!(it.next(), Some(&0x3));
538 assert_eq!(it.next(), Some(&0x5));
539 assert_eq!(it.next(), Some(&0x6));
540 assert_eq!(it.next(), Some(&0x7));
541 assert_eq!(it.next(), None);
542 }
543
544 #[test]
545 fn test_5() {
546 let mut ring = FrodoRing::<u8, 4>::new();
547
548 assert!(ring.push(0x1).is_ok());
549 assert!(ring.push(0x2).is_ok());
550 assert!(ring.push(0x3).is_ok());
551 assert!(ring.push(0x4).is_ok());
552
553 assert_eq!(ring.remove_at(1), Some(0x2));
554 assert_eq!(ring.used(), 4);
555 assert_eq!(ring.at(0), Some(&0x1));
556 assert_eq!(ring.at(1), None);
557 assert_eq!(ring.at(2), Some(&0x3));
558 assert_eq!(ring.at(3), Some(&0x4));
559
560 assert_eq!(ring.remove_at(2), Some(0x3));
561 assert_eq!(ring.used(), 4);
562 assert_eq!(ring.at(0), Some(&0x1));
563 assert_eq!(ring.at(1), None);
564 assert_eq!(ring.at(2), None);
565 assert_eq!(ring.at(3), Some(&0x4));
566
567 assert_eq!(ring.remove_at(0), Some(0x1));
568 assert_eq!(ring.used(), 1);
569 assert_eq!(ring.at(0), Some(&0x4));
570 assert_eq!(ring.at(1), None);
571 assert_eq!(ring.at(2), None);
572 assert_eq!(ring.at(3), None);
573 }
574
575 #[test]
576 fn test_6() {
577 let mut ring = FrodoRing::<u8, 4>::new();
578
579 assert!(ring.push(0x1).is_ok());
580 assert!(ring.push(0x2).is_ok());
581 assert!(ring.push(0x3).is_ok());
582 assert!(ring.push(0x4).is_ok());
583
584 assert_eq!(ring.remove_at(1), Some(0x2));
585 assert_eq!(ring.used(), 4);
586 assert_eq!(ring.at(0), Some(&0x1));
587 assert_eq!(ring.at(1), None);
588 assert_eq!(ring.at(2), Some(&0x3));
589 assert_eq!(ring.at(3), Some(&0x4));
590
591 assert_eq!(ring.remove_at(2), Some(0x3));
592 assert_eq!(ring.used(), 4);
593 assert_eq!(ring.at(0), Some(&0x1));
594 assert_eq!(ring.at(1), None);
595 assert_eq!(ring.at(2), None);
596 assert_eq!(ring.at(3), Some(&0x4));
597
598 assert_eq!(ring.remove_at(3), Some(0x4));
599 assert_eq!(ring.used(), 1);
600 assert_eq!(ring.at(0), Some(&0x1));
601 assert_eq!(ring.at(1), None);
602 assert_eq!(ring.at(2), None);
603 assert_eq!(ring.at(3), None);
604 }
605
606 #[test]
607 fn test_7() {
608 let mut ring = FrodoRing::<u8, 4>::new();
609
610 assert!(ring.push(0x1).is_ok());
611 assert!(ring.push(0x2).is_ok());
612 assert!(ring.push(0x3).is_ok());
613 assert!(ring.push(0x4).is_ok());
614
615 assert_eq!(ring.pick(), Some(0x1));
616 assert_eq!(ring.pick(), Some(0x2));
617 assert_eq!(ring.pick(), Some(0x3));
618 assert_eq!(ring.pick(), Some(0x4));
619 assert_eq!(ring.pick(), None);
620 }
621
622 #[test]
623 fn test_8() {
624 let mut ring = FrodoRing::<u8, 4>::new();
625
626 assert!(ring.push(0x1).is_ok());
627 assert!(ring.push(0x2).is_ok());
628 assert!(ring.push(0x3).is_ok());
629 assert!(ring.push(0x4).is_ok());
630
631 assert_eq!(ring.at(0), Some(&0x1));
632 assert_eq!(ring.at(1), Some(&0x2));
633 assert_eq!(ring.at(2), Some(&0x3));
634 assert_eq!(ring.at(3), Some(&0x4));
635 assert_eq!(ring.get(0), Some(&0x1));
636 assert_eq!(ring.get(1), Some(&0x2));
637 assert_eq!(ring.get(2), Some(&0x3));
638 assert_eq!(ring.get(3), Some(&0x4));
639
640 assert_eq!(ring.get(4), None);
641
642 assert_eq!(ring.remove_at(1), Some(0x2));
643 assert_eq!(ring.used(), 4);
644 assert_eq!(ring.at(0), Some(&0x1));
645 assert_eq!(ring.at(1), None);
646 assert_eq!(ring.at(2), Some(&0x3));
647 assert_eq!(ring.at(3), Some(&0x4));
648 assert_eq!(ring.get(0), Some(&0x1));
649 assert_eq!(ring.get(1), Some(&0x3));
650 assert_eq!(ring.get(2), Some(&0x4));
651 assert_eq!(ring.get(3), None);
652 }
653
654 #[test]
655 fn test_9() {
656 let mut ring = FrodoRing::<u8, 4>::new();
657
658 assert!(ring.push(0x1).is_ok());
659 assert!(ring.push(0x2).is_ok());
660 assert!(ring.push(0x3).is_ok());
661 assert!(ring.push(0x4).is_ok());
662
663 assert_eq!(ring.remove(1), Some(0x2));
664 assert_eq!(ring.used(), 4);
665 assert_eq!(ring.at(0), Some(&0x1));
666 assert_eq!(ring.at(1), None);
667 assert_eq!(ring.at(2), Some(&0x3));
668 assert_eq!(ring.at(3), Some(&0x4));
669
670 assert_eq!(ring.remove(1), Some(0x3));
671 assert_eq!(ring.used(), 4);
672 assert_eq!(ring.at(0), Some(&0x1));
673 assert_eq!(ring.at(1), None);
674 assert_eq!(ring.at(2), None);
675 assert_eq!(ring.at(3), Some(&0x4));
676
677 assert_eq!(ring.remove(1), Some(0x4));
678 assert_eq!(ring.used(), 1);
679 assert_eq!(ring.at(0), Some(&0x1));
680 assert_eq!(ring.at(1), None);
681 assert_eq!(ring.at(2), None);
682 assert_eq!(ring.at(3), None);
683 }
684}