taskgraph/storage/
static_store.rs1use crate::error::{Result, TaskError};
5use crate::core::task::{Task, TaskStore, TaskStatus};
6
7pub struct StaticStore<const N: usize> {
9 tasks: [Option<Task>; N],
10 edges: [u64; N],
11 count: usize,
12}
13
14impl<const N: usize> StaticStore<N> {
15 pub const fn new() -> Result<Self> {
17 if N > 64 {
18 return Err(TaskError::CapacityExceeded);
19 }
20 const NONE_TASK: Option<Task> = None;
21 Ok(Self {
22 tasks: [NONE_TASK; N],
23 edges: [0; N],
24 count: 0,
25 })
26 }
27}
28
29use core::sync::atomic::Ordering;
30
31impl<const N: usize> TaskStore for StaticStore<N> {
32 fn add_task(&mut self, mut task: Task, deps: &[usize]) -> Result<usize> {
33 if self.count >= N {
34 return Err(TaskError::CapacityExceeded);
35 }
36
37 let id = self.count;
38 task.remaining_deps.store(deps.len(), Ordering::SeqCst);
39 task.initial_deps = deps.len();
40
41 for &d in deps {
45 if d >= self.count {
46 return Err(TaskError::InvalidState);
47 }
48 self.edges[d] |= 1 << id;
50 }
51
52 self.tasks[id] = Some(task);
53 self.count += 1;
54 Ok(id)
55 }
56
57 fn get_successors(&self, id: usize) -> u64 {
58 if id < N {
59 self.edges[id]
60 } else {
61 0
62 }
63 }
64
65 fn get_task(&self, id: usize) -> Option<&Task> {
66 if id < self.count {
67 self.tasks[id].as_ref()
68 } else {
69 None
70 }
71 }
72
73 fn get_task_mut(&mut self, id: usize) -> Option<&mut Task> {
74 if id < self.count {
75 self.tasks[id].as_mut()
76 } else {
77 None
78 }
79 }
80
81 fn update_status(&mut self, id: usize, status: TaskStatus) -> Result<()> {
82 let task = self.get_task_mut(id).ok_or(TaskError::InvalidState)?;
83 task.status = status;
84 Ok(())
85 }
86
87 fn task_count(&self) -> usize {
88 self.count
89 }
90}
91
92impl<const N: usize> Default for StaticStore<N> {
93 fn default() -> Self {
94 Self::new().expect("StaticStore capacity exceeded limit (64)")
95 }
96}