Skip to content

Commit cc9168b

Browse files
authored
Merge pull request #25 from purpleprotocol/enhancement/24/remove-arc-instances
Remove all Arc instances
2 parents 6541b39 + 8bd9cce commit cc9168b

4 files changed

Lines changed: 80 additions & 97 deletions

File tree

src/edge.rs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,17 @@ use crate::vertex_id::VertexId;
55
use std::hash::Hash;
66
#[cfg(not(feature = "no_std"))]
77
use std::hash::Hasher;
8-
#[cfg(not(feature = "no_std"))]
9-
use std::sync::Arc;
108

119
#[cfg(feature = "no_std")]
1210
extern crate alloc;
1311
#[cfg(feature = "no_std")]
14-
use alloc::sync::Arc;
15-
#[cfg(feature = "no_std")]
1612
use core::hash::{Hash, Hasher};
1713

1814
#[derive(Clone, Debug)]
1915
/// Edge internal struct
2016
pub struct Edge {
21-
inbound: Arc<VertexId>,
22-
outbound: Arc<VertexId>,
17+
inbound: VertexId,
18+
outbound: VertexId,
2319
}
2420

2521
impl PartialEq for Edge {
@@ -38,7 +34,7 @@ impl Hash for Edge {
3834
}
3935

4036
impl Edge {
41-
pub fn new(outbound: Arc<VertexId>, inbound: Arc<VertexId>) -> Edge {
37+
pub fn new(outbound: VertexId, inbound: VertexId) -> Edge {
4238
Edge {
4339
inbound,
4440
outbound,
@@ -48,13 +44,13 @@ impl Edge {
4844
/// Returns true if the given vertex ids are the
4945
/// inbound and outbound vertices of the edge.
5046
pub(crate) fn matches(&self, a: &VertexId, b: &VertexId) -> bool {
51-
a == self.outbound.as_ref() && b == self.inbound.as_ref()
47+
a == &self.outbound && b == &self.inbound
5248
}
5349

5450
/// Returns true if either the inbound or outbound
5551
/// vertex is matching the given `VertexId`.
5652
pub(crate) fn matches_any(&self, id: &VertexId) -> bool {
57-
id == self.inbound.as_ref() || id == self.outbound.as_ref()
53+
id == &self.inbound || id == &self.outbound
5854
}
5955

6056
/// Returns the inbound VertexId

src/graph.rs

Lines changed: 61 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,17 @@ use crate::edge::Edge;
44
use crate::iterators::{Bfs, Dfs, VertexIter};
55
use crate::vertex_id::VertexId;
66
use hashbrown::{HashMap, HashSet};
7-
#[cfg(not(feature = "no_std"))]
8-
use std::sync::Arc;
97

108
#[cfg(feature = "no_std")]
119
use core::iter;
12-
#[cfg(feature = "no_std")]
13-
use core::cmp::Ordering;
1410
#[cfg(not(feature = "no_std"))]
1511
use std::iter;
16-
#[cfg(not(feature = "no_std"))]
17-
use std::cmp::Ordering;
1812

1913
#[cfg(feature = "no_std")]
2014
extern crate alloc;
2115
#[cfg(feature = "no_std")]
2216
use alloc::boxed::Box;
2317
#[cfg(feature = "no_std")]
24-
use alloc::sync::Arc;
25-
#[cfg(feature = "no_std")]
2618
use alloc::vec;
2719
#[cfg(feature = "no_std")]
2820
use alloc::vec::Vec;
@@ -39,11 +31,11 @@ pub enum GraphErr {
3931
#[derive(Clone, Debug)]
4032
/// Graph data-structure
4133
pub struct Graph<T> {
42-
vertices: HashMap<Arc<VertexId>, (T, Arc<VertexId>)>,
34+
vertices: HashMap<VertexId, (T, VertexId)>,
4335
edges: HashMap<Edge, f32>,
44-
roots: Vec<Arc<VertexId>>,
45-
inbound_table: HashMap<Arc<VertexId>, Vec<Arc<VertexId>>>,
46-
outbound_table: HashMap<Arc<VertexId>, Vec<Arc<VertexId>>>,
36+
roots: Vec<VertexId>,
37+
inbound_table: HashMap<VertexId, Vec<VertexId>>,
38+
outbound_table: HashMap<VertexId, Vec<VertexId>>,
4739
}
4840

4941
impl<T> Graph<T> {
@@ -187,10 +179,9 @@ impl<T> Graph<T> {
187179
/// ```
188180
pub fn add_vertex(&mut self, item: T) -> VertexId {
189181
let id = VertexId::random();
190-
let id_ptr = Arc::new(id);
191182

192-
self.vertices.insert(id_ptr.clone(), (item, id_ptr.clone()));
193-
self.roots.push(id_ptr);
183+
self.vertices.insert(id.clone(), (item, id.clone()));
184+
self.roots.push(id);
194185

195186
id
196187
}
@@ -285,10 +276,7 @@ impl<T> Graph<T> {
285276
return None;
286277
}
287278

288-
let a = Arc::from(*a);
289-
let b = Arc::from(*b);
290-
291-
if let Some(result) = self.edges.get(&Edge::new(a, b)) {
279+
if let Some(result) = self.edges.get(&Edge::new(a.clone(), b.clone())) {
292280
Some(*result)
293281
} else {
294282
None
@@ -319,27 +307,24 @@ impl<T> Graph<T> {
319307
/// graph.set_weight(&v1, &v2, 0.123).unwrap();
320308
/// assert_eq!(graph.weight(&v1, &v2), Some(0.123));
321309
/// ```
322-
pub fn set_weight(&mut self, a_ref: &VertexId, b_ref: &VertexId, new_weight: f32) -> Result<(), GraphErr> {
323-
if !self.has_edge(a_ref, b_ref) {
310+
pub fn set_weight(&mut self, a: &VertexId, b: &VertexId, new_weight: f32) -> Result<(), GraphErr> {
311+
if !self.has_edge(a, b) {
324312
return Err(GraphErr::NoSuchEdge);
325313
}
326314

327315
if new_weight > 1.0 || new_weight < -1.0 {
328316
return Err(GraphErr::InvalidWeight);
329317
}
330318

331-
let a = Arc::from(*a_ref);
332-
let b = Arc::from(*b_ref);
333-
334-
self.edges.insert(Edge::new(a.clone(), b), new_weight);
319+
self.edges.insert(Edge::new(a.clone(), b.clone()), new_weight);
335320

336321
// Sort outbound vertices after setting a new weight
337-
let mut outbounds = self.outbound_table.get(&a).unwrap().clone();
322+
let mut outbounds = self.outbound_table.get(a).unwrap().clone();
338323

339324
self.sort_outbounds(a.clone(), &mut outbounds);
340325

341326
// Update outbounds
342-
self.outbound_table.insert(a, outbounds);
327+
self.outbound_table.insert(a.clone(), outbounds);
343328

344329
Ok(())
345330
}
@@ -363,10 +348,8 @@ impl<T> Graph<T> {
363348
/// assert!(!graph.has_edge(&v2, &v3));
364349
/// ```
365350
pub fn has_edge(&self, a: &VertexId, b: &VertexId) -> bool {
366-
let rc_other = Arc::from(*b);
367-
368351
match self.outbound_table.get(a) {
369-
Some(outbounds) => outbounds.contains(&rc_other),
352+
Some(outbounds) => outbounds.contains(b),
370353
None => false,
371354
}
372355
}
@@ -496,7 +479,7 @@ impl<T> Graph<T> {
496479

497480
self.outbound_table.remove(id);
498481
self.edges.retain(|e, _| !e.matches_any(id));
499-
self.roots.retain(|r| r.as_ref() != id);
482+
self.roots.retain(|r| r != id);
500483
}
501484

502485
/// Removes the specified edge from the graph.
@@ -529,14 +512,14 @@ impl<T> Graph<T> {
529512
let mut remove = false;
530513

531514
if let Some(outbounds) = self.outbound_table.get_mut(a) {
532-
outbounds.retain(|v| *v.as_ref() != *b);
515+
outbounds.retain(|v| v != b);
533516
remove = true;
534517
}
535518

536519
// If outbound vertex doesn't have any more inbounds,
537520
// mark it as root.
538521
if self.in_neighbors_count(&b) == 0 {
539-
self.roots.push(Arc::from(*b));
522+
self.roots.push(b.clone());
540523
}
541524

542525
if remove {
@@ -991,15 +974,6 @@ impl<T> Graph<T> {
991974
Bfs::new(self)
992975
}
993976

994-
/// Attempts to fetch a reference to a stored vertex id
995-
/// which is equal to the given `VertexId`.
996-
pub(crate) fn fetch_id_ref<'b>(&'b self, id: &VertexId) -> Option<&'b VertexId> {
997-
match self.vertices.get(id) {
998-
Some((_, id_ptr)) => Some(id_ptr.as_ref()),
999-
None => None,
1000-
}
1001-
}
1002-
1003977
/// Creates a file with the dot representation of the graph.
1004978
/// This method requires the `dot` feature.
1005979
///
@@ -1041,14 +1015,14 @@ impl<T> Graph<T> {
10411015
}
10421016

10431017
fn do_add_edge(&mut self, a: &VertexId, b: &VertexId, weight: f32) -> Result<(), GraphErr> {
1044-
let id_ptr1 = if let Some((_, a_prime)) = self.vertices.get(a) {
1045-
a_prime.clone()
1018+
let id_ptr1 = if self.vertices.get(a).is_some() {
1019+
a.clone()
10461020
} else {
10471021
return Err(GraphErr::NoSuchVertex);
10481022
};
10491023

1050-
let id_ptr2 = if let Some((_, b_prime)) = self.vertices.get(b) {
1051-
b_prime.clone()
1024+
let id_ptr2 = if self.vertices.get(b).is_some() {
1025+
b.clone()
10521026
} else {
10531027
return Err(GraphErr::NoSuchVertex);
10541028
};
@@ -1085,13 +1059,13 @@ impl<T> Graph<T> {
10851059
}
10861060

10871061
// Remove outbound vertex from roots
1088-
self.roots = self.roots.iter().filter(|v| ***v != *b).cloned().collect();
1062+
self.roots = self.roots.iter().filter(|v| *v != b).cloned().collect();
10891063

10901064
Ok(())
10911065
}
10921066

1093-
fn sort_outbounds(&self, inbound: Arc<VertexId>, outbounds: &mut Vec<Arc<VertexId>>) {
1094-
let outbound_weights: HashMap<Arc<VertexId>, f32> = outbounds
1067+
fn sort_outbounds(&self, inbound: VertexId, outbounds: &mut Vec<VertexId>) {
1068+
let outbound_weights: HashMap<VertexId, f32> = outbounds
10951069
.iter()
10961070
.map(|id| (id.clone(), *self.edges.get(&Edge::new(inbound.clone(), id.clone())).unwrap()))
10971071
.collect();
@@ -1130,13 +1104,22 @@ impl<T> Graph<T> {
11301104
});
11311105
}
11321106

1107+
/// Attempts to fetch a reference to a stored vertex id
1108+
/// which is equal to the given `VertexId`.
1109+
pub(crate) fn fetch_id_ref<'b>(&'b self, id: &VertexId) -> Option<&'b VertexId> {
1110+
match self.vertices.get(id) {
1111+
Some((_, id_ptr)) => Some(id_ptr.as_ref()),
1112+
None => None,
1113+
}
1114+
}
1115+
11331116
/// Returns a reference to the inner edges hash map.
11341117
fn edges_hm_ref(&self) -> Result<(&HashMap<Edge, f32>), GraphErr> {
11351118
Ok(&self.edges)
11361119
}
11371120

11381121
/// Returns a reference to the inner vertices hashmap.
1139-
fn vertex_hm_ref(&self) -> &HashMap<Arc<VertexId>, (T, Arc<VertexId>)> {
1122+
fn vertex_hm_ref(&self) -> &HashMap<VertexId, (T, VertexId)> {
11401123
&self.vertices
11411124
}
11421125
}
@@ -1178,40 +1161,40 @@ mod tests {
11781161
assert_eq!(dfs.next(), Some(&v7));
11791162
}
11801163

1181-
// #[test]
1182-
// fn dfs_mul_roots() {
1183-
// let mut graph: Graph<usize> = Graph::new();
1164+
#[test]
1165+
fn dfs_mul_roots() {
1166+
let mut graph: Graph<usize> = Graph::new();
11841167

1185-
// let v1 = graph.add_vertex(0);
1186-
// let v2 = graph.add_vertex(1);
1187-
// let v3 = graph.add_vertex(2);
1188-
// let v4 = graph.add_vertex(3);
1168+
let v1 = graph.add_vertex(0);
1169+
let v2 = graph.add_vertex(1);
1170+
let v3 = graph.add_vertex(2);
1171+
let v4 = graph.add_vertex(3);
11891172

1190-
// graph.add_edge(&v1, &v2).unwrap();
1191-
// graph.add_edge(&v3, &v1).unwrap();
1192-
// graph.add_edge(&v1, &v4).unwrap();
1173+
graph.add_edge(&v1, &v2).unwrap();
1174+
graph.add_edge(&v3, &v1).unwrap();
1175+
graph.add_edge(&v1, &v4).unwrap();
11931176

1194-
// let v5 = graph.add_vertex(4);
1195-
// let v6 = graph.add_vertex(5);
1177+
let v5 = graph.add_vertex(4);
1178+
let v6 = graph.add_vertex(5);
11961179

1197-
// graph.add_edge(&v5, &v6).unwrap();
1180+
graph.add_edge(&v5, &v6).unwrap();
11981181

1199-
// // Iterate over vertices
1200-
// let mut dfs = graph.dfs();
1182+
// Iterate over vertices
1183+
let mut dfs = graph.dfs();
12011184

1202-
// for _ in 0..2 {
1203-
// let v = dfs.next();
1185+
for _ in 0..2 {
1186+
let v = dfs.next();
12041187

1205-
// if v == Some(&v3) {
1206-
// assert_eq!(dfs.next(), Some(&v1));
1207-
// assert!(set![&v2, &v4] == (&mut dfs).take(2).collect());
1208-
// } else if v == Some(&v5) {
1209-
// assert_eq!(dfs.next(), Some(&v6));
1210-
// } else {
1211-
// panic!("Not a root node")
1212-
// }
1213-
// }
1188+
if v == Some(&v3) {
1189+
assert_eq!(dfs.next(), Some(&v1));
1190+
assert!(set![&v2, &v4] == (&mut dfs).take(2).collect());
1191+
} else if v == Some(&v5) {
1192+
assert_eq!(dfs.next(), Some(&v6));
1193+
} else {
1194+
panic!("Not a root node")
1195+
}
1196+
}
12141197

1215-
// assert_eq!(dfs.count(), 0, "There were remaining nodes");
1216-
// }
1198+
assert_eq!(dfs.count(), 0, "There were remaining nodes");
1199+
}
12171200
}

src/iterators/bfs.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,22 @@ use crate::vertex_id::VertexId;
66
use hashbrown::HashSet;
77
#[cfg(not(feature = "no_std"))]
88
use std::collections::VecDeque;
9-
#[cfg(not(feature = "no_std"))]
10-
use std::sync::Arc;
119

1210
#[cfg(feature = "no_std")]
1311
extern crate alloc;
1412
#[cfg(feature = "no_std")]
15-
use alloc::{collections::vec_deque::VecDeque, sync::Arc};
13+
use alloc::{collections::vec_deque::VecDeque};
1614

1715
#[cfg(feature = "no_std")]
1816
use alloc::vec::Vec;
1917

2018
#[derive(Debug)]
2119
/// Breadth-First Iterator
2220
pub struct Bfs<'a, T> {
23-
queue: VecDeque<Arc<VertexId>>,
24-
current_ptr: Option<Arc<VertexId>>,
25-
visited_set: HashSet<Arc<VertexId>>,
26-
roots_stack: Vec<Arc<VertexId>>,
21+
queue: VecDeque<VertexId>,
22+
current_ptr: Option<VertexId>,
23+
visited_set: HashSet<VertexId>,
24+
roots_stack: Vec<VertexId>,
2725
iterable: &'a Graph<T>,
2826
}
2927

@@ -32,7 +30,7 @@ impl<'a, T> Bfs<'a, T> {
3230
let mut roots_stack = Vec::with_capacity(graph.roots_count());
3331

3432
for v in graph.roots() {
35-
roots_stack.push(Arc::from(*v));
33+
roots_stack.push(v.clone());
3634
}
3735

3836
let current_ptr = roots_stack.pop();
@@ -66,8 +64,8 @@ impl<'a, T> Iterator for Bfs<'a, T> {
6664
// and check their visited status.
6765
for n in self.iterable.out_neighbors(current_ptr.as_ref()) {
6866
if !self.visited_set.contains(n) {
69-
self.visited_set.insert(Arc::from(*n));
70-
self.queue.push_back(Arc::from(*n));
67+
self.visited_set.insert(n.clone());
68+
self.queue.push_back(n.clone());
7169

7270
return self.iterable.fetch_id_ref(n);
7371
}

src/vertex_id.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ impl core::fmt::Debug for VertexId {
1919
}
2020
}
2121

22+
impl core::convert::AsRef<VertexId> for VertexId {
23+
fn as_ref(&self) -> &VertexId {
24+
&self
25+
}
26+
}
27+
2228
impl VertexId {
2329
pub fn random() -> VertexId {
2430
/*

0 commit comments

Comments
 (0)