dvcompute_dist/simulation/
strategy.rs1use std::rc::Rc;
8use std::ops::Deref;
9
10use crate::simulation::Point;
11use crate::simulation::ref_comp::*;
12
13use dvcompute_utils::collections::im::*;
14
15pub trait QueueStorage {
20
21 type Priority;
24
25 type Item;
27
28 fn is_empty(&self, p: &Point) -> bool;
30
31 fn pop(&self, p: &Point) -> Option<Self::Item>;
33
34 fn push(&self, item: Self::Item, p: &Point);
36
37 fn push_with_priority(&self, priority: Self::Priority, item: Self::Item, p: &Point);
39
40 fn remove_by<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
42 where F: Fn(&Self::Item) -> bool + Clone;
43
44 fn exists<F>(&self, predicate: F, p: &Point) -> bool
46 where F: Fn(&Self::Item) -> bool + Clone;
47
48 fn find<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
50 where F: Fn(&Self::Item) -> bool + Clone,
51 Self::Item: Clone;
52}
53
54pub type QueueStorageBox<Item, Priority> = Box<dyn BoxableQueueStorage<Item = Item, Priority = Priority>>;
56
57pub trait BoxableQueueStorage {
59
60 type Priority;
63
64 type Item;
66
67 fn is_empty(&self, p: &Point) -> bool;
69
70 fn pop(&self, p: &Point) -> Option<Self::Item>;
72
73 fn push(&self, item: Self::Item, p: &Point);
75
76 fn push_with_priority(&self, priority: Self::Priority, item: Self::Item, p: &Point);
78
79 fn remove_boxed_by(&self, predicate: Rc<dyn Fn(&Self::Item) -> bool>, p: &Point) -> Option<Self::Item>;
81
82 fn exists_boxed(&self, predicate: Rc<dyn Fn(&Self::Item) -> bool>, p: &Point) -> bool;
84
85 fn find_boxed(&self, predicate: Rc<dyn Fn(&Self::Item) -> bool>, p: &Point) -> Option<Self::Item>
87 where Self::Item: Clone;
88}
89
90impl<S> BoxableQueueStorage for S
91 where S: QueueStorage
92{
93 type Priority = S::Priority;
94 type Item = S::Item;
95
96 fn is_empty(&self, p: &Point) -> bool {
97 S::is_empty(self, p)
98 }
99
100 fn pop(&self, p: &Point) -> Option<Self::Item> {
101 S::pop(self, p)
102 }
103
104 fn push(&self, item: Self::Item, p: &Point) {
105 S::push(self, item, p)
106 }
107
108 fn push_with_priority(&self, priority: Self::Priority, item: Self::Item, p: &Point) {
109 S::push_with_priority(self, priority, item, p)
110 }
111
112 fn remove_boxed_by(&self, predicate: Rc<dyn Fn(&Self::Item) -> bool>, p: &Point) -> Option<Self::Item> {
113 S::remove_by(self, move |x| { predicate(x) }, p)
114 }
115
116 fn exists_boxed(&self, predicate: Rc<dyn Fn(&Self::Item) -> bool>, p: &Point) -> bool {
117 S::exists(self, move |x| { predicate(x) }, p)
118 }
119
120 fn find_boxed(&self, predicate: Rc<dyn Fn(&Self::Item) -> bool>, p: &Point) -> Option<Self::Item>
121 where Self::Item: Clone
122 {
123 S::find(self, move |x| { predicate(x) }, p)
124 }
125}
126
127pub trait QueueStrategy {
129
130 type Priority;
132
133 fn new_storage<T>(&self) -> QueueStorageBox<T, Self::Priority>
135 where T: Clone + 'static;
136}
137
138pub struct FCFSStorage<T> {
140
141 queue: RefComp<Queue<T>>
143}
144
145impl<T> FCFSStorage<T>
146 where T: Clone
147{
148 pub fn new() -> Self {
150 FCFSStorage { queue: RefComp::new(Queue::empty()) }
151 }
152}
153
154impl<T> QueueStorage for FCFSStorage<T>
155 where T: Clone + 'static
156{
157 type Priority = ();
158 type Item = T;
159
160 #[inline]
161 fn is_empty(&self, p: &Point) -> bool {
162 let queue = self.queue.read_at(p);
163 queue.is_empty()
164 }
165
166 fn pop(&self, p: &Point) -> Option<Self::Item> {
167 let results = {
168 let queue = self.queue.read_at(p);
169 queue.pop_front()
170 };
171 match results {
172 None => None,
173 Some((item, queue)) => {
174 self.queue.write_at(queue, p);
175 Some(item)
176 }
177 }
178 }
179
180 fn push(&self, item: Self::Item, p: &Point) {
181 let results = {
182 let queue = self.queue.read_at(p);
183 queue.push_back(item)
184 };
185 self.queue.write_at(results, p);
186 }
187
188 fn push_with_priority(&self, _priority: Self::Priority, _item: Self::Item, _p: &Point) {
189 panic!("Not supported operation");
190 }
191
192 fn remove_by<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
193 where F: Fn(&Self::Item) -> bool + Clone
194 {
195 let results = {
196 let queue = self.queue.read_at(p);
197 queue.remove_by(predicate)
198 };
199 match results {
200 None => None,
201 Some((item, queue)) => {
202 self.queue.write_at(queue, p);
203 Some(item)
204 }
205 }
206 }
207
208 fn exists<F>(&self, predicate: F, p: &Point) -> bool
209 where F: Fn(&Self::Item) -> bool + Clone
210 {
211 let queue = self.queue.read_at(p);
212 queue.exists(predicate)
213 }
214
215 fn find<F>(&self, predicate: F, p: &Point) -> Option<T>
216 where F: Fn(&Self::Item) -> bool + Clone,
217 Self::Item: Clone
218 {
219 let queue = self.queue.read_at(p);
220 queue.find(predicate)
221 }
222}
223
224pub struct LCFSStorage<T> {
226
227 queue: RefComp<List<T>>
229}
230
231impl<T> LCFSStorage<T>
232 where T: Clone
233{
234 pub fn new() -> Self {
236 LCFSStorage { queue: RefComp::new(List::Nil) }
237 }
238}
239
240impl<T> QueueStorage for LCFSStorage<T>
241 where T: Clone + 'static
242{
243 type Priority = ();
244 type Item = T;
245
246 #[inline]
247 fn is_empty(&self, p: &Point) -> bool {
248 let queue = self.queue.read_at(p);
249 queue.is_empty()
250 }
251
252 fn pop(&self, p: &Point) -> Option<Self::Item> {
253 match self.queue.read_at(p) {
254 List::Nil => None,
255 List::Cons(head, tail) => {
256 let tail = tail.deref();
257 self.queue.write_at(tail.clone(), p);
258 Some(head)
259 }
260 }
261 }
262
263 fn push(&self, item: Self::Item, p: &Point) {
264 let results = {
265 let queue = self.queue.read_at(p);
266 List::Cons(item, Rc::new(queue))
267 };
268 self.queue.write_at(results, p);
269 }
270
271 fn push_with_priority(&self, _priority: Self::Priority, _item: Self::Item, _p: &Point) {
272 panic!("Not supported operation");
273 }
274
275 fn remove_by<F>(&self, predicate: F, p: &Point) -> Option<Self::Item>
276 where F: Fn(&Self::Item) -> bool + Clone
277 {
278 let results = {
279 let queue = self.queue.read_at(p);
280 queue.remove_by(predicate)
281 };
282 match results {
283 None => None,
284 Some((item, queue)) => {
285 self.queue.write_at(queue, p);
286 Some(item)
287 }
288 }
289 }
290
291 fn exists<F>(&self, predicate: F, p: &Point) -> bool
292 where F: Fn(&Self::Item) -> bool + Clone
293 {
294 let queue = self.queue.read_at(p);
295 queue.exists(predicate)
296 }
297
298 fn find<F>(&self, predicate: F, p: &Point) -> Option<T>
299 where F: Fn(&Self::Item) -> bool + Clone,
300 Self::Item: Clone
301 {
302 let queue = self.queue.read_at(p);
303 queue.find(predicate)
304 }
305}
306
307#[derive(Clone)]
309pub enum FCFSStrategy {
310
311 Instance
313}
314
315impl QueueStrategy for FCFSStrategy {
316
317 type Priority = ();
318
319 fn new_storage<T>(&self) -> QueueStorageBox<T, Self::Priority>
320 where T: Clone + 'static
321 {
322 Box::new(FCFSStorage::new())
323 }
324}
325
326#[derive(Clone)]
328pub enum LCFSStrategy {
329
330 Instance
332}
333
334impl QueueStrategy for LCFSStrategy {
335
336 type Priority = ();
337
338 fn new_storage<T>(&self) -> QueueStorageBox<T, Self::Priority>
339 where T: Clone + 'static
340 {
341 Box::new(LCFSStorage::new())
342 }
343}