github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/file/location_set.go (about) 1 package file 2 3 import ( 4 "sort" 5 6 "github.com/mitchellh/hashstructure/v2" 7 8 "github.com/anchore/syft/internal/log" 9 ) 10 11 type LocationSet struct { 12 set map[LocationData]LocationMetadata 13 } 14 15 func NewLocationSet(locations ...Location) (s LocationSet) { 16 for _, l := range locations { 17 s.Add(l) 18 } 19 20 return s 21 } 22 23 func (s *LocationSet) Add(locations ...Location) { 24 if s.set == nil { 25 s.set = make(map[LocationData]LocationMetadata) 26 } 27 for _, l := range locations { 28 if m, ok := s.set[l.LocationData]; ok { 29 err := m.merge(l.LocationMetadata) 30 if err != nil { 31 log.Debugf("partial merge of location metadata: %+v", err) 32 } 33 s.set[l.LocationData] = m 34 } else { 35 s.set[l.LocationData] = l.LocationMetadata 36 } 37 } 38 } 39 40 func (s LocationSet) Remove(locations ...Location) { 41 if s.set == nil { 42 return 43 } 44 for _, l := range locations { 45 delete(s.set, l.LocationData) 46 } 47 } 48 49 func (s LocationSet) Contains(l Location) bool { 50 if s.set == nil { 51 return false 52 } 53 _, ok := s.set[l.LocationData] 54 return ok 55 } 56 57 func (s LocationSet) ToSlice() []Location { 58 if s.set == nil { 59 return nil 60 } 61 locations := make([]Location, len(s.set)) 62 idx := 0 63 for dir := range s.set { 64 locations[idx] = Location{ 65 LocationData: dir, 66 LocationMetadata: s.set[dir], 67 } 68 idx++ 69 } 70 sort.Sort(Locations(locations)) 71 return locations 72 } 73 74 func (s *LocationSet) CoordinateSet() CoordinateSet { 75 if s.set == nil { 76 return NewCoordinateSet() 77 } 78 set := NewCoordinateSet() 79 for l := range s.set { 80 set.Add(l.Coordinates) 81 } 82 return set 83 } 84 85 func (s *LocationSet) Empty() bool { 86 if s.set == nil { 87 return true 88 } 89 return len(s.set) == 0 90 } 91 92 func (s LocationSet) Hash() (uint64, error) { 93 // access paths and filesystem IDs are not considered when hashing a location set, only the real paths 94 return hashstructure.Hash(s.CoordinateSet().Paths(), hashstructure.FormatV2, &hashstructure.HashOptions{ 95 ZeroNil: true, 96 SlicesAsSets: true, 97 }) 98 }