pui_core/pool/
sequence.rs1use core::sync::atomic::Ordering::Relaxed;
2
3use radium::Radium;
4
5use crate::scalar::{OpaqueScalar, ScalarAllocator};
6
7use super::{Pool, PoolMut};
8
9pub struct Sequence<R, P: ?Sized> {
25 pub index: R,
27 pub pools: P,
31}
32
33impl<A: ScalarAllocator, R: Radium<Item = usize>, P: PoolMut<A>> PoolMut<A> for Sequence<R, [P]> {
34 fn insert_mut(&mut self, mut scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
35 let index = self.index.get_mut();
36 let initial_index = *index;
37 let initial_index = initial_index % self.pools.len();
38
39 loop {
40 let current = *index % self.pools.len();
41
42 if current == initial_index {
43 return Some(scalar)
44 }
45
46 scalar = self.pools[current].insert_mut(scalar)?;
47 *index = index.wrapping_add(1);
48 }
49 }
50
51 fn remove_mut(&mut self) -> Option<OpaqueScalar<A>> {
52 let index = self.index.get_mut();
53 let initial_index = *index;
54 let initial_index = initial_index % self.pools.len();
55
56 loop {
57 let current = *index % self.pools.len();
58
59 if current == initial_index {
60 return None
61 }
62
63 if let Some(scalar) = self.pools[current].remove_mut() {
64 return Some(scalar)
65 }
66
67 *index = index.wrapping_add(1);
68 }
69 }
70}
71
72impl<A: ScalarAllocator, R: Radium<Item = usize>, P: Pool<A>> Pool<A> for Sequence<R, [P]> {
73 fn insert(&self, mut scalar: OpaqueScalar<A>) -> Option<OpaqueScalar<A>> {
74 let mut initial_index = None;
75 loop {
76 let current = self.index.fetch_add(1, Relaxed) % self.pools.len();
77 match initial_index {
78 None => initial_index = Some(current),
79 Some(initial_index) => {
80 if current == initial_index {
81 return Some(scalar)
82 }
83 }
84 }
85
86 scalar = self.pools[current].insert(scalar)?;
87 }
88 }
89
90 fn remove(&self) -> Option<OpaqueScalar<A>> {
91 let mut initial_index = None;
92 loop {
93 let current = self.index.fetch_add(1, Relaxed) % self.pools.len();
94 match initial_index {
95 None => initial_index = Some(current),
96 Some(initial_index) => {
97 if current == initial_index {
98 return None
99 }
100 }
101 }
102
103 if let Some(scalar) = self.pools[current].remove() {
104 return Some(scalar)
105 }
106 }
107 }
108}