| skipped 9 lines |
10 | 10 | | "github.com/anchore/syft/syft/artifact" |
11 | 11 | | ) |
12 | 12 | | |
13 | | - | type orderedIDSet struct { |
14 | | - | slice []artifact.ID |
15 | | - | } |
16 | | - | |
17 | | - | func (s *orderedIDSet) add(ids ...artifact.ID) { |
18 | | - | loopNewIDs: |
19 | | - | for _, newID := range ids { |
20 | | - | for _, existingID := range s.slice { |
21 | | - | if existingID == newID { |
22 | | - | continue loopNewIDs |
23 | | - | } |
24 | | - | } |
25 | | - | s.slice = append(s.slice, newID) |
26 | | - | } |
27 | | - | } |
28 | | - | |
29 | | - | func (s *orderedIDSet) delete(id artifact.ID) { |
30 | | - | for i, existingID := range s.slice { |
31 | | - | if existingID == id { |
32 | | - | s.slice = append(s.slice[:i], s.slice[i+1:]...) |
33 | | - | return |
34 | | - | } |
35 | | - | } |
36 | | - | } |
37 | | - | |
38 | | - | // Catalog represents a collection of Packages. |
39 | | - | type Catalog struct { |
| 13 | + | // Collection represents a collection of Packages. |
| 14 | + | type Collection struct { |
40 | 15 | | byID map[artifact.ID]Package |
41 | 16 | | idsByName map[string]orderedIDSet |
42 | 17 | | idsByType map[Type]orderedIDSet |
| skipped 1 lines |
44 | 19 | | lock sync.RWMutex |
45 | 20 | | } |
46 | 21 | | |
47 | | - | // NewCatalog returns a new empty Catalog |
48 | | - | func NewCatalog(pkgs ...Package) *Catalog { |
49 | | - | catalog := Catalog{ |
| 22 | + | // NewCollection returns a new empty Collection |
| 23 | + | func NewCollection(pkgs ...Package) *Collection { |
| 24 | + | catalog := Collection{ |
50 | 25 | | byID: make(map[artifact.ID]Package), |
51 | 26 | | idsByName: make(map[string]orderedIDSet), |
52 | 27 | | idsByType: make(map[Type]orderedIDSet), |
| skipped 8 lines |
61 | 36 | | } |
62 | 37 | | |
63 | 38 | | // PackageCount returns the total number of packages that have been added. |
64 | | - | func (c *Catalog) PackageCount() int { |
| 39 | + | func (c *Collection) PackageCount() int { |
65 | 40 | | return len(c.byID) |
66 | 41 | | } |
67 | 42 | | |
68 | 43 | | // Package returns the package with the given ID. |
69 | | - | func (c *Catalog) Package(id artifact.ID) *Package { |
| 44 | + | func (c *Collection) Package(id artifact.ID) *Package { |
70 | 45 | | v, exists := c.byID[id] |
71 | 46 | | if !exists { |
72 | 47 | | return nil |
| skipped 8 lines |
81 | 56 | | } |
82 | 57 | | |
83 | 58 | | // PackagesByPath returns all packages that were discovered from the given path. |
84 | | - | func (c *Catalog) PackagesByPath(path string) []Package { |
| 59 | + | func (c *Collection) PackagesByPath(path string) []Package { |
85 | 60 | | return c.Packages(c.idsByPath[path].slice) |
86 | 61 | | } |
87 | 62 | | |
88 | 63 | | // PackagesByName returns all packages that were discovered with a matching name. |
89 | | - | func (c *Catalog) PackagesByName(name string) []Package { |
| 64 | + | func (c *Collection) PackagesByName(name string) []Package { |
90 | 65 | | return c.Packages(c.idsByName[name].slice) |
91 | 66 | | } |
92 | 67 | | |
93 | 68 | | // Packages returns all packages for the given ID. |
94 | | - | func (c *Catalog) Packages(ids []artifact.ID) (result []Package) { |
| 69 | + | func (c *Collection) Packages(ids []artifact.ID) (result []Package) { |
95 | 70 | | for _, i := range ids { |
96 | 71 | | p, exists := c.byID[i] |
97 | 72 | | if exists { |
| skipped 4 lines |
102 | 77 | | } |
103 | 78 | | |
104 | 79 | | // Add n packages to the catalog. |
105 | | - | func (c *Catalog) Add(pkgs ...Package) { |
| 80 | + | func (c *Collection) Add(pkgs ...Package) { |
106 | 81 | | c.lock.Lock() |
107 | 82 | | defer c.lock.Unlock() |
108 | 83 | | |
| skipped 20 lines |
129 | 104 | | } |
130 | 105 | | } |
131 | 106 | | |
132 | | - | func (c *Catalog) addToIndex(p Package) { |
| 107 | + | func (c *Collection) addToIndex(p Package) { |
133 | 108 | | c.byID[p.id] = p |
134 | 109 | | c.addNameToIndex(p) |
135 | 110 | | c.addTypeToIndex(p) |
136 | 111 | | c.addPathsToIndex(p) |
137 | 112 | | } |
138 | 113 | | |
139 | | - | func (c *Catalog) addNameToIndex(p Package) { |
| 114 | + | func (c *Collection) addNameToIndex(p Package) { |
140 | 115 | | nameIndex := c.idsByName[p.Name] |
141 | 116 | | nameIndex.add(p.id) |
142 | 117 | | c.idsByName[p.Name] = nameIndex |
143 | 118 | | } |
144 | 119 | | |
145 | | - | func (c *Catalog) addTypeToIndex(p Package) { |
| 120 | + | func (c *Collection) addTypeToIndex(p Package) { |
146 | 121 | | typeIndex := c.idsByType[p.Type] |
147 | 122 | | typeIndex.add(p.id) |
148 | 123 | | c.idsByType[p.Type] = typeIndex |
149 | 124 | | } |
150 | 125 | | |
151 | | - | func (c *Catalog) addPathsToIndex(p Package) { |
| 126 | + | func (c *Collection) addPathsToIndex(p Package) { |
152 | 127 | | observedPaths := internal.NewStringSet() |
153 | 128 | | for _, l := range p.Locations.ToSlice() { |
154 | 129 | | if l.RealPath != "" && !observedPaths.Contains(l.RealPath) { |
| skipped 7 lines |
162 | 137 | | } |
163 | 138 | | } |
164 | 139 | | |
165 | | - | func (c *Catalog) addPathToIndex(id artifact.ID, path string) { |
| 140 | + | func (c *Collection) addPathToIndex(id artifact.ID, path string) { |
166 | 141 | | pathIndex := c.idsByPath[path] |
167 | 142 | | pathIndex.add(id) |
168 | 143 | | c.idsByPath[path] = pathIndex |
169 | 144 | | } |
170 | 145 | | |
171 | | - | func (c *Catalog) Delete(ids ...artifact.ID) { |
| 146 | + | func (c *Collection) Delete(ids ...artifact.ID) { |
172 | 147 | | c.lock.Lock() |
173 | 148 | | defer c.lock.Unlock() |
174 | 149 | | |
| skipped 10 lines |
185 | 160 | | } |
186 | 161 | | } |
187 | 162 | | |
188 | | - | func (c *Catalog) deleteNameFromIndex(p Package) { |
| 163 | + | func (c *Collection) deleteNameFromIndex(p Package) { |
189 | 164 | | nameIndex := c.idsByName[p.Name] |
190 | 165 | | nameIndex.delete(p.id) |
191 | 166 | | c.idsByName[p.Name] = nameIndex |
192 | 167 | | } |
193 | 168 | | |
194 | | - | func (c *Catalog) deleteTypeFromIndex(p Package) { |
| 169 | + | func (c *Collection) deleteTypeFromIndex(p Package) { |
195 | 170 | | typeIndex := c.idsByType[p.Type] |
196 | 171 | | typeIndex.delete(p.id) |
197 | 172 | | c.idsByType[p.Type] = typeIndex |
198 | 173 | | } |
199 | 174 | | |
200 | | - | func (c *Catalog) deletePathsFromIndex(p Package) { |
| 175 | + | func (c *Collection) deletePathsFromIndex(p Package) { |
201 | 176 | | observedPaths := internal.NewStringSet() |
202 | 177 | | for _, l := range p.Locations.ToSlice() { |
203 | 178 | | if l.RealPath != "" && !observedPaths.Contains(l.RealPath) { |
| skipped 7 lines |
211 | 186 | | } |
212 | 187 | | } |
213 | 188 | | |
214 | | - | func (c *Catalog) deletePathFromIndex(id artifact.ID, path string) { |
| 189 | + | func (c *Collection) deletePathFromIndex(id artifact.ID, path string) { |
215 | 190 | | pathIndex := c.idsByPath[path] |
216 | 191 | | pathIndex.delete(id) |
217 | 192 | | if len(pathIndex.slice) == 0 { |
| skipped 4 lines |
222 | 197 | | } |
223 | 198 | | |
224 | 199 | | // Enumerate all packages for the given type(s), enumerating all packages if no type is specified. |
225 | | - | func (c *Catalog) Enumerate(types ...Type) <-chan Package { |
| 200 | + | func (c *Collection) Enumerate(types ...Type) <-chan Package { |
226 | 201 | | channel := make(chan Package) |
227 | 202 | | go func() { |
228 | 203 | | defer close(channel) |
| skipped 28 lines |
257 | 232 | | |
258 | 233 | | // Sorted enumerates all packages for the given types sorted by package name. Enumerates all packages if no type |
259 | 234 | | // is specified. |
260 | | - | func (c *Catalog) Sorted(types ...Type) (pkgs []Package) { |
| 235 | + | func (c *Collection) Sorted(types ...Type) (pkgs []Package) { |
261 | 236 | | for p := range c.Enumerate(types...) { |
262 | 237 | | pkgs = append(pkgs, p) |
263 | 238 | | } |
| skipped 3 lines |
267 | 242 | | return pkgs |
268 | 243 | | } |
269 | 244 | | |
| 245 | + | type orderedIDSet struct { |
| 246 | + | slice []artifact.ID |
| 247 | + | } |
| 248 | + | |
| 249 | + | func (s *orderedIDSet) add(ids ...artifact.ID) { |
| 250 | + | loopNewIDs: |
| 251 | + | for _, newID := range ids { |
| 252 | + | for _, existingID := range s.slice { |
| 253 | + | if existingID == newID { |
| 254 | + | continue loopNewIDs |
| 255 | + | } |
| 256 | + | } |
| 257 | + | s.slice = append(s.slice, newID) |
| 258 | + | } |
| 259 | + | } |
| 260 | + | |
| 261 | + | func (s *orderedIDSet) delete(id artifact.ID) { |
| 262 | + | for i, existingID := range s.slice { |
| 263 | + | if existingID == id { |
| 264 | + | s.slice = append(s.slice[:i], s.slice[i+1:]...) |
| 265 | + | return |
| 266 | + | } |
| 267 | + | } |
| 268 | + | } |
| 269 | + | |