use std::collections::HashMap;
use crate::profile::Output;
use crate::wl_backend::WlHead;
use super::{
IntermediatePairing, IntermediatePairingWithMultipleModes, IntermediatePairingWithoutMode,
};
pub struct HopcroftKarpMap;
impl HopcroftKarpMap {
pub fn hkmap<Output, Head, E>(edges: impl Iterator<Item = E>) -> impl Iterator<Item = E>
where
Output: PartialEq + Clone,
Head: PartialEq + Clone,
E: Edge<Output, Head>,
{
let mut map = CombinedMap::default();
let mapped_edges = edges.map(|e| map.insert(e)).collect();
let matched_mapped_edges = hopcroft_karp::matching(&mapped_edges);
matched_mapped_edges
.into_iter()
.filter_map(move |me| map.pairs.remove(&me))
}
}
struct CombinedMap<Output, Head, E>
where
Output: PartialEq,
Head: PartialEq,
E: Edge<Output, Head>,
{
mapping_output: LeftMap<Output>,
mapping_head: RightMap<Head>,
pairs: HashMap<(isize, isize), E>,
}
impl<Output, Head, E> Default for CombinedMap<Output, Head, E>
where
Output: PartialEq,
Head: PartialEq,
E: Edge<Output, Head>,
{
fn default() -> Self {
Self {
mapping_output: Default::default(),
mapping_head: Default::default(),
pairs: Default::default(),
}
}
}
impl<Output, Head, E> CombinedMap<Output, Head, E>
where
Output: PartialEq + Clone,
Head: PartialEq + Clone,
E: Edge<Output, Head>,
{
fn insert(&mut self, edge: E) -> (isize, isize) {
let left = self.mapping_output.insert(edge.left().clone());
let right = self.mapping_head.insert(edge.right().clone());
self.pairs.insert((left, right), edge);
(left, right)
}
}
struct InnerMap<T: PartialEq> {
list: Vec<T>,
}
struct LeftMap<T: PartialEq> {
map: InnerMap<T>,
}
struct RightMap<T: PartialEq> {
map: InnerMap<T>,
}
impl<T: PartialEq> Default for InnerMap<T> {
fn default() -> Self {
Self { list: vec![] }
}
}
impl<T: PartialEq> Default for RightMap<T> {
fn default() -> Self {
Self {
map: Default::default(),
}
}
}
impl<T: PartialEq> Default for LeftMap<T> {
fn default() -> Self {
Self {
map: Default::default(),
}
}
}
impl<T: PartialEq> LeftMap<T> {
fn insert(&mut self, value: T) -> isize {
let index: usize = self.map.insert(value);
let index: isize = -((index + 1) as isize);
assert!(index < 0);
index
}
}
impl<T: PartialEq> RightMap<T> {
fn insert(&mut self, value: T) -> isize {
let index: usize = self.map.insert(value);
let index: isize = (index + 1) as isize;
assert!(index > 0);
index
}
}
impl<T: PartialEq> InnerMap<T> {
fn insert(&mut self, value: T) -> usize {
match self.list.iter().position(|t| *t == value) {
Some(idx) => idx,
None => {
self.list.push(value);
self.list.len() - 1
}
}
}
}
pub trait Edge<L, R> {
fn left(&self) -> &L;
fn right(&self) -> &R;
}
impl Edge<Output, WlHead> for IntermediatePairing {
fn left(&self) -> &Output {
match self {
IntermediatePairing::WithMultipleModes(ip) => ip.left(),
IntermediatePairing::WithoutMode(ip) => ip.left(),
}
}
fn right(&self) -> &WlHead {
match self {
IntermediatePairing::WithMultipleModes(ip) => ip.right(),
IntermediatePairing::WithoutMode(ip) => ip.right(),
}
}
}
impl Edge<Output, WlHead> for IntermediatePairingWithMultipleModes {
fn left(&self) -> &Output {
&self.output
}
fn right(&self) -> &WlHead {
&self.matched_head
}
}
impl Edge<Output, WlHead> for IntermediatePairingWithoutMode {
fn left(&self) -> &Output {
&self.output
}
fn right(&self) -> &WlHead {
&self.matched_head
}
}