1// Copyright 2021 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package compliance 16 17// ShippedNodes returns the set of nodes in a license graph where the target or 18// a derivative work gets distributed. (caches result) 19func ShippedNodes(lg *LicenseGraph) TargetNodeSet { 20 lg.mu.Lock() 21 shipped := lg.shippedNodes 22 lg.mu.Unlock() 23 if shipped != nil { 24 return *shipped 25 } 26 27 tset := make(TargetNodeSet) 28 29 WalkTopDown(NoEdgeContext{}, lg, func(lg *LicenseGraph, tn *TargetNode, path TargetEdgePath) bool { 30 if _, alreadyWalked := tset[tn]; alreadyWalked { 31 return false 32 } 33 if len(path) > 0 { 34 if !edgeIsDerivation(path[len(path)-1].edge) { 35 return false 36 } 37 } 38 tset[tn] = struct{}{} 39 return true 40 }) 41 42 shipped = &tset 43 44 lg.mu.Lock() 45 if lg.shippedNodes == nil { 46 lg.shippedNodes = shipped 47 } else { 48 // if we end up with 2, release the later for garbage collection. 49 shipped = lg.shippedNodes 50 } 51 lg.mu.Unlock() 52 53 return *shipped 54} 55