Skip to content

Commit bf83aca

Browse files
committed
Update daggy and use StableDag
Fix RustAudio#103. Use the StableDag structure which (which uses petgraph's StableGraph) implements a directed acyclic graph with stable indices.
1 parent f8a355b commit bf83aca

File tree

3 files changed

+52
-72
lines changed

3 files changed

+52
-72
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ name = "dsp"
1919
path = "./src/lib.rs"
2020

2121
[dependencies]
22-
daggy = "0.4.0"
22+
daggy = { git = "https://github.com/mitchmindtree/daggy", rev = "bcb36c7b", features = ["stable_dag"] }
2323
sample = "0.10.0"
2424

2525
[dev-dependencies]

src/graph.rs

Lines changed: 48 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,33 @@
88
//! The `Graph` type requires that its nodes implement the [`Node`](../node/trait.Node.html) trait.
99
1010
use crate::node::Node;
11-
use daggy::{self, Walker};
11+
use daggy::{stabledag, petgraph::{self, visit::{IntoNodeReferences, IntoEdgeReferences, EdgeRef}}};
1212
use sample::{self, Frame, Sample};
1313

14+
// Daggy/petgraph re-exports
15+
pub use stabledag::Walker;
16+
1417
/// An alias for our Graph's Node Index.
15-
pub type NodeIndex = daggy::NodeIndex<usize>;
18+
pub type NodeIndex = stabledag::NodeIndex<usize>;
1619
/// An alias for our Graph's Edge Index.
17-
pub type EdgeIndex = daggy::EdgeIndex<usize>;
20+
pub type EdgeIndex = stabledag::EdgeIndex<usize>;
1821

19-
/// An alias for the iterator yielding mutable access to all node weights.
20-
pub type NodesMut<'a, N> = daggy::NodeWeightsMut<'a, N, usize>;
22+
/// An alias for our Graph's Node Indices.
23+
pub type NodeReferences<'a, N> = petgraph::stable_graph::NodeReferences<'a, N, usize>;
24+
/// An alias for our Graph's Edge Indices.
25+
pub type EdgeReferences<'a, N> = petgraph::stable_graph::EdgeReferences<'a, N, usize>;
2126

22-
/// Read only access to a **Graph**'s internal node array.
23-
pub type RawNodes<'a, N> = daggy::RawNodes<'a, N, usize>;
24-
/// Read only access to a **Graph**'s internal edge array.
25-
pub type RawEdges<'a, F> = daggy::RawEdges<'a, Connection<F>, usize>;
27+
/// An alias for the iterator yielding mutable access to all node weights.
28+
pub type NodesMut<'a, N> = stabledag::NodeWeightsMut<'a, N, usize>;
2629

2730
/// An iterator yielding indices to recently added connections.
28-
pub type EdgeIndices = daggy::EdgeIndices<usize>;
31+
pub type EdgeIndices = stabledag::EdgeIndices<usize>;
2932

3033
/// An alias for the **Dag** used within our **Graph**.
31-
pub type Dag<F, N> = daggy::Dag<N, Connection<F>, usize>;
34+
pub type Dag<F, N> = stabledag::StableDag<N, Connection<F>, usize>;
3235

3336
/// An alias for the **PetGraph** used by our **Graph**'s internal **Dag**.
34-
pub type PetGraph<F, N> = daggy::PetGraph<N, Connection<F>, usize>;
37+
pub type PetGraph<F, N> = petgraph::stable_graph::StableDiGraph<N, Connection<F>, usize>;
3538

3639
/// A directed, acyclic DSP graph.
3740
///
@@ -104,12 +107,12 @@ pub struct WouldCycle;
104107

105108
/// A walker object for walking over nodes that are inputs to some node.
106109
pub struct Inputs<F, N> {
107-
parents: daggy::Parents<N, Connection<F>, usize>,
110+
parents: stabledag::Parents<N, Connection<F>, usize>,
108111
}
109112

110113
/// A walker object for walking over nodes that are outputs to some node.
111114
pub struct Outputs<F, N> {
112-
children: daggy::Children<N, Connection<F>, usize>,
115+
children: stabledag::Children<N, Connection<F>, usize>,
113116
}
114117

115118
/// A walker type for walking over a **Graph**'s nodes in the order in which they will visited when
@@ -135,7 +138,7 @@ where
135138
/// rough idea of the number of nodes, connections and frames per buffer upon the **Graph**'s
136139
/// instantiation.
137140
pub fn new() -> Self {
138-
let dag = daggy::Dag::new();
141+
let dag = Dag::new();
139142
Graph {
140143
dag: dag,
141144
visit_order: Vec::new(),
@@ -152,7 +155,7 @@ where
152155
/// for mixing the dry and wet signals when `Node::audio_requested` is called.
153156
pub fn with_capacity(nodes: usize, connections: usize, frames_per_buffer: usize) -> Self {
154157
Graph {
155-
dag: daggy::Dag::with_capacity(nodes, connections),
158+
dag: Dag::with_capacity(nodes, connections),
156159
visit_order: Vec::with_capacity(nodes),
157160
dry_buffer: Vec::with_capacity(frames_per_buffer),
158161
maybe_master: None,
@@ -234,26 +237,24 @@ where
234237
self.dag.node_weight_mut(node)
235238
}
236239

237-
/// Read only access to the internal node array.
238-
pub fn raw_nodes(&self) -> RawNodes<N> {
239-
self.dag.raw_nodes()
240+
/// An iterator over the graph's nodes.
241+
pub fn node_references(&self) -> NodeReferences<N> {
242+
self.dag.node_references()
240243
}
241244

242-
/// An iterator yielding mutable access to all nodes.
243-
///
244-
/// The order in which nodes are yielded matches the order of their indices.
245-
pub fn nodes_mut(&mut self) -> NodesMut<N> {
246-
self.dag.node_weights_mut()
245+
/// An iterator over the graph's edges.
246+
pub fn edge_references(&self) -> EdgeReferences<Connection<F>> {
247+
self.dag.edge_references()
247248
}
248249

249250
/// A reference to the connection at the given index (or `None` if it doesn't exist).
250251
pub fn connection(&self, edge: EdgeIndex) -> Option<&Connection<F>> {
251252
self.dag.edge_weight(edge)
252253
}
253254

254-
/// Read only access to the internal edge array.
255-
pub fn raw_edges(&self) -> RawEdges<F> {
256-
self.dag.raw_edges()
255+
/// A mutable reference to the connection at the given index (or `None` if it doesn't exist)
256+
fn connection_mut(&mut self, edge: EdgeIndex) -> Option<&mut Connection<F>> {
257+
self.dag.edge_weight_mut(edge)
257258
}
258259

259260
/// Index the **Graph** by two `NodeIndex`s at once.
@@ -480,7 +481,7 @@ where
480481
pub fn remove_all_input_connections(&mut self, idx: NodeIndex) -> usize {
481482
let mut inputs = self.inputs(idx);
482483
let mut num = 0;
483-
while let Some(connection) = inputs.next_edge(&self) {
484+
while let Some((connection, _)) = inputs.walk_next(&self) {
484485
self.remove_edge(connection);
485486
num += 1;
486487
}
@@ -493,7 +494,7 @@ where
493494
pub fn remove_all_output_connections(&mut self, idx: NodeIndex) -> usize {
494495
let mut outputs = self.outputs(idx);
495496
let mut num = 0;
496-
while let Some(connection) = outputs.next_edge(&self) {
497+
while let Some((connection, _)) = outputs.walk_next(&self) {
497498
self.remove_edge(connection);
498499
num += 1;
499500
}
@@ -509,8 +510,8 @@ where
509510
let mut num_removed = 0;
510511
for i in 0..self.dag.node_count() {
511512
let idx = NodeIndex::new(i);
512-
let num_inputs = self.inputs(idx).count(self);
513-
let num_outputs = self.outputs(idx).count(self);
513+
let num_inputs = self.inputs(idx).iter(self).count();
514+
let num_outputs = self.outputs(idx).iter(self).count();
514515
if num_inputs == 0 && num_outputs == 0 {
515516
if self.maybe_master == Some(idx) {
516517
self.maybe_master = None;
@@ -535,7 +536,9 @@ where
535536
resize_buffer_to(&mut self.dry_buffer, buffer_size);
536537

537538
// Initialise all connection buffers.
538-
for connection in self.dag.edge_weights_mut() {
539+
let edge_ids = self.edge_references().map(|e| e.id()).collect::<Vec<_>>();
540+
for edge_id in edge_ids {
541+
let connection = self.connection_mut(edge_id).unwrap();
539542
resize_buffer_to(&mut connection.buffer, buffer_size);
540543
}
541544
}
@@ -566,7 +569,7 @@ where
566569

567570
// Walk over each of the input connections to sum their buffers to the output.
568571
let mut inputs = self.inputs(node_idx);
569-
while let Some(connection_idx) = inputs.next_edge(self) {
572+
while let Some((connection_idx, _)) = inputs.walk_next(self) {
570573
let connection = &self[connection_idx];
571574
// Sum the connection's buffer onto the output.
572575
//
@@ -621,7 +624,7 @@ where
621624

622625
// Walk over each of the outgoing connections and write the rendered output to them.
623626
let mut outputs = self.outputs(node_idx);
624-
while let Some(connection_idx) = outputs.next_edge(self) {
627+
while let Some((connection_idx, _)) = outputs.walk_next(self) {
625628
let connection = &mut self.dag[connection_idx];
626629

627630
// Ensure the buffer matches the target length.
@@ -646,7 +649,8 @@ where
646649
///
647650
/// The user should never have to worry about this, thus the method is private.
648651
fn prepare_visit_order(&mut self) {
649-
self.visit_order = daggy::petgraph::algo::toposort(self.dag.graph());
652+
self.visit_order = petgraph::algo::toposort(self.dag.graph(), None)
653+
.expect("A cycle was found in the DAG while toposorting");
650654
}
651655
}
652656

@@ -686,7 +690,7 @@ where
686690
// use the first node that has no output connections.
687691
let mut visit_order_rev = self.visit_order_rev();
688692
while let Some(node) = visit_order_rev.next(self) {
689-
if self.inputs(node).count(self) == 0 {
693+
if self.inputs(node).iter(self).count() == 0 {
690694
self.audio_requested_from(node, output, sample_hz);
691695
return;
692696
}
@@ -696,47 +700,23 @@ where
696700
}
697701
}
698702

699-
impl<F, N> Walker<Graph<F, N>> for Inputs<F, N> {
700-
type Index = usize;
703+
impl<F, N> Walker<&Graph<F, N>> for Inputs<F, N> {
704+
type Item = (EdgeIndex, NodeIndex);
701705

702706
/// The next (connection, node) input pair to some node in our walk for the given **Graph**.
703707
#[inline]
704-
fn next(&mut self, graph: &Graph<F, N>) -> Option<(EdgeIndex, NodeIndex)> {
705-
self.parents.next(&graph.dag)
706-
}
707-
708-
/// The next input connection to some node in our walk for the given **Graph**.
709-
#[inline]
710-
fn next_edge(&mut self, graph: &Graph<F, N>) -> Option<EdgeIndex> {
711-
self.parents.next_edge(&graph.dag)
712-
}
713-
714-
/// The next input node to some node in our walk for the given **Graph**.
715-
#[inline]
716-
fn next_node(&mut self, graph: &Graph<F, N>) -> Option<NodeIndex> {
717-
self.parents.next_node(&graph.dag)
708+
fn walk_next(&mut self, graph: &Graph<F, N>) -> Option<(EdgeIndex, NodeIndex)> {
709+
self.parents.walk_next(&graph.dag)
718710
}
719711
}
720712

721-
impl<F, N> Walker<Graph<F, N>> for Outputs<F, N> {
722-
type Index = usize;
713+
impl<F, N> Walker<&Graph<F, N>> for Outputs<F, N> {
714+
type Item = (EdgeIndex, NodeIndex);
723715

724716
/// The next (connection, node) output pair from some node in our walk for the given **Graph**.
725717
#[inline]
726-
fn next(&mut self, graph: &Graph<F, N>) -> Option<(EdgeIndex, NodeIndex)> {
727-
self.children.next(&graph.dag)
728-
}
729-
730-
/// The next output connection from some node in our walk for the given **Graph**.
731-
#[inline]
732-
fn next_edge(&mut self, graph: &Graph<F, N>) -> Option<EdgeIndex> {
733-
self.children.next_edge(&graph.dag)
734-
}
735-
736-
/// The next output node from some node in our walk for the given **Graph**.
737-
#[inline]
738-
fn next_node(&mut self, graph: &Graph<F, N>) -> Option<NodeIndex> {
739-
self.children.next_node(&graph.dag)
718+
fn walk_next(&mut self, graph: &Graph<F, N>) -> Option<(EdgeIndex, NodeIndex)> {
719+
self.children.walk_next(&graph.dag)
740720
}
741721
}
742722

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
#![forbid(unsafe_code)]
1313
#![deny(missing_docs)]
1414

15-
pub use daggy::{self, Walker};
15+
pub use daggy::stabledag;
1616
pub use graph::{
17-
Connection, Dag, EdgeIndex, Graph, Inputs, NodeIndex, NodesMut, Outputs, PetGraph, RawEdges,
18-
RawNodes, VisitOrder, VisitOrderReverse, WouldCycle,
17+
Connection, Dag, EdgeIndex, Graph, Inputs, NodeIndex, NodesMut, Outputs, PetGraph,
18+
VisitOrder, VisitOrderReverse, WouldCycle, Walker,
1919
};
2020
pub use node::Node;
2121
pub use sample::{

0 commit comments

Comments
 (0)