use petgraph::{data::DataMap, visit::GraphBase};
use crate::{
BorrowDataCell, LabellingOperator,
local_view::LocalGraphView,
worklists::{PushWrapper, Worklist, WorklistChannel},
};
use std::{borrow::Borrow, fmt::Debug, ops::DerefMut};
#[derive(Default)]
pub struct SingleThreadExecutor {}
impl SingleThreadExecutor {
pub fn new() -> Self {
Self {}
}
}
impl SingleThreadExecutor {
pub fn run_node_labelling<Wl, Op, G>(&self, mut initial_worklist: Wl, operator: Op, graph: G)
where
Wl: Worklist<Op::WorkItem>,
Op: LabellingOperator<G>,
G: GraphBase + DataMap,
G::NodeWeight: BorrowDataCell<UserData = Op::NodeWeight>,
G::NodeId: Debug,
G::EdgeId: Debug,
{
let wl_channel = initial_worklist.create_channel();
while let Some(work_item) = wl_channel.pop() {
let active_node = *work_item.borrow();
let node_data = graph.node_weight(active_node).expect("node has no data");
let local_view = LocalGraphView::new(&graph, active_node);
let mut data_guard = node_data.borrow_data_cell().try_write(0).expect(
"there should be no other access to the node data when using a single thread",
);
operator
.op(work_item, local_view, data_guard.deref_mut(), PushWrapper::new(&wl_channel, 0))
.expect("data conflicts should not happen in the single threaded executor. Did the operator cause it?");
}
initial_worklist.stop();
}
}