Skip to content

Commit 368db99

Browse files
committed
rewriting (does not compile)
1 parent b0da56f commit 368db99

File tree

4 files changed

+90
-29
lines changed

4 files changed

+90
-29
lines changed

src/dfx/src/lib/graph/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod traverse_filtered;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// TODO: Somebody, adopt this code to `pethgraph`.
2+
use petgraph::{data::DataMap, visit::{Dfs, IntoNeighbors, VisitMap}};
3+
4+
pub struct DfsFiltered<N, VM>
5+
// where P: FnMut(&N) -> bool
6+
{
7+
base: Dfs<N, VM>,
8+
// node_filter: P,
9+
}
10+
11+
impl<N, VM> DfsFiltered<N, VM> {
12+
pub fn new(base: Dfs<N, VM>) -> Self {
13+
Self {
14+
base
15+
}
16+
}
17+
18+
pub fn traverse<G, P, C>(&mut self, graph: G, predicate: P, call: C)
19+
where C: Fn(&N, &N) -> (),
20+
G: IntoNeighbors<NodeId = N> + DataMap<NodeWeight = N>,
21+
P: Fn(&N) -> bool,
22+
N: Copy + PartialEq,
23+
VM: VisitMap<N>,
24+
{
25+
while let Some(item) = &self.base.next(graph) {
26+
if predicate(item) {
27+
let parent = self.base.stack.iter().rev().find(
28+
|&entry| if let Some(elt) = graph.node_weight(*entry) {
29+
predicate(elt)
30+
} else {
31+
false
32+
}
33+
);
34+
if let Some(parent) = parent {
35+
call(parent, item);
36+
}
37+
}
38+
}
39+
}
40+
}

src/dfx/src/lib/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ pub mod diagnosis;
88
pub mod environment;
99
pub mod error;
1010
pub mod error_code;
11+
pub mod graph;
1112
pub mod ic_attributes;
1213
pub mod identity;
1314
pub mod info;

src/dfx/src/lib/models/canister.rs

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::lib::environment::Environment;
77
use crate::lib::error::{BuildError, DfxError, DfxResult};
88
use crate::lib::metadata::dfx::DfxMetadata;
99
use crate::lib::metadata::names::{CANDID_ARGS, CANDID_SERVICE, DFX};
10-
use crate::lib::operations::canister;
10+
use crate::lib::graph::traverse_filtered::{self, DfsFiltered};
1111
use crate::lib::wasm::file::{compress_bytes, read_wasm_module};
1212
use crate::util::assets;
1313
use anyhow::{anyhow, bail, Context};
@@ -578,39 +578,58 @@ impl CanisterPool {
578578
Some(canisters_to_build) => canisters_to_build,
579579
None => self.canisters.iter().map(|canister| canister.get_name().to_string()).collect(),
580580
};
581-
// Transform the graph of file dependencies to graph of canister dependencies.
582-
// For this do DFS for each of `real_canisters_to_build`.
583-
// TODO: Somebody, adopt this code to `pethgraph`.
581+
// // Transform the graph of file dependencies to graph of canister dependencies.
582+
// // For this do DFS for each of `real_canisters_to_build`.
584583
let source_graph = &self.imports.borrow().graph;
585584
let mut dest_graph: DiGraph<CanisterId, ()> = DiGraph::new();
586585
let mut dest_id_set = HashMap::new();
587-
let mut name_to_dest = HashMap::new();
588-
for start_name in real_canisters_to_build.iter() {
589-
let dest_start = self.get_first_canister_with_name(&start_name).unwrap().canister_id();
590-
let dest_start = *dest_id_set.entry(dest_start.clone()).or_insert_with(|| dest_graph.add_node(dest_start.clone())); // TODO: always inserts
591-
name_to_dest.insert(start_name, dest_start);
592-
let mut iter = Dfs::new(&source_graph, dest_start);
593-
iter.next(&source_graph);
594-
while let Some(cur_source_id) = iter.next(&source_graph) {
595-
let cur_source_node = source_graph.node_weight(cur_source_id).unwrap();
596-
if let MotokoImport::Canister(name) = cur_source_node {
597-
let parent_in_source_id = *iter.stack.iter().rev().find(
598-
|&entry|
599-
if let Some(MotokoImport::Canister(_parent_name)) = source_graph.node_weight(*entry) {
600-
true
601-
} else {
602-
false
603-
}
604-
).unwrap();
605-
// Both parent and current ancestor are `Canister` dependencies.
606-
let parent_in_dest_id =
607-
name_to_dest.entry(parent_in_source_id).or_insert_with(|| dest_graph.add_node(cur_canister_id));
608-
dest_graph.add_edge(parent_in_dest_id, b, ())
609-
// let parent_in_source = source_graph.node_weight(*parent_in_source).unwrap();
586+
let dfs = Dfs::from_parts(real_canisters_to_build, HashMap::new()); // TODO: Use `FixedBitSet` instead of `HashMap`?
587+
let filtered_dfs = DfsFiltered::new(dfs);
588+
filtered_dfs.traverse(
589+
source_graph,
590+
|s| {
591+
if let Some(MotokoImport::Canister(_parent_name)) = source_graph.node_weight(*entry) {
592+
true
593+
} else {
594+
false
610595
}
611-
// let cur_node_id = id_set.entry(cur_source_id).or_insert_with(|| id_set.insert(cur_source_id));
596+
},
597+
|parent, child| {
598+
let parent_id = *dest_id_set.entry(parent).or_insert_with(|| dest_graph.add_node(parent));
599+
let child_id = *dest_id_set.entry(child).or_insert_with(|| dest_graph.add_node(child));
600+
dest_graph.add_edge(parent_id, child_id, ());
612601
}
613-
}
602+
);
603+
// let source_graph = &self.imports.borrow().graph;
604+
// let mut dest_graph: DiGraph<CanisterId, ()> = DiGraph::new();
605+
// let mut dest_id_set = HashMap::new();
606+
// let mut name_to_dest = HashMap::new();
607+
// for start_name in real_canisters_to_build.iter() {
608+
// let dest_start = self.get_first_canister_with_name(&start_name).unwrap().canister_id();
609+
// let dest_start = *dest_id_set.entry(dest_start.clone()).or_insert_with(|| dest_graph.add_node(dest_start.clone())); // TODO: always inserts
610+
// name_to_dest.insert(start_name, dest_start);
611+
// let mut iter = Dfs::new(&source_graph, dest_start);
612+
// iter.next(&source_graph);
613+
// while let Some(cur_source_id) = iter.next(&source_graph) {
614+
// let cur_source_node = source_graph.node_weight(cur_source_id).unwrap();
615+
// if let MotokoImport::Canister(name) = cur_source_node {
616+
// let parent_in_source_id = *iter.stack.iter().rev().find(
617+
// |&entry|
618+
// if let Some(MotokoImport::Canister(_parent_name)) = source_graph.node_weight(*entry) {
619+
// true
620+
// } else {
621+
// false
622+
// }
623+
// ).unwrap();
624+
// // Both parent and current ancestor are `Canister` dependencies.
625+
// let parent_in_dest_id =
626+
// name_to_dest.entry(parent_in_source_id).or_insert_with(|| dest_graph.add_node(cur_canister_id));
627+
// dest_graph.add_edge(parent_in_dest_id, b, ())
628+
// // let parent_in_source = source_graph.node_weight(*parent_in_source).unwrap();
629+
// }
630+
// // let cur_node_id = id_set.entry(cur_source_id).or_insert_with(|| id_set.insert(cur_source_id));
631+
// }
632+
// }
614633

615634
Ok(dest_graph)
616635
// FIXME: Wrong behavior on indirect dependencies.

0 commit comments

Comments
 (0)