use preserves::value::Map; use preserves::value::Set; use std::fmt::Debug; #[derive(Debug)] pub struct Graph { forward_edges: Map>, reverse_edges: Map>, damaged_nodes: Set, } impl Graph { pub fn new() -> Self { Graph { forward_edges: Map::new(), reverse_edges: Map::new(), damaged_nodes: Set::new(), } } pub fn is_clean(&self) -> bool { self.damaged_nodes.is_empty() } pub fn record_observation(&mut self, observer: SubjectId, observed: ObjectId) { self.forward_edges.entry(observed.clone()).or_default().insert(observer.clone()); self.reverse_edges.entry(observer).or_default().insert(observed); } pub fn record_damage(&mut self, observed: ObjectId) { self.damaged_nodes.insert(observed); } fn forget_subject(&mut self, observer: &SubjectId) { if let Some(observeds) = self.reverse_edges.remove(observer) { for observed in observeds.into_iter() { if let Some(observers) = self.forward_edges.get_mut(&observed) { observers.remove(observer); } } } } // To repair: repeat: // - take_damaged_nodes; if none, return successfully - otherwise: // - for each, take_observers_of. // - for each, invoke the observer's repair function. pub fn take_damaged_nodes(&mut self) -> Set { std::mem::take(&mut self.damaged_nodes) } pub fn take_observers_of(&mut self, observed: &ObjectId) -> Set { let observers = self.forward_edges.remove(&observed).unwrap_or_default(); for observer in observers.iter() { self.forget_subject(observer); } observers } }