Performance improvements around package ID (#698)

* set package ID in catalogers and improve hashing performance

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>

* update setting ID + tests

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman
2021-12-16 08:55:53 -05:00
committed by GitHub
parent 727b84ce0d
commit a27907659d
59 changed files with 319 additions and 243 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ func NewCoordinateSet(start ...Coordinates) CoordinateSet {
}
func (c Coordinates) ID() artifact.ID {
f, err := artifact.IDFromHash(c)
f, err := artifact.IDByHash(c)
if err != nil {
// TODO: what to do in this case?
log.Warnf("unable to get fingerprint of location coordinate=%+v: %+v", c, err)
+4 -12
View File
@@ -3,21 +3,19 @@ package source
import (
"fmt"
"github.com/mitchellh/hashstructure/v2"
"github.com/anchore/stereoscope/pkg/file"
"github.com/anchore/stereoscope/pkg/image"
"github.com/anchore/syft/internal/log"
)
var _ hashstructure.Hashable = (*Location)(nil)
// Location represents a path relative to a particular filesystem resolved to a specific file.Reference. This struct is used as a key
// in content fetching to uniquely identify a file relative to a request (the VirtualPath).
type Location struct {
Coordinates
VirtualPath string // The path to the file which may or may not have hardlinks / symlinks
ref file.Reference // The file reference relative to the stereoscope.FileCatalog that has more information about this location.
// note: it is IMPORTANT to ignore anything but the coordinates for a Location when considering the ID (hash value)
// since the coordinates are the minimally correct ID for a location (symlinks should not come into play)
VirtualPath string `hash:"ignore"` // The path to the file which may or may not have hardlinks / symlinks
ref file.Reference `hash:"ignore"` // The file reference relative to the stereoscope.FileCatalog that has more information about this location.
}
// NewLocation creates a new Location representing a path without denoting a filesystem or FileCatalog reference.
@@ -97,9 +95,3 @@ func (l Location) String() string {
}
return fmt.Sprintf("Location<%s>", str)
}
func (l Location) Hash() (uint64, error) {
// since location is part of the package definition it is important that only coordinates are used during object
// hashing. (Location hash should be a pass-through for the coordinates and not include ref or VirtualPath.)
return hashstructure.Hash(l.ID(), hashstructure.FormatV2, nil)
}
+47
View File
@@ -0,0 +1,47 @@
package source
import (
"testing"
"github.com/anchore/stereoscope/pkg/file"
"github.com/stretchr/testify/assert"
)
func TestLocation_ID(t *testing.T) {
tests := []struct {
name string
coordinates Coordinates
virtualPath string
ref file.Reference
}{
{
name: "coordinates should match location hash",
coordinates: Coordinates{
RealPath: "path!",
FileSystemID: "filesystem!",
},
},
{
name: "coordinates should match location hash (with extra fields)",
coordinates: Coordinates{
RealPath: "path!",
FileSystemID: "filesystem!",
},
virtualPath: "virtualPath!",
ref: file.Reference{
RealPath: "other-real-path!",
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
l := Location{
Coordinates: test.coordinates,
VirtualPath: test.virtualPath,
ref: test.ref,
}
assert.Equal(t, l.ID(), test.coordinates.ID())
})
}
}