Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pkg/apk/apk/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,9 @@ type cache struct {
dir string
offline bool

shared *Cache
shared *Cache
resolverCache *resolverCache
disqualifyCache *disqualifyCache
}

// client return an http.Client that knows how to read from and write to the cache
Expand Down
15 changes: 13 additions & 2 deletions pkg/apk/apk/implementation.go
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,12 @@ func (a *APK) ResolveWorld(ctx context.Context) (toInstall []*RepositoryPackage,
if err != nil {
return toInstall, conflicts, fmt.Errorf("error getting world packages: %w", err)
}
resolver := NewPkgResolver(ctx, indexes)

resolverCache := globalResolverCache
if a.cache != nil {
resolverCache = a.cache.resolverCache
}
resolver := resolverCache.get(ctx, indexes)

// For other architectures we're building (if any), we want to disqualify any packages not present in all archs.
allArchs := map[string][]NamedIndex{}
Expand All @@ -622,7 +627,13 @@ func (a *APK) ResolveWorld(ctx context.Context) (toInstall []*RepositoryPackage,
allArchs[otherArch] = indexes
}

toInstall, conflicts, err = resolver.GetPackagesWithDependencies(ctx, directPkgs, allArchs)
dqCache := globalDisqualifyCache
if a.cache != nil {
dqCache = a.cache.disqualifyCache
}
dq := dqCache.get(ctx, allArchs, resolverCache)

toInstall, conflicts, err = resolver.GetPackagesWithDependencies(ctx, directPkgs, dq)
if err != nil {
return
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/apk/apk/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,11 @@ func WithCache(cacheDir string, offline bool, shared *Cache) Option {
}
}
o.cache = &cache{
dir: cacheDir,
offline: offline,
shared: shared,
dir: cacheDir,
offline: offline,
shared: shared,
resolverCache: &resolverCache{},
disqualifyCache: &disqualifyCache{},
}
return nil
}
Expand Down
17 changes: 8 additions & 9 deletions pkg/apk/apk/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,6 @@ func (p *PkgResolver) Clone() *PkgResolver {
// NewPkgResolver creates a new pkgResolver from a list of indexes.
// The indexes are anything that implements NamedIndex.
func NewPkgResolver(ctx context.Context, indexes []NamedIndex) *PkgResolver {
return globalResolverCache.Get(ctx, indexes)
}

func newPkgResolver(ctx context.Context, indexes []NamedIndex) *PkgResolver {
_, span := otel.Tracer("go-apk").Start(ctx, "NewPkgResolver")
defer span.End()

Expand Down Expand Up @@ -485,12 +481,15 @@ func (p *PkgResolver) constrain(constraints []string, dq map[*RepositoryPackage]

// GetPackagesWithDependencies get all of the dependencies for the given packages based on the
// indexes. Does not filter for installed already or not.
func (p *PkgResolver) GetPackagesWithDependencies(ctx context.Context, packages []string, allArchs map[string][]NamedIndex) (toInstall []*RepositoryPackage, conflicts []string, err error) {
func (p *PkgResolver) GetPackagesWithDependencies(ctx context.Context, packages []string, dq map[*RepositoryPackage]string) (toInstall []*RepositoryPackage, conflicts []string, err error) {
_, span := otel.Tracer("go-apk").Start(ctx, "GetPackagesWithDependencies")
defer span.End()

// Tracks all the packages we have disqualified and the reason we disqualified them.
dq := globalDisqualifyCache.Get(ctx, allArchs)
if dq == nil {
// Make sure we have a map to avoid panics. The code below mutates this map, so we need
// it to not be nil in all cases.
dq = map[*RepositoryPackage]string{}
}

// We're going to mutate this as our set of input packages to install, so make a copy.
constraints := slices.Clone(packages)
Expand Down Expand Up @@ -1136,7 +1135,7 @@ func maybedqerror(pkgs []*repositoryPackage, dq map[*RepositoryPackage]string) e
return errors.New("not in indexes")
}

func disqualifyDifference(ctx context.Context, byArch map[string][]NamedIndex) map[*RepositoryPackage]string {
func disqualifyDifference(ctx context.Context, byArch map[string][]NamedIndex, resolverCache *resolverCache) map[*RepositoryPackage]string {
dq := map[*RepositoryPackage]string{}

if len(byArch) == 1 {
Expand Down Expand Up @@ -1164,7 +1163,7 @@ func disqualifyDifference(ctx context.Context, byArch map[string][]NamedIndex) m
}

for arch := range allowablePackages {
p := globalResolverCache.Get(ctx, byArch[arch])
p := resolverCache.get(ctx, byArch[arch])
for otherArch, allowed := range allowablePackages {
if otherArch == arch {
continue
Expand Down
3 changes: 2 additions & 1 deletion pkg/apk/apk/repo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1026,8 +1026,9 @@ func TestDisqualifyingOtherArchitectures(t *testing.T) {
"x86_64": testNamedRepositoryFromIndexes(index),
"aarch64": armIndex,
}
dq := disqualifyDifference(context.Background(), byArch, globalResolverCache)

resolver := NewPkgResolver(context.Background(), armIndex)
_, _, err := resolver.GetPackagesWithDependencies(context.Background(), names, byArch)
_, _, err := resolver.GetPackagesWithDependencies(context.Background(), names, dq)
require.ErrorContains(t, err, "package \"onlyinarm64-1.0.0.apk\" not available for arch \"x86_64\"")
}
8 changes: 4 additions & 4 deletions pkg/apk/apk/shameful_global_caches.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ func (r *resolverCache) fill(indexes []NamedIndex, pr *PkgResolver) {
child.fill(indexes[1:], pr)
}

func (r *resolverCache) Get(ctx context.Context, indexes []NamedIndex) *PkgResolver {
func (r *resolverCache) get(ctx context.Context, indexes []NamedIndex) *PkgResolver {
r.Lock()
defer r.Unlock()

if pr := r.find(indexes); pr != nil {
return pr.Clone()
}

pr := newPkgResolver(ctx, indexes)
pr := NewPkgResolver(ctx, indexes)
r.fill(indexes, pr)

return pr.Clone()
Expand Down Expand Up @@ -130,7 +130,7 @@ func (r *disqualifyCache) fill(indexes []NamedIndex, dq map[*RepositoryPackage]s

// It is expensive to compute the difference between every architecture.
// This caches that difference based on the input []NamedIndex for every architecture.
func (r *disqualifyCache) Get(ctx context.Context, byArch map[string][]NamedIndex) map[*RepositoryPackage]string {
func (r *disqualifyCache) get(ctx context.Context, byArch map[string][]NamedIndex, resolverCache *resolverCache) map[*RepositoryPackage]string {
r.Lock()
defer r.Unlock()

Expand All @@ -142,7 +142,7 @@ func (r *disqualifyCache) Get(ctx context.Context, byArch map[string][]NamedInde
return maps.Clone(dq)
}

dq := disqualifyDifference(ctx, byArch)
dq := disqualifyDifference(ctx, byArch, resolverCache)
r.fill(indexes, dq)

return maps.Clone(dq)
Expand Down
Loading