-
-
Notifications
You must be signed in to change notification settings - Fork 636
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[engine] rm python graphmaker; create dot formatted display #4295
Changes from 1 commit
d51e93a
8859afd
f103b04
df5f362
8eaec05
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
33d19203e5948e2c510aa872df99e2053ad44976 | ||
aa91e2c950bf916906836bec8bd28bd4f2408327 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ use nodes::Runnable; | |
use std::collections::{hash_map, HashMap, HashSet, VecDeque}; | ||
use std::hash::Hash; | ||
use std::fmt; | ||
use std::io; | ||
|
||
use tasks::{Task, Tasks}; | ||
|
||
|
@@ -137,11 +138,6 @@ type RuleDependencyEdges = HashMap<InnerEntry, RuleEdges>; | |
type RuleDiagnostics = Vec<Diagnostic>; | ||
type UnfulfillableRuleMap = HashMap<Entry, RuleDiagnostics>; | ||
|
||
#[derive(Debug)] | ||
pub struct RootSubjectTypes { | ||
pub subject_types: Vec<TypeId> | ||
} | ||
|
||
#[derive(Eq, Hash, PartialEq, Clone, Debug)] | ||
pub struct Diagnostic { | ||
subject_type: TypeId, | ||
|
@@ -152,11 +148,11 @@ pub struct Diagnostic { | |
// to be found statically rather than dynamically. | ||
pub struct GraphMaker<'a> { | ||
tasks: &'a Tasks, | ||
root_subject_types: RootSubjectTypes | ||
root_subject_types: Vec<TypeId> | ||
} | ||
|
||
impl <'a> GraphMaker<'a> { | ||
pub fn new<'t>(tasks: &'t Tasks, root_subject_types: RootSubjectTypes) -> GraphMaker { | ||
pub fn new<'t>(tasks: &'t Tasks, root_subject_types: Vec<TypeId>) -> GraphMaker { | ||
GraphMaker { tasks: tasks, root_subject_types: root_subject_types } | ||
} | ||
|
||
|
@@ -165,15 +161,15 @@ impl <'a> GraphMaker<'a> { | |
let mut full_dependency_edges: RuleDependencyEdges = HashMap::new(); | ||
let mut full_unfulfillable_rules: UnfulfillableRuleMap = HashMap::new(); | ||
|
||
let beginning_root_opt = self.gen_root_entry(subject_type, product_type); | ||
if beginning_root_opt.is_none() { | ||
let beginning_root = if let Some(beginning_root) = self.gen_root_entry(subject_type, product_type) { | ||
beginning_root | ||
} else { | ||
return RuleGraph { root_subject_types: vec![], | ||
root_dependencies: full_root_rule_dependency_edges, | ||
rule_dependency_edges: full_dependency_edges, | ||
unfulfillable_rules: full_unfulfillable_rules, | ||
} | ||
} | ||
let beginning_root = beginning_root_opt.unwrap(); | ||
}; | ||
|
||
let constructed_graph = self._construct_graph( | ||
beginning_root, | ||
|
@@ -189,14 +185,15 @@ impl <'a> GraphMaker<'a> { | |
|
||
self.add_unreachable_rule_diagnostics(&full_dependency_edges, &mut full_unfulfillable_rules); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It certainly seems like you should be able to pass these in without cloning them... is the issue just that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. I started to see that when I extracted the method. Thanks for pointing it out. |
||
|
||
let unfinished_graph = RuleGraph { | ||
root_subject_types: self.root_subject_types.subject_types.clone(), | ||
let mut unfinished_graph = RuleGraph { | ||
root_subject_types: self.root_subject_types.clone(), | ||
root_dependencies: full_root_rule_dependency_edges, | ||
rule_dependency_edges: full_dependency_edges, | ||
unfulfillable_rules: full_unfulfillable_rules | ||
}; | ||
|
||
self._remove_unfulfillable_rules_and_dependents(unfinished_graph) | ||
self._remove_unfulfillable_rules_and_dependents(&mut unfinished_graph); | ||
unfinished_graph | ||
} | ||
|
||
pub fn full_graph(&self) -> RuleGraph { | ||
|
@@ -221,14 +218,15 @@ impl <'a> GraphMaker<'a> { | |
|
||
self.add_unreachable_rule_diagnostics(&full_dependency_edges, &mut full_unfulfillable_rules); | ||
|
||
let unfinished_graph = RuleGraph { | ||
root_subject_types: self.root_subject_types.subject_types.clone(), | ||
let mut in_progress_graph = RuleGraph { | ||
root_subject_types: self.root_subject_types.clone(), | ||
root_dependencies: full_root_rule_dependency_edges, | ||
rule_dependency_edges: full_dependency_edges, | ||
unfulfillable_rules: full_unfulfillable_rules | ||
}; | ||
|
||
self._remove_unfulfillable_rules_and_dependents(unfinished_graph) | ||
self._remove_unfulfillable_rules_and_dependents(&mut in_progress_graph); | ||
in_progress_graph | ||
} | ||
|
||
fn add_unreachable_rule_diagnostics(&self, full_dependency_edges: &RuleDependencyEdges, full_unfulfillable_rules: &mut UnfulfillableRuleMap) { | ||
|
@@ -427,15 +425,15 @@ impl <'a> GraphMaker<'a> { | |
} | ||
} | ||
RuleGraph { | ||
root_subject_types: self.root_subject_types.subject_types.clone(), | ||
root_subject_types: self.root_subject_types.clone(), | ||
root_dependencies: root_rule_dependency_edges, | ||
rule_dependency_edges: rule_dependency_edges, | ||
unfulfillable_rules: unfulfillable_rules | ||
} | ||
} | ||
|
||
fn _remove_unfulfillable_rules_and_dependents(&self, | ||
mut rule_graph: RuleGraph) -> RuleGraph { | ||
rule_graph: &mut RuleGraph) { | ||
// Removes all unfulfillable rules transitively from the roots and the dependency edges. | ||
// | ||
// Takes the current root rule set and dependency table and removes all rules that are not | ||
|
@@ -478,12 +476,11 @@ impl <'a> GraphMaker<'a> { | |
} | ||
} | ||
} | ||
rule_graph | ||
} | ||
|
||
fn gen_root_entries(&self, product_types: &Vec<TypeConstraint>) -> Vec<RootEntry> { | ||
fn gen_root_entries(&self, product_types: &HashSet<TypeConstraint>) -> Vec<RootEntry> { | ||
let mut result: Vec<RootEntry> = Vec::new(); | ||
for subj_type in &self.root_subject_types.subject_types { | ||
for subj_type in &self.root_subject_types { | ||
for pt in product_types { | ||
if let Some(entry) = self.gen_root_entry(subj_type, pt) { | ||
result.push(entry); | ||
|
@@ -688,26 +685,23 @@ impl RuleGraph { | |
_ => false, | ||
}) | ||
} | ||
} | ||
|
||
impl fmt::Display for RuleGraph { | ||
// TODO instead of this, make own fmt thing that accepts externs | ||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
pub fn visualize(&self, f: &mut io::Write) -> io::Result<()> { | ||
if self.root_dependencies.is_empty() && self.rule_dependency_edges.is_empty() { | ||
try!(f.write_str("digraph {\n")); | ||
try!(f.write_str(" // empty graph\n")); | ||
return f.write_str("}"); | ||
write!(f, "digraph {{\n")?; | ||
write!(f, " // empty graph\n")?; | ||
return write!(f, "}}"); | ||
} | ||
|
||
|
||
let mut root_subject_type_strs = self.root_subject_types.iter() | ||
.map(|&t| type_str(t)) | ||
.collect::<Vec<String>>(); | ||
root_subject_type_strs.sort(); | ||
try!(f.write_str("digraph {\n")); | ||
try!(write!(f, " // root subject types: {}\n", root_subject_type_strs | ||
.join(", "))); | ||
try!(f.write_str(" // root entries\n")); | ||
write!(f, "digraph {{\n")?; | ||
write!(f, " // root subject types: {}\n", root_subject_type_strs.join(", "))?; | ||
write!(f, " // root entries\n")?; | ||
let mut root_rule_strs = self.root_dependencies.iter() | ||
.map(|(k, deps)| { | ||
let root_str = entry_str(&Entry::from(k.clone())); | ||
|
@@ -721,20 +715,19 @@ impl fmt::Display for RuleGraph { | |
}) | ||
.collect::<Vec<String>>(); | ||
root_rule_strs.sort(); | ||
try!(write!(f, "{}\n", root_rule_strs.join("\n"))); | ||
write!(f, "{}\n", root_rule_strs.join("\n"))?; | ||
|
||
|
||
try!(f.write_str(" // internal entries\n")); | ||
write!(f, " // internal entries\n")?; | ||
let mut internal_rule_strs = self.rule_dependency_edges.iter() | ||
.map(|(k, deps)| format!(" \"{}\" -> {{{}}}", entry_str(&Entry::from(k.clone())), deps.dependencies.iter() | ||
.map(|d| format!("\"{}\"", entry_str(d))) | ||
.collect::<Vec<String>>() | ||
.join(" "))) | ||
.collect::<Vec<String>>(); | ||
internal_rule_strs.sort(); | ||
try!(write!(f, "{}\n", internal_rule_strs.join("\n"))); | ||
|
||
f.write_str("}") | ||
write!(f, "{}\n", internal_rule_strs.join("\n"))?; | ||
write!(f, "}}") | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than:
... you can just return the result of visualize: