1use crate::storage::{
9 CountedByKey, DoubleMapStorage, EmptyCallback, KeyIterableByKeyMap, ValueStorage,
10};
11use core::{fmt::Debug, marker::PhantomData};
12
13pub trait Scheduler {
15 type BlockNumber;
17 type Task;
19 type Cost;
21 type Error: TaskPoolError;
23 type OutputError: From<Self::Error> + Debug;
28
29 type CostsPerBlock: SchedulingCostsPerBlock<BlockNumber = Self::BlockNumber, Cost = Self::Cost>;
31
32 type FirstIncompleteTasksBlock: ValueStorage<Value = Self::BlockNumber>;
39
40 type TaskPool: TaskPool<
44 BlockNumber = Self::BlockNumber,
45 Task = Self::Task,
46 Error = Self::Error,
47 OutputError = Self::OutputError,
48 > + CountedByKey<Key = Self::BlockNumber, Length = usize>
49 + KeyIterableByKeyMap<Key1 = Self::BlockNumber, Key2 = Self::Task>;
50
51 fn reset() {
56 Self::FirstIncompleteTasksBlock::kill();
57 Self::TaskPool::clear();
58 }
59}
60
61pub trait SchedulingCostsPerBlock {
63 type BlockNumber;
65 type Cost;
67
68 fn reserve_for() -> Self::BlockNumber;
70
71 fn code() -> Self::Cost;
73 fn mailbox() -> Self::Cost;
75 fn program() -> Self::Cost;
77 fn waitlist() -> Self::Cost;
79 fn reservation() -> Self::Cost;
81 fn dispatch_stash() -> Self::Cost;
84
85 fn by_storage_type(storage: StorageType) -> Self::Cost;
87}
88
89#[derive(Debug, Clone, Copy)]
94pub enum StorageType {
95 Code,
96 Mailbox,
97 Program,
98 Waitlist,
99 Reservation,
100 DispatchStash,
101}
102
103pub trait TaskPool {
105 type BlockNumber;
107 type Task;
109 type Error: TaskPoolError;
111 type OutputError: From<Self::Error>;
113
114 fn add(bn: Self::BlockNumber, task: Self::Task) -> Result<(), Self::OutputError>;
116
117 fn clear();
119
120 fn contains(bn: &Self::BlockNumber, task: &Self::Task) -> bool;
122
123 fn delete(bn: Self::BlockNumber, task: Self::Task) -> Result<(), Self::OutputError>;
126}
127
128pub trait TaskPoolCallbacks {
130 type OnAdd: EmptyCallback;
132 type OnDelete: EmptyCallback;
134}
135
136pub trait TaskPoolError {
140 fn duplicate_task() -> Self;
142
143 fn task_not_found() -> Self;
145}
146
147pub struct TaskPoolImpl<T, Task, Error, OutputError, Callbacks>(
153 PhantomData<(T, Task, Error, OutputError, Callbacks)>,
154)
155where
156 T: DoubleMapStorage<Key2 = Task, Value = ()>,
157 Error: TaskPoolError,
158 OutputError: From<Error>,
159 Callbacks: TaskPoolCallbacks;
160
161impl<T, Task, Error, OutputError, Callbacks> TaskPool
163 for TaskPoolImpl<T, Task, Error, OutputError, Callbacks>
164where
165 T: DoubleMapStorage<Key2 = Task, Value = ()>,
166 Error: TaskPoolError,
167 OutputError: From<Error>,
168 Callbacks: TaskPoolCallbacks,
169{
170 type BlockNumber = T::Key1;
171 type Task = T::Key2;
172 type Error = Error;
173 type OutputError = OutputError;
174
175 fn add(bn: Self::BlockNumber, task: Self::Task) -> Result<(), Self::OutputError> {
176 if !Self::contains(&bn, &task) {
177 T::insert(bn, task, ());
178 Callbacks::OnAdd::call();
179 Ok(())
180 } else {
181 Err(Self::Error::duplicate_task().into())
182 }
183 }
184
185 fn clear() {
186 T::clear()
187 }
188
189 fn contains(bn: &Self::BlockNumber, task: &Self::Task) -> bool {
190 T::contains_keys(bn, task)
191 }
192
193 fn delete(bn: Self::BlockNumber, task: Self::Task) -> Result<(), Self::OutputError> {
194 if T::contains_keys(&bn, &task) {
195 T::remove(bn, task);
196 Callbacks::OnDelete::call();
197 Ok(())
198 } else {
199 Err(Self::Error::task_not_found().into())
200 }
201 }
202}
203
204impl<T, Task, Error, OutputError, Callbacks> CountedByKey
207 for TaskPoolImpl<T, Task, Error, OutputError, Callbacks>
208where
209 T: DoubleMapStorage<Key2 = Task, Value = ()> + CountedByKey<Key = T::Key1>,
210 Error: TaskPoolError,
211 OutputError: From<Error>,
212 Callbacks: TaskPoolCallbacks,
213{
214 type Key = T::Key1;
215 type Length = T::Length;
216
217 fn len(key: &Self::Key) -> Self::Length {
218 T::len(key)
219 }
220}
221
222impl<T, Task, Error, OutputError, Callbacks> KeyIterableByKeyMap
225 for TaskPoolImpl<T, Task, Error, OutputError, Callbacks>
226where
227 T: DoubleMapStorage<Key2 = Task, Value = ()> + KeyIterableByKeyMap,
228 Error: TaskPoolError,
229 OutputError: From<Error>,
230 Callbacks: TaskPoolCallbacks,
231{
232 type Key1 = <T as KeyIterableByKeyMap>::Key1;
233 type Key2 = <T as KeyIterableByKeyMap>::Key2;
234 type DrainIter = T::DrainIter;
235 type Iter = T::Iter;
236
237 fn drain_prefix_keys(bn: Self::Key1) -> Self::DrainIter {
238 T::drain_prefix_keys(bn)
239 }
240
241 fn iter_prefix_keys(bn: Self::Key1) -> Self::Iter {
242 T::iter_prefix_keys(bn)
243 }
244}