aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-12-08 21:47:39 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2021-12-08 21:47:39 +0000
commitd497acc1c9a7e0bd568f50f78970b9329a7280dd (patch)
tree3113842b35072bf8be4af5719d57390525cee4ec
parente808bc4a09bf24367a6c700842ba21418b40fe52 (diff)
parent3a820dd5a0aa6612fc0dbacfee662b17cce22dd5 (diff)
downloadbuild-d497acc1c9a7e0bd568f50f78970b9329a7280dd.tar.gz
Merge "license metadata performance"
-rw-r--r--tools/compliance/actionset.go9
-rw-r--r--tools/compliance/policy/resolve.go57
2 files changed, 52 insertions, 14 deletions
diff --git a/tools/compliance/actionset.go b/tools/compliance/actionset.go
index d575321928..656c5deea8 100644
--- a/tools/compliance/actionset.go
+++ b/tools/compliance/actionset.go
@@ -108,3 +108,12 @@ func (as actionSet) isEmpty() bool {
}
return true
}
+
+// conditions returns the set of conditions resolved by the action set.
+func (as actionSet) conditions() *LicenseConditionSet {
+ result := newLicenseConditionSet()
+ for _, cs := range as {
+ result.AddSet(cs)
+ }
+ return result
+}
diff --git a/tools/compliance/policy/resolve.go b/tools/compliance/policy/resolve.go
index 9962e68492..c051ed8bb2 100644
--- a/tools/compliance/policy/resolve.go
+++ b/tools/compliance/policy/resolve.go
@@ -133,16 +133,15 @@ func ResolveTopDownConditions(lg *LicenseGraph) *ResolutionSet {
//
// rmap is the resulting ResolutionSet
rmap := make(map[*TargetNode]actionSet)
- for attachesTo, as := range rs.resolutions {
- rmap[attachesTo] = as.copy()
- }
+
+ // cmap contains the set of targets walked as pure aggregates. i.e. containers
+ cmap := make(map[*TargetNode]bool)
path := make([]*dependencyEdge, 0, 32)
- var walk func(f string, cs *LicenseConditionSet, treatAsAggregate bool)
+ var walk func(fnode *TargetNode, cs *LicenseConditionSet, treatAsAggregate bool)
- walk = func(f string, cs *LicenseConditionSet, treatAsAggregate bool) {
- fnode := lg.targets[f]
+ walk = func(fnode *TargetNode, cs *LicenseConditionSet, treatAsAggregate bool) {
if !cs.IsEmpty() {
parentsAllAggregate := true
for _, e := range path {
@@ -163,31 +162,52 @@ func ResolveTopDownConditions(lg *LicenseGraph) *ResolutionSet {
rmap[fnode].add(fnode, cs)
}
}
- // add conditions attached to `f`
+ if treatAsAggregate {
+ cmap[fnode] = true
+ }
+ // add conditions attached to `fnode`
cs = cs.Copy()
for _, fcs := range rs.resolutions[fnode] {
cs.AddSet(fcs)
}
// for each dependency
- for _, edge := range lg.index[f] {
+ for _, edge := range lg.index[fnode.name] {
e := TargetEdge{lg, edge}
// dcs holds the dpendency conditions inherited from the target
dcs := targetConditionsApplicableToDep(e, cs, treatAsAggregate)
- if dcs.IsEmpty() {
- if !treatAsAggregate || (!edgeIsDerivation(e) && !edgeIsDynamicLink(e)) {
- continue
+ if dcs.IsEmpty() && !treatAsAggregate {
+ continue
+ }
+ dnode := lg.targets[edge.dependency]
+ if as, alreadyWalked := rmap[dnode]; alreadyWalked {
+ diff := dcs.Copy()
+ diff.RemoveSet(as.conditions())
+ if diff.IsEmpty() {
+ // no new conditions
+
+ // pure aggregates never need walking a 2nd time with same conditions
+ if treatAsAggregate {
+ continue
+ }
+ // non-aggregates don't need walking as non-aggregate a 2nd time
+ if _, asAggregate := cmap[dnode]; !asAggregate {
+ continue
+ }
+ // previously walked as pure aggregate; need to re-walk as non-aggregate
+ delete(cmap, dnode)
}
}
path = append(path, edge)
// add the conditions to the dependency
- walk(edge.dependency, dcs, treatAsAggregate && lg.targets[edge.dependency].IsContainer())
+ walk(dnode, dcs, treatAsAggregate && lg.targets[edge.dependency].IsContainer())
path = path[:len(path)-1]
}
}
// walk each of the roots
for _, r := range lg.rootFiles {
- as, ok := rs.resolutions[lg.targets[r]]
+ rnode := lg.targets[r]
+ as, ok := rs.resolutions[rnode]
if !ok {
// no conditions in root or transitive closure of dependencies
continue
@@ -198,7 +218,16 @@ func ResolveTopDownConditions(lg *LicenseGraph) *ResolutionSet {
path = path[:0]
// add the conditions to the root and its transitive closure
- walk(r, newLicenseConditionSet(), lg.targets[r].IsContainer())
+ walk(rnode, newLicenseConditionSet(), lg.targets[r].IsContainer())
+ }
+
+ // back-fill any bottom-up conditions on targets missed by top-down walk
+ for attachesTo, as := range rs.resolutions {
+ if _, ok := rmap[attachesTo]; !ok {
+ rmap[attachesTo] = as.copy()
+ } else {
+ rmap[attachesTo].addSet(as)
+ }
}
rs = &ResolutionSet{rmap}