From 3fe369c271888fef9b2d21a145b241aa36314bfd Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Sun, 18 Dec 2022 14:15:02 -0800 Subject: [PATCH] An ActionSet doesn't need to walk the graph. Resolutions map back to the root, but actions do not. An iteration works just fine. Simplify TargetNodeSet so that it is directly iterable. Bug: 261787132 Test: m droid dist compliance_dumpgraph compliance_dumpresolutions \ compliance_sbom compliance_listshare compliance_rtrace \ compliance_checkshare xmlnotice textnotice htmlnotice \ compliancenotice_shippedlibs compliancenotice_bom Test: m compliance_checkshare cts && \ out/host/linux-x86/bin/compliance_checkshare out/host/linux-x86/gen/META/lic_intermediates/out/host/linux-x86/cts/android-cts.zip.meta_lic Change-Id: Ic5a2d809b5a9a47b5d85f61e3a4a790dbe8f5fd2 --- tools/compliance/graph.go | 25 ++++++---------------- tools/compliance/noticeindex.go | 2 +- tools/compliance/policy_shipped.go | 10 ++++----- tools/compliance/policy_walk.go | 34 +++++------------------------- 4 files changed, 18 insertions(+), 53 deletions(-) diff --git a/tools/compliance/graph.go b/tools/compliance/graph.go index 80a2f47e58..fac1d05b69 100644 --- a/tools/compliance/graph.go +++ b/tools/compliance/graph.go @@ -459,36 +459,25 @@ func (ea TargetEdgeAnnotations) AsList() []string { } // TargetNodeSet describes a set of distinct nodes in a license graph. -type TargetNodeSet struct { - nodes map[*TargetNode]struct{} -} +type TargetNodeSet map[*TargetNode]struct{} // Contains returns true when `target` is an element of the set. -func (ts *TargetNodeSet) Contains(target *TargetNode) bool { - _, isPresent := ts.nodes[target] +func (ts TargetNodeSet) Contains(target *TargetNode) bool { + _, isPresent := ts[target] return isPresent } -// AsList returns the list of target nodes in the set. (unordered) -func (ts *TargetNodeSet) AsList() TargetNodeList { - result := make(TargetNodeList, 0, len(ts.nodes)) - for tn := range ts.nodes { - result = append(result, tn) - } - return result -} - // Names returns the array of target node namess in the set. (unordered) -func (ts *TargetNodeSet) Names() []string { - result := make([]string, 0, len(ts.nodes)) - for tn := range ts.nodes { +func (ts TargetNodeSet) Names() []string { + result := make([]string, 0, len(ts)) + for tn := range ts { result = append(result, tn.name) } return result } // String returns a human-readable string representation of the set. -func (ts *TargetNodeSet) String() string { +func (ts TargetNodeSet) String() string { return fmt.Sprintf("{%s}", strings.Join(ts.Names(), ", ")) } diff --git a/tools/compliance/noticeindex.go b/tools/compliance/noticeindex.go index dbfede6d94..c91a8dfa32 100644 --- a/tools/compliance/noticeindex.go +++ b/tools/compliance/noticeindex.go @@ -42,7 +42,7 @@ type NoticeIndex struct { // rs identifies the set of resolutions upon which the index is based. rs ResolutionSet // shipped identifies the set of target nodes shipped directly or as derivative works. - shipped *TargetNodeSet + shipped TargetNodeSet // rootFS locates the root of the file system from which to read the files. rootFS fs.FS // hash maps license text filenames to content hashes diff --git a/tools/compliance/policy_shipped.go b/tools/compliance/policy_shipped.go index 75c8399c23..b21a95ae75 100644 --- a/tools/compliance/policy_shipped.go +++ b/tools/compliance/policy_shipped.go @@ -16,15 +16,15 @@ package compliance // ShippedNodes returns the set of nodes in a license graph where the target or // a derivative work gets distributed. (caches result) -func ShippedNodes(lg *LicenseGraph) *TargetNodeSet { +func ShippedNodes(lg *LicenseGraph) TargetNodeSet { lg.mu.Lock() shipped := lg.shippedNodes lg.mu.Unlock() if shipped != nil { - return shipped + return *shipped } - tset := make(map[*TargetNode]struct{}) + tset := make(TargetNodeSet) WalkTopDown(NoEdgeContext{}, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool { if _, alreadyWalked := tset[tn]; alreadyWalked { @@ -39,7 +39,7 @@ func ShippedNodes(lg *LicenseGraph) *TargetNodeSet { return true }) - shipped = &TargetNodeSet{tset} + shipped = &tset lg.mu.Lock() if lg.shippedNodes == nil { @@ -50,5 +50,5 @@ func ShippedNodes(lg *LicenseGraph) *TargetNodeSet { } lg.mu.Unlock() - return shipped + return *shipped } diff --git a/tools/compliance/policy_walk.go b/tools/compliance/policy_walk.go index beb6d53391..e6b94ab653 100644 --- a/tools/compliance/policy_walk.go +++ b/tools/compliance/policy_walk.go @@ -247,40 +247,16 @@ func WalkResolutionsForCondition(lg *LicenseGraph, conditions LicenseConditionSe // WalkActionsForCondition performs a top-down walk of the LicenseGraph // resolving all distributed works for `conditions`. func WalkActionsForCondition(lg *LicenseGraph, conditions LicenseConditionSet) ActionSet { - shipped := ShippedNodes(lg) - - // cmap identifies previously walked target/condition pairs. - cmap := make(map[resolutionKey]struct{}) - // amap maps 'actsOn' targets to the applicable conditions // // amap is the resulting ActionSet amap := make(ActionSet) - WalkTopDown(ApplicableConditionsContext{conditions}, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool { - universe := conditions - if len(path) > 0 { - universe = path[len(path)-1].ctx.(LicenseConditionSet) + + for tn := range ShippedNodes(lg) { + if cs := conditions.Intersection(tn.resolution); !cs.IsEmpty() { + amap[tn] = cs } - if universe.IsEmpty() { - return false - } - key := resolutionKey{tn, universe} - if _, ok := cmap[key]; ok { - return false - } - if !shipped.Contains(tn) { - return false - } - cs := universe.Intersection(tn.resolution) - if !cs.IsEmpty() { - if _, ok := amap[tn]; ok { - amap[tn] = cs - } else { - amap[tn] = amap[tn].Union(cs) - } - } - return true - }) + } return amap }