Skip to content

Commit 8bbb9c8

Browse files
authored
Add _mut methods for edge mutation for faster single-thread access (#121)
* Add _mut methods for edge mutation for faster single-thread access * Avoid duplication layout application
1 parent 39b5165 commit 8bbb9c8

File tree

2 files changed

+82
-23
lines changed

2 files changed

+82
-23
lines changed

crates/builder/src/graph/adj_list.rs

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,28 @@ impl<NI: Idx, EV> AdjacencyList<NI, EV> {
5858
#[inline]
5959
pub(crate) fn insert(&self, source: NI, target: Target<NI, EV>) {
6060
let mut edges = self.edges[source.index()].write().unwrap();
61+
Self::apply_layout(self.layout, &mut edges, target);
62+
}
6163

62-
match self.layout {
64+
#[inline]
65+
pub(crate) fn insert_mut(&mut self, source: NI, target: Target<NI, EV>) {
66+
let edges = self.edges[source.index()].get_mut().unwrap();
67+
Self::apply_layout(self.layout, edges, target);
68+
}
69+
70+
#[inline]
71+
fn check_bounds(&self, node: NI) -> Result<(), crate::Error> {
72+
if node >= self.node_count() {
73+
return Err(crate::Error::MissingNode {
74+
node: format!("{}", node.index()),
75+
});
76+
};
77+
Ok(())
78+
}
79+
80+
#[inline]
81+
fn apply_layout(layout: CsrLayout, edges: &mut Vec<Target<NI, EV>>, target: Target<NI, EV>) {
82+
match layout {
6383
CsrLayout::Sorted => match edges.binary_search(&target) {
6484
Ok(i) => edges.insert(i, target),
6585
Err(i) => edges.insert(i, target),
@@ -345,26 +365,35 @@ impl<NI: Idx, NV> EdgeMutation<NI> for DirectedALGraph<NI, NV> {
345365
fn add_edge(&self, source: NI, target: NI) -> Result<(), crate::Error> {
346366
self.add_edge_with_value(source, target, ())
347367
}
368+
369+
fn add_edge_mut(&mut self, source: NI, target: NI) -> Result<(), crate::Error> {
370+
self.add_edge_with_value_mut(source, target, ())
371+
}
348372
}
349373

350374
impl<NI: Idx, NV, EV: Copy> EdgeMutationWithValues<NI, EV> for DirectedALGraph<NI, NV, EV> {
351375
fn add_edge_with_value(&self, source: NI, target: NI, value: EV) -> Result<(), crate::Error> {
352-
if source >= self.al_out.node_count() {
353-
return Err(crate::Error::MissingNode {
354-
node: format!("{}", source.index()),
355-
});
356-
}
357-
if target >= self.al_inc.node_count() {
358-
return Err(crate::Error::MissingNode {
359-
node: format!("{}", target.index()),
360-
});
361-
}
362-
376+
self.al_out.check_bounds(source)?;
377+
self.al_inc.check_bounds(target)?;
363378
self.al_out.insert(source, Target::new(target, value));
364379
self.al_inc.insert(target, Target::new(source, value));
365380

366381
Ok(())
367382
}
383+
384+
fn add_edge_with_value_mut(
385+
&mut self,
386+
source: NI,
387+
target: NI,
388+
value: EV,
389+
) -> Result<(), crate::Error> {
390+
self.al_out.check_bounds(source)?;
391+
self.al_inc.check_bounds(target)?;
392+
self.al_out.insert_mut(source, Target::new(target, value));
393+
self.al_inc.insert_mut(target, Target::new(source, value));
394+
395+
Ok(())
396+
}
368397
}
369398

370399
impl<NI, EV, E> From<(E, CsrLayout)> for DirectedALGraph<NI, (), EV>
@@ -482,26 +511,35 @@ impl<NI: Idx, NV> EdgeMutation<NI> for UndirectedALGraph<NI, NV, ()> {
482511
fn add_edge(&self, source: NI, target: NI) -> Result<(), crate::Error> {
483512
self.add_edge_with_value(source, target, ())
484513
}
514+
515+
fn add_edge_mut(&mut self, source: NI, target: NI) -> Result<(), crate::Error> {
516+
self.add_edge_with_value_mut(source, target, ())
517+
}
485518
}
486519

487520
impl<NI: Idx, NV, EV: Copy> EdgeMutationWithValues<NI, EV> for UndirectedALGraph<NI, NV, EV> {
488521
fn add_edge_with_value(&self, source: NI, target: NI, value: EV) -> Result<(), crate::Error> {
489-
if source >= self.al.node_count() {
490-
return Err(crate::Error::MissingNode {
491-
node: format!("{}", source.index()),
492-
});
493-
}
494-
if target >= self.al.node_count() {
495-
return Err(crate::Error::MissingNode {
496-
node: format!("{}", target.index()),
497-
});
498-
}
499-
522+
self.al.check_bounds(source)?;
523+
self.al.check_bounds(target)?;
500524
self.al.insert(source, Target::new(target, value));
501525
self.al.insert(target, Target::new(source, value));
502526

503527
Ok(())
504528
}
529+
530+
fn add_edge_with_value_mut(
531+
&mut self,
532+
source: NI,
533+
target: NI,
534+
value: EV,
535+
) -> Result<(), crate::Error> {
536+
self.al.check_bounds(source)?;
537+
self.al.check_bounds(target)?;
538+
self.al.insert_mut(source, Target::new(target, value));
539+
self.al.insert_mut(target, Target::new(source, value));
540+
541+
Ok(())
542+
}
505543
}
506544

507545
impl<NI, EV, E> From<(E, CsrLayout)> for UndirectedALGraph<NI, (), EV>

crates/builder/src/lib.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,16 @@ pub trait EdgeMutation<NI: Idx> {
420420
/// If either the source or the target node does not exist,
421421
/// the method will return [`Error::MissingNode`].
422422
fn add_edge(&self, source: NI, target: NI) -> Result<(), Error>;
423+
424+
/// Adds a new edge between the given source and target node.
425+
///
426+
/// Does not require locking the node-local list due to `&mut self`.
427+
///
428+
/// # Errors
429+
///
430+
/// If either the source or the target node does not exist,
431+
/// the method will return [`Error::MissingNode`].
432+
fn add_edge_mut(&mut self, source: NI, target: NI) -> Result<(), Error>;
423433
}
424434

425435
/// Allows adding new edges to a graph.
@@ -432,6 +442,17 @@ pub trait EdgeMutationWithValues<NI: Idx, EV> {
432442
/// If either the source or the target node does not exist,
433443
/// the method will return [`Error::MissingNode`].
434444
fn add_edge_with_value(&self, source: NI, target: NI, value: EV) -> Result<(), Error>;
445+
446+
/// Adds a new edge between the given source and target node
447+
/// and assigns the given value to it.
448+
///
449+
/// Does not require locking the node-local list due to `&mut self`.
450+
///
451+
/// # Errors
452+
///
453+
/// If either the source or the target node does not exist,
454+
/// the method will return [`Error::MissingNode`].
455+
fn add_edge_with_value_mut(&mut self, source: NI, target: NI, value: EV) -> Result<(), Error>;
435456
}
436457

437458
#[repr(transparent)]

0 commit comments

Comments
 (0)