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  }