#[allow(unused_imports)]
use crate::mwpf::shim::prelude::*;
use crate::mwpf::decoding_hypergraph::*;
use crate::mwpf::dual_module::*;
use crate::mwpf::matrix::*;
use crate::mwpf::plugin_union_find::*;
use crate::mwpf::relaxer::*;
use crate::mwpf::relaxer_forest::*;
use num_traits::Signed;
use parking_lot::RwLock;
use std::sync::Arc;
pub type EchelonMatrix = Echelon<Tail<Tight<BasicMatrix>>>;
pub trait PluginImpl: std::fmt::Debug {
fn find_relaxers(
&self,
decoding_graph: &DecodingHyperGraph,
matrix: &mut EchelonMatrix,
positive_dual_nodes: &[DualNodePtr],
) -> RelaxerVec;
fn entry() -> PluginEntry
where
Self: 'static + Send + Sync + Sized + Default,
{
PluginEntry {
plugin: Arc::new(Self::default()),
repeat_strategy: RepeatStrategy::default(),
}
}
fn entry_with_strategy(strategy: RepeatStrategy) -> PluginEntry
where
Self: 'static + Send + Sync + Sized + Default,
{
PluginEntry {
plugin: Arc::new(Self::default()),
repeat_strategy: strategy,
}
}
}
#[derive(PartialEq, Eq, Clone, Debug, Default)]
pub enum RepeatStrategy {
#[default]
Once,
Multiple {
max_repetition: usize,
},
}
impl RepeatStrategy {
pub fn new() -> Self {
Self::default()
}
}
pub struct PluginEntry {
pub plugin: Arc<dyn PluginImpl + Send + Sync>,
pub repeat_strategy: RepeatStrategy,
}
impl PluginEntry {
pub fn execute(
&self,
decoding_graph: &DecodingHyperGraph,
matrix: &mut EchelonMatrix,
positive_dual_nodes: &[DualNodePtr],
relaxer_forest: &mut RelaxerForest,
) -> Option<Relaxer> {
let mut repeat = true;
let mut repeat_count = 0;
while repeat {
let relaxers = self.plugin.find_relaxers(decoding_graph, &mut *matrix, positive_dual_nodes);
if relaxers.is_empty() {
repeat = false;
}
for relaxer in relaxers.into_iter() {
for edge_index in relaxer.get_untighten_edges().keys() {
matrix.update_edge_tightness(*edge_index, false);
}
let relaxer = Arc::new(relaxer);
let sum_speed = relaxer.get_sum_speed();
if sum_speed.is_positive() {
return Some(relaxer_forest.expand(&relaxer));
} else {
relaxer_forest.add(relaxer);
}
}
match self.repeat_strategy {
RepeatStrategy::Once => {
repeat = false;
}
RepeatStrategy::Multiple { max_repetition } => {
if repeat_count + 1 >= max_repetition {
repeat = false;
}
}
}
repeat_count += 1;
}
None
}
}
pub type PluginVec = Vec<PluginEntry>;
pub struct PluginManager {
pub plugins: Arc<PluginVec>,
pub plugin_count: Arc<RwLock<usize>>,
}
impl PluginManager {
pub fn new(plugins: Arc<PluginVec>, plugin_count: Arc<RwLock<usize>>) -> Self {
Self { plugins, plugin_count }
}
pub fn is_empty(&self) -> bool {
self.plugins.is_empty()
}
pub fn find_relaxer(
&mut self,
decoding_graph: &DecodingHyperGraph,
matrix: &mut EchelonMatrix,
positive_dual_nodes: &[DualNodePtr],
) -> Option<Relaxer> {
let mut relaxer_forest = RelaxerForest::new(
matrix.get_view_edges().into_iter(),
positive_dual_nodes
.iter()
.map(|ptr| ptr.read_recursive().invalid_subgraph.clone()),
);
for plugin_entry in self.plugins.iter().take(*self.plugin_count.read_recursive()) {
if let Some(relaxer) = plugin_entry.execute(decoding_graph, matrix, positive_dual_nodes, &mut relaxer_forest) {
return Some(relaxer);
}
}
PluginUnionFind::entry().execute(decoding_graph, matrix, positive_dual_nodes, &mut relaxer_forest)
}
}