Skip to content

Commit

Permalink
WIP: Back to working, except for the new capability.
Browse files Browse the repository at this point in the history
# Building wheels and fs_util will be skipped. Delete if not intended.
[ci skip-build-wheels]
  • Loading branch information
stuhood committed Sep 1, 2022
1 parent c8867a1 commit f1be0bd
Showing 1 changed file with 81 additions and 55 deletions.
136 changes: 81 additions & 55 deletions src/rust/engine/rule_graph/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// Licensed under the Apache License, Version 2.0 (see LICENSE).

use crate::rules::{DependencyKey, ParamTypes, Query, Rule};
use crate::{params_str, Entry, EntryWithDeps, RootEntry, RuleEdges, RuleEntry, Reentry, RuleGraph};
use crate::{
params_str, Entry, EntryWithDeps, Reentry, RootEntry, RuleEdges, RuleEntry, RuleGraph,
};

use std::collections::{BTreeMap, VecDeque};

Expand Down Expand Up @@ -45,11 +47,31 @@ impl<R: Rule> Node<R> {
// TODO: Give Query an internal DependencyKey to avoid cloning here.
match self {
Node::Rule(r) => r.dependency_keys().into_iter().cloned().collect(),
Node::Reentry(_, in_scope_params) => in_scope_params.iter().cloned().map(DependencyKey::new).collect(),
Node::Reentry(_, in_scope_params) => in_scope_params
.iter()
.cloned()
.map(DependencyKey::new)
.collect(),
Node::Query(q) => vec![DependencyKey::new(q.product)],
Node::Param(_) => vec![],
}
}

fn add_inherent_in_set(&self, in_set: &mut ParamTypes<R::TypeId>) {
match self {
Node::Reentry(query, _) => {
// Reentry nodes include in_sets computed from their Query and their dependencies.
in_set.extend(query.params.iter().cloned());
}
Node::Param(p) => {
// Params are always leaves with an in-set of their own value, and no out-set.
in_set.insert(*p);
}
Node::Rule(_) | Node::Query(_) => {
// Rules and Queries only have in_sets computed from their dependencies.
}
}
}
}

///
Expand Down Expand Up @@ -186,14 +208,12 @@ pub struct Builder<R: Rule> {
impl<R: Rule> Builder<R> {
pub fn new(rules: IndexSet<R>, mut queries: IndexSet<Query<R::TypeId>>) -> Builder<R> {
// Extend the Queries with those assumed by Reentry nodes.
queries.extend(rules
.iter()
.flat_map(|rule| {
rule
.dependency_keys()
.into_iter()
.filter_map(|dk| dk.as_reentry_query())
}));
queries.extend(rules.iter().flat_map(|rule| {
rule
.dependency_keys()
.into_iter()
.filter_map(|dk| dk.as_reentry_query())
}));

// Group rules by product/return type.
let mut rules_by_type = BTreeMap::new();
Expand Down Expand Up @@ -280,7 +300,14 @@ impl<R: Rule> Builder<R> {

// Rules and Reentries are created on the fly based on the out_set of dependees.
let mut rules: HashMap<(R, ParamTypes<R::TypeId>), NodeIndex<u32>> = HashMap::default();
let mut reentries: HashMap<(Query<R::TypeId>, ParamTypes<R::TypeId>, ParamTypes<R::TypeId>), NodeIndex<u32>> = HashMap::default();
let mut reentries: HashMap<
(
Query<R::TypeId>,
ParamTypes<R::TypeId>,
ParamTypes<R::TypeId>,
),
NodeIndex<u32>,
> = HashMap::default();
let mut satisfiable_nodes: HashSet<Node<R>> = HashSet::default();
let mut unsatisfiable_nodes: HashMap<NodeIndex<u32>, Vec<DependencyKey<R::TypeId>>> =
HashMap::default();
Expand Down Expand Up @@ -311,15 +338,14 @@ impl<R: Rule> Builder<R> {
if let Some(in_scope_params) = dependency_key.in_scope_params.as_ref() {
// If a DependencyKey has `in_scope_params`, it is solved by re-entering the graph with
// a Query.
let query =
Query::new(
dependency_key.product,
dependency_key
.provided_params
.iter()
.chain(in_scope_params.iter())
.cloned()
);
let query = Query::new(
dependency_key.product,
dependency_key
.provided_params
.iter()
.chain(in_scope_params.iter())
.cloned(),
);
let in_scope_params = in_scope_params.into_iter().cloned().collect();
return (dependency_key, vec![Node::Reentry(query, in_scope_params)]);
}
Expand Down Expand Up @@ -391,7 +417,12 @@ impl<R: Rule> Builder<R> {
// This can be revisited in future.
let reentry_id = reentries
.entry((query.clone(), in_scope_params.clone(), out_set.clone()))
.or_insert_with(|| graph.add_node((Node::Reentry(query.clone(), in_scope_params), out_set.clone())));
.or_insert_with(|| {
graph.add_node((
Node::Reentry(query.clone(), in_scope_params),
out_set.clone(),
))
});
graph.add_edge(node_id, *reentry_id, dependency_key.clone());
to_visit.push(*reentry_id);
}
Expand Down Expand Up @@ -875,35 +906,22 @@ impl<R: Rule> Builder<R> {
}

// Compute an initial in_set from the Node's dependencies.
let mut in_set =
Self::dependencies_in_set(
node_id,
graph
.edges_directed(node_id, Direction::Outgoing)
.filter(|edge_ref| !graph[edge_ref.target()].is_deleted())
.map(|edge_ref| {
(
edge_ref.weight().clone(),
edge_ref.target(),
&graph[edge_ref.target()].0.in_set,
)
}),
);
let mut in_set = Self::dependencies_in_set(
node_id,
graph
.edges_directed(node_id, Direction::Outgoing)
.filter(|edge_ref| !graph[edge_ref.target()].is_deleted())
.map(|edge_ref| {
(
edge_ref.weight().clone(),
edge_ref.target(),
&graph[edge_ref.target()].0.in_set,
)
}),
);

// Then extend it with Node-specific params.
match &graph[node_id].0.node {
Node::Rule(_) | Node::Query(_) => {
// Rules and Queries only have in_sets computed from their dependencies.
}
Node::Reentry(query, _) => {
// Reentry nodes include in_sets computed from their Query and their dependencies.
in_set.extend(query.params.iter().cloned());
}
Node::Param(p) => {
// Params are always leaves with an in-set of their own value, and no out-set.
in_set.insert(*p);
}
};
graph[node_id].0.node.add_inherent_in_set(&mut in_set);

if in_set != graph[node_id].0.in_set {
to_visit.extend(graph.neighbors_directed(node_id, Direction::Incoming));
Expand Down Expand Up @@ -1209,7 +1227,10 @@ impl<R: Rule> Builder<R> {
}))),
Node::Query(q) => Entry::WithDeps(Intern::new(EntryWithDeps::Root(RootEntry(q.clone())))),
Node::Param(p) => Entry::Param(*p),
Node::Reentry(q, params) => Entry::WithDeps(Intern::new(EntryWithDeps::Reentry(Reentry { params: params.clone(), query: q.clone() }))),
Node::Reentry(q, params) => Entry::WithDeps(Intern::new(EntryWithDeps::Reentry(Reentry {
params: params.clone(),
query: q.clone(),
}))),
}
};

Expand Down Expand Up @@ -1425,12 +1446,17 @@ impl<R: Rule> Builder<R> {
// Then generate the combinations of possibly valid deps.
for combination in combinations_of_one(&filtered_deps) {
// Union the pre-filtered per-dependency in_sets.
let in_set = combination
.iter()
.fold(ParamTypes::new(), |mut in_set, (_, _, dep_in_set)| {
in_set.extend(dep_in_set.iter().cloned());
in_set
});
let in_set = {
let mut in_set =
combination
.iter()
.fold(ParamTypes::new(), |mut in_set, (_, _, dep_in_set)| {
in_set.extend(dep_in_set.iter().cloned());
in_set
});
graph[node_id].0.node.add_inherent_in_set(&mut in_set);
in_set
};

// Confirm that this combination of deps is satisfiable in terms of the in_set.
let in_set_satisfiable = combination
Expand Down

0 comments on commit f1be0bd

Please sign in to comment.