1use std::{
2 collections::{hash_map::Entry, HashMap},
3 fmt::Debug,
4 mem,
5 sync::{Arc, RwLock},
6};
7
8use token_ref_cell::{BoxToken, TokenRefCell};
9
10#[derive(Debug, Default)]
11pub struct Graph {
12 nodes: HashMap<NodeId, Arc<TokenRefCell<Node>>>,
13 token: BoxToken,
14}
15
16pub type NodeId = usize;
17
18#[derive(Debug, Default)]
19pub struct Node {
20 id: NodeId,
21 edges: HashMap<NodeId, Arc<TokenRefCell<Node>>>,
22}
23
24impl Graph {
25 pub fn new() -> Self {
26 Self::default()
27 }
28
29 pub fn get_node(&self, id: NodeId) -> Option<&Node> {
30 Some(self.nodes.get(&id)?.borrow(&self.token).into_ref())
31 }
32
33 pub fn insert_node(&mut self, id: NodeId) -> bool {
34 let entry = self.nodes.entry(id);
35 let inserted = matches!(entry, Entry::Vacant(_));
36 entry.or_insert_with(|| Node::new_cell(id, &self.token));
37 inserted
38 }
39
40 pub fn remove_node(&mut self, id: NodeId) -> bool {
41 let Some(node) = self.nodes.remove(&id) else {
42 return false;
43 };
44 let mut node_mut = node.borrow_mut(&mut self.token);
45 let mut reborrow_mut =
46 node_mut.reborrow_stateful_mut(|node| node.edges.values().map(AsRef::as_ref));
47 while let Some(mut other) = reborrow_mut.reborrow_opt_mut(|edges| edges.next()) {
48 other.edges.remove(&id);
49 }
50 true
51 }
52
53 pub fn insert_edge(&mut self, node1: NodeId, node2: NodeId) {
54 let mut node = |id| {
55 let entry = self.nodes.entry(id);
56 let node = entry.or_insert_with(|| Node::new_cell(node1, &self.token));
57 node.clone()
58 };
59 let node_cell1 = node(node1);
60 let node_cell2 = node(node2);
61 node_cell1
62 .borrow_mut(&mut self.token)
63 .edges
64 .insert(node2, node_cell2.clone());
65 node_cell2
66 .borrow_mut(&mut self.token)
67 .edges
68 .insert(node1, node_cell1);
69 }
70
71 pub fn remove_edge(&mut self, node1: NodeId, node2: NodeId) {
72 let mut remove = |a, b| {
73 let Some(node) = self.nodes.get(&a) else {
74 return false;
75 };
76 node.borrow_mut(&mut self.token).edges.remove(&b);
77 true
78 };
79 if remove(node1, node2) {
80 remove(node2, node1);
81 }
82 }
83
84 pub fn clear(&mut self) {
85 let mut nodes = mem::take(&mut self.nodes);
86 for (_, node) in nodes.drain() {
87 if let Ok(mut node) = node.try_borrow_mut(&mut self.token) {
88 node.edges.clear();
89 }
90 }
91 self.nodes = nodes;
92 }
93}
94
95impl Node {
96 fn new_cell(id: NodeId, token: &BoxToken) -> Arc<TokenRefCell<Node>> {
97 let edges = HashMap::new();
98 Arc::new(TokenRefCell::new(Node { id, edges }, token))
99 }
100
101 pub fn id(&self) -> NodeId {
102 self.id
103 }
104
105 pub fn edges(&self) -> impl Iterator<Item = NodeId> + '_ {
106 self.edges.keys().copied()
107 }
108}
109
110impl Drop for Graph {
111 fn drop(&mut self) {
112 self.clear();
113 }
114}
115
116fn main() {
117 let graph = Arc::new(RwLock::new(Graph::new()));
118 {
119 let mut graph_mut = graph.write().unwrap();
120 graph_mut.insert_edge(0, 1);
121 graph_mut.insert_edge(1, 2);
122 graph_mut.insert_edge(2, 0);
123 graph_mut.remove_node(1);
124 }
125 {
126 let graph_ref = graph.read().unwrap();
127 let node = graph_ref.get_node(0).unwrap();
128 assert_eq!(node.id(), 0);
129 let mut edges = node.edges();
130 assert_eq!(edges.next(), Some(2));
131 assert_eq!(edges.next(), None);
132 }
133}