Skip to content

Commit 6663ebb

Browse files
committed
Made Graph thread-safe again
1 parent a3c2fb0 commit 6663ebb

2 files changed

Lines changed: 28 additions & 12 deletions

File tree

src/graph.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ use core::fmt::Debug;
1717
use std::fmt::Debug;
1818

1919
#[cfg(feature = "no_std")]
20-
use core::cell::RefCell;
20+
use core::mem;
2121

2222
#[cfg(not(feature = "no_std"))]
23-
use std::cell::RefCell;
23+
use std::mem;
2424

2525
#[cfg(feature = "no_std")]
2626
extern crate alloc;
@@ -89,7 +89,7 @@ pub struct Graph<T>
8989

9090
#[cfg(feature = "dot")]
9191
/// Mapping between vertices and labels
92-
labels: RefCell<HashMap<VertexId, String>>,
92+
labels: HashMap<VertexId, String>,
9393
}
9494

9595
impl<T> Graph<T>
@@ -116,7 +116,7 @@ impl<T> Graph<T>
116116
outbound_table: HashMap::new(),
117117

118118
#[cfg(feature = "dot")]
119-
labels: RefCell::new(HashMap::new()),
119+
labels: HashMap::new(),
120120
}
121121
}
122122

@@ -144,7 +144,7 @@ impl<T> Graph<T>
144144
outbound_table: HashMap::with_capacity(capacity),
145145

146146
#[cfg(feature = "dot")]
147-
labels: RefCell::new(HashMap::with_capacity(capacity)),
147+
labels: HashMap::with_capacity(capacity),
148148
}
149149
}
150150

@@ -208,7 +208,7 @@ impl<T> Graph<T>
208208
self.inbound_table.reserve(additional);
209209

210210
#[cfg(feature = "dot")]
211-
self.labels.borrow_mut().reserve(additional);
211+
self.labels.reserve(additional);
212212
}
213213

214214
/// Shrinks the capacity of the graph as much as possible.
@@ -235,7 +235,7 @@ impl<T> Graph<T>
235235
self.inbound_table.shrink_to_fit();
236236

237237
#[cfg(feature = "dot")]
238-
self.labels.borrow_mut().shrink_to_fit();
238+
self.labels.shrink_to_fit();
239239

240240
// Calculate additional value for edges vector
241241
// such that it is always n^2 where n is the
@@ -1267,7 +1267,7 @@ impl<T> Graph<T>
12671267
}
12681268

12691269
let old_label = self.label(vertex_id).unwrap();
1270-
self.labels.borrow_mut().insert(vertex_id.clone(), label.to_owned());
1270+
self.labels.insert(vertex_id.clone(), label.to_owned());
12711271

12721272
Ok(old_label)
12731273
}
@@ -1282,7 +1282,7 @@ impl<T> Graph<T>
12821282
return None;
12831283
}
12841284

1285-
if let Some(label) = self.labels.borrow().get(vertex_id) {
1285+
if let Some(label) = self.labels.get(vertex_id) {
12861286
return Some(label.clone());
12871287
}
12881288

@@ -1299,11 +1299,12 @@ impl<T> Graph<T>
12991299
let label = format!("N_{}", encoded);
13001300
assert!(dot::Id::new(label.to_owned()).is_ok());
13011301

1302-
{
1303-
self.labels.borrow_mut().insert(vertex_id.clone(), label);
1302+
unsafe {
1303+
let labels_ptr = mem::transmute::<&HashMap<VertexId, String>, &mut HashMap<VertexId, String>>(&self.labels);
1304+
labels_ptr.insert(vertex_id.clone(), label);
13041305
}
13051306

1306-
self.labels.borrow().get(vertex_id).map(|s| s.clone())
1307+
self.labels.get(vertex_id).map(|s| s.clone())
13071308
}
13081309

13091310
fn do_add_edge(&mut self, a: &VertexId, b: &VertexId, weight: f32) -> Result<(), GraphErr> {
@@ -1413,6 +1414,19 @@ impl<T> Graph<T>
14131414
mod tests {
14141415
use super::*;
14151416

1417+
#[test]
1418+
fn is_thread_safe() {
1419+
let mut graph: Graph<usize> = Graph::new();
1420+
graph.add_vertex(0);
1421+
1422+
std::panic::set_hook(Box::new(move |_| {
1423+
let mut graph = graph.clone();
1424+
1425+
graph.add_vertex(1);
1426+
graph.add_vertex(2);
1427+
}));
1428+
}
1429+
14161430
#[test]
14171431
fn dfs() {
14181432
let mut graph: Graph<usize> = Graph::new();

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
//! assert_eq!(graph.edge_count(), 0);
3838
//! ```
3939
40+
#![allow(mutable_transmutes)]
41+
4042
mod edge;
4143
#[macro_use]
4244
mod macros;

0 commit comments

Comments
 (0)