use std::collections::HashMap;
use std::sync::{Arc, RwLock};
use uuid::Uuid;
use crate::meta_storage::mem::error::MemResult;
use crate::meta_storage::mem::resolution::ResolutionTable;
use crate::meta_storage::mem::ticket::TicketTable;
use crate::schema::RunFootprint;
#[derive(Debug, Default)]
pub(super) struct MemStore {
tickets: RwLock<HashMap<&'static str, Arc<TicketTable>>>,
resolutions: RwLock<HashMap<&'static str, Arc<ResolutionTable>>>,
footprint: RwLock<Option<RunFootprint>>,
executions: RwLock<HashMap<Uuid, Execution>>,
}
#[derive(Debug)]
struct Execution {
run_id: Uuid,
ended_at: Option<chrono::DateTime<chrono::Utc>>,
end_reason: Option<String>,
}
impl MemStore {
pub(super) fn init_ticket_table(&self, task_id: &'static str) -> MemResult<()> {
let _ = self
.tickets
.write()?
.entry(task_id)
.or_insert_with(|| Arc::new(TicketTable::default()));
Ok(())
}
pub(super) fn ticket_table(
&self,
task_id: &'static str,
) -> MemResult<Option<Arc<TicketTable>>> {
Ok(self.tickets.read()?.get(task_id).cloned())
}
pub(super) fn init_resolution_table(&self, dim_id: &'static str) -> MemResult<()> {
let _ = self
.resolutions
.write()?
.entry(dim_id)
.or_insert_with(|| Arc::new(ResolutionTable::default()));
Ok(())
}
pub(super) fn resolution_table(
&self,
dim_id: &'static str,
) -> MemResult<Option<Arc<ResolutionTable>>> {
Ok(self.resolutions.read()?.get(dim_id).cloned())
}
pub(super) fn clear_footprint(&self) -> MemResult<()> {
*self.footprint.write()? = None;
self.executions.write()?.clear();
Ok(())
}
pub(super) fn get_footprint(&self) -> MemResult<Option<RunFootprint>> {
Ok(self.footprint.read()?.clone())
}
pub(super) fn upsert_run(&self, footprint: &RunFootprint) -> MemResult<()> {
*self.footprint.write()? = Some(footprint.clone());
Ok(())
}
pub(super) fn put_execution(&self, run_id: Uuid, execution_id: Uuid) -> MemResult<()> {
let _old_value = self.executions.write()?.insert(
execution_id,
Execution {
run_id,
ended_at: None,
end_reason: None,
},
);
Ok(())
}
pub(super) fn update_execution_on_finish(
&self,
footprint: &RunFootprint,
execution_id: Uuid,
) -> MemResult<()> {
let mut executions = self.executions.write()?;
let Some(execution) = executions.get_mut(&execution_id) else {
return Ok(());
};
if execution.run_id != footprint.metadata.run_id {
return Ok(());
}
execution.ended_at = Some(footprint.at);
execution.end_reason = Some(footprint.metadata.state.to_string());
Ok(())
}
}