use std::{collections::HashMap, fmt::Debug};
use super::Job;
pub trait JobStore<T: Job>: Send + Sync + Debug {
fn add_future_job(&mut self, template_id: u64, job: T) -> u32;
fn add_active_job(&mut self, job: T);
fn activate_future_job(&mut self, template_id: u64, prev_hash_header_timestamp: u32) -> bool;
fn mark_past_jobs_as_stale(&mut self);
fn get_future_job_id_from_template_id(&self, template_id: u64) -> Option<u32>;
fn get_active_job(&self) -> Option<T>;
fn has_future_jobs(&self) -> bool;
fn get_future_job(&self, job_id: u32) -> Option<T>;
fn has_past_jobs(&self) -> bool;
fn get_past_job(&self, job_id: u32) -> Option<T>;
fn has_stale_jobs(&self) -> bool;
fn get_stale_job(&self, job_id: u32) -> Option<T>;
}
#[derive(Debug)]
pub struct DefaultJobStore<T: Job + Clone> {
future_template_to_job_id: HashMap<u64, u32>,
future_jobs: HashMap<u32, T>,
active_job: Option<T>,
past_jobs: HashMap<u32, T>,
stale_jobs: HashMap<u32, T>,
}
impl<T: Job + Clone> DefaultJobStore<T> {
pub fn new() -> Self {
Self {
future_template_to_job_id: HashMap::new(),
future_jobs: HashMap::new(),
active_job: None,
past_jobs: HashMap::new(),
stale_jobs: HashMap::new(),
}
}
}
impl<T: Job + Clone> Default for DefaultJobStore<T> {
fn default() -> Self {
Self::new()
}
}
impl<T: Job + Clone + Debug> JobStore<T> for DefaultJobStore<T> {
fn add_future_job(&mut self, template_id: u64, new_job: T) -> u32 {
let new_job_id = new_job.get_job_id();
self.future_jobs.insert(new_job_id, new_job);
self.future_template_to_job_id
.insert(template_id, new_job_id);
new_job_id
}
fn add_active_job(&mut self, job: T) {
if let Some(active_job) = self.active_job.take() {
self.past_jobs.insert(active_job.get_job_id(), active_job);
}
self.active_job = Some(job);
}
fn activate_future_job(&mut self, template_id: u64, prev_hash_header_timestamp: u32) -> bool {
let mut future_job =
if let Some(job_id) = self.future_template_to_job_id.remove(&template_id) {
if let Some(job) = self.future_jobs.remove(&job_id) {
job
} else {
return false;
}
} else {
return false;
};
if let Some(active_job) = self.active_job.take() {
self.past_jobs.insert(active_job.get_job_id(), active_job);
}
future_job.activate(prev_hash_header_timestamp);
self.active_job = Some(future_job);
self.future_jobs.clear();
self.future_template_to_job_id.clear();
self.mark_past_jobs_as_stale();
true
}
fn mark_past_jobs_as_stale(&mut self) {
self.stale_jobs = std::mem::take(&mut self.past_jobs);
}
fn get_future_job_id_from_template_id(&self, template_id: u64) -> Option<u32> {
self.future_template_to_job_id.get(&template_id).cloned()
}
fn get_active_job(&self) -> Option<T> {
self.active_job.clone()
}
fn has_future_jobs(&self) -> bool {
!self.future_jobs.is_empty()
}
fn get_future_job(&self, job_id: u32) -> Option<T> {
self.future_jobs.get(&job_id).cloned()
}
fn has_past_jobs(&self) -> bool {
!self.past_jobs.is_empty()
}
fn get_past_job(&self, job_id: u32) -> Option<T> {
self.past_jobs.get(&job_id).cloned()
}
fn has_stale_jobs(&self) -> bool {
!self.stale_jobs.is_empty()
}
fn get_stale_job(&self, job_id: u32) -> Option<T> {
self.stale_jobs.get(&job_id).cloned()
}
}