github.com/kastenhq/syft@v0.0.0-20230821225854-0710af25cdbe/syft/file/coordinate_set.go (about)

     1  package file
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/mitchellh/hashstructure/v2"
     7  	"github.com/scylladb/go-set/strset"
     8  )
     9  
    10  type CoordinateSet struct {
    11  	set map[Coordinates]struct{}
    12  }
    13  
    14  func NewCoordinateSet(coordinates ...Coordinates) (s CoordinateSet) {
    15  	for _, l := range coordinates {
    16  		s.Add(l)
    17  	}
    18  
    19  	return s
    20  }
    21  
    22  func (s *CoordinateSet) Add(coordinates ...Coordinates) {
    23  	if s.set == nil {
    24  		s.set = make(map[Coordinates]struct{})
    25  	}
    26  	for _, l := range coordinates {
    27  		s.set[l] = struct{}{}
    28  	}
    29  }
    30  
    31  func (s CoordinateSet) Remove(coordinates ...Coordinates) {
    32  	if s.set == nil {
    33  		return
    34  	}
    35  	for _, l := range coordinates {
    36  		delete(s.set, l)
    37  	}
    38  }
    39  
    40  func (s CoordinateSet) Contains(l Coordinates) bool {
    41  	if s.set == nil {
    42  		return false
    43  	}
    44  	_, ok := s.set[l]
    45  	return ok
    46  }
    47  
    48  func (s CoordinateSet) Paths() []string {
    49  	if s.set == nil {
    50  		return nil
    51  	}
    52  
    53  	paths := strset.New()
    54  	for _, c := range s.ToSlice() {
    55  		paths.Add(c.RealPath)
    56  	}
    57  	pathSlice := paths.List()
    58  	sort.Strings(pathSlice)
    59  	return pathSlice
    60  }
    61  
    62  func (s CoordinateSet) ToSlice() []Coordinates {
    63  	if s.set == nil {
    64  		return nil
    65  	}
    66  	coordinates := make([]Coordinates, len(s.set))
    67  	idx := 0
    68  	for v := range s.set {
    69  		coordinates[idx] = v
    70  		idx++
    71  	}
    72  	sort.SliceStable(coordinates, func(i, j int) bool {
    73  		if coordinates[i].RealPath == coordinates[j].RealPath {
    74  			return coordinates[i].FileSystemID < coordinates[j].FileSystemID
    75  		}
    76  		return coordinates[i].RealPath < coordinates[j].RealPath
    77  	})
    78  	return coordinates
    79  }
    80  
    81  func (s CoordinateSet) Hash() (uint64, error) {
    82  	return hashstructure.Hash(s.ToSlice(), hashstructure.FormatV2, &hashstructure.HashOptions{
    83  		ZeroNil:      true,
    84  		SlicesAsSets: true,
    85  	})
    86  }