github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/internal/relationship/binary/relationship_index.go (about) 1 package binary 2 3 import ( 4 "github.com/scylladb/go-set/strset" 5 6 "github.com/anchore/syft/syft/artifact" 7 ) 8 9 type relationshipIndex struct { 10 typesByFromTo map[artifact.ID]map[artifact.ID]*strset.Set 11 additional []artifact.Relationship 12 } 13 14 func newRelationshipIndex(existing ...artifact.Relationship) *relationshipIndex { 15 r := &relationshipIndex{ 16 typesByFromTo: make(map[artifact.ID]map[artifact.ID]*strset.Set), 17 additional: make([]artifact.Relationship, 0), 18 } 19 for _, rel := range existing { 20 r.track(rel) 21 } 22 return r 23 } 24 25 // track this relationship as "exists" in the index (this is used to prevent duplicate relationships from being added). 26 // returns true if the relationship is new to the index, false otherwise. 27 func (i *relationshipIndex) track(r artifact.Relationship) bool { 28 fromID := r.From.ID() 29 if _, ok := i.typesByFromTo[fromID]; !ok { 30 i.typesByFromTo[fromID] = make(map[artifact.ID]*strset.Set) 31 } 32 33 toID := r.To.ID() 34 if _, ok := i.typesByFromTo[fromID][toID]; !ok { 35 i.typesByFromTo[fromID][toID] = strset.New() 36 } 37 38 var exists bool 39 if i.typesByFromTo[fromID][toID].Has(string(r.Type)) { 40 exists = true 41 } 42 43 i.typesByFromTo[fromID][toID].Add(string(r.Type)) 44 return !exists 45 } 46 47 // add a new relationship to the index, returning true if the relationship is new to the index, false otherwise (thus is a duplicate). 48 // nolint:unparam 49 func (i *relationshipIndex) add(r artifact.Relationship) bool { 50 if i.track(r) { 51 i.additional = append(i.additional, r) 52 return true 53 } 54 return false 55 } 56 57 func (i *relationshipIndex) newRelationships() []artifact.Relationship { 58 return i.additional 59 }