1
0
mirror of https://github.com/containers/image.git synced 2025-04-17 08:37:06 +03:00

Replace Set.Values with a non-allocating Set.All

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač 2024-08-23 00:59:30 +02:00
parent 4c5a86a9eb
commit bc6b35d0c9
6 changed files with 36 additions and 16 deletions

View File

@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"io"
"iter"
"maps"
"reflect"
"slices"
@ -417,7 +418,7 @@ func (ic *imageCopier) compareImageDestinationManifestEqual(ctx context.Context,
}
}
algos, err := algorithmsByNames(compressionAlgos.Values())
algos, err := algorithmsByNames(compressionAlgos.All())
if err != nil {
return nil, err
}
@ -552,7 +553,7 @@ func (ic *imageCopier) copyLayers(ctx context.Context) ([]compressiontypes.Algor
if srcInfosUpdated || layerDigestsDiffer(srcInfos, destInfos) {
ic.manifestUpdates.LayerInfos = destInfos
}
algos, err := algorithmsByNames(compressionAlgos.Values())
algos, err := algorithmsByNames(compressionAlgos.All())
if err != nil {
return nil, err
}
@ -988,10 +989,10 @@ func computeDiffID(stream io.Reader, decompressor compressiontypes.DecompressorF
return digest.Canonical.FromReader(stream)
}
// algorithmsByNames returns slice of Algorithms from slice of Algorithm Names
func algorithmsByNames(names []string) ([]compressiontypes.Algorithm, error) {
// algorithmsByNames returns slice of Algorithms from a sequence of Algorithm Names
func algorithmsByNames(names iter.Seq[string]) ([]compressiontypes.Algorithm, error) {
result := []compressiontypes.Algorithm{}
for _, name := range names {
for name := range names {
algo, err := compression.AlgorithmByName(name)
if err != nil {
return nil, err

View File

@ -1,6 +1,10 @@
package set
import "golang.org/x/exp/maps"
import (
"iter"
"golang.org/x/exp/maps"
)
// FIXME:
// - Docstrings
@ -47,6 +51,12 @@ func (s *Set[E]) Empty() bool {
return len(s.m) == 0
}
func (s *Set[E]) Values() []E {
return maps.Keys(s.m)
func (s *Set[E]) All() iter.Seq[E] {
return func(yield func(E) bool) {
for _, v := range maps.Keys(s.m) {
if !yield(v) {
return
}
}
}
}

View File

@ -1,6 +1,7 @@
package set
import (
"slices"
"testing"
"github.com/stretchr/testify/assert"
@ -26,7 +27,7 @@ func TestAdd(t *testing.T) {
s.Add(2) // Adding an already-present element
assert.True(t, s.Contains(2))
// should not contain duplicate value of `2`
assert.ElementsMatch(t, []int{1, 2}, s.Values())
assert.ElementsMatch(t, []int{1, 2}, slices.Collect(s.All()))
// Unrelated elements are unaffected
assert.True(t, s.Contains(1))
assert.False(t, s.Contains(3))
@ -36,7 +37,7 @@ func TestAddSlice(t *testing.T) {
s := NewWithValues(1)
s.Add(2)
s.AddSlice([]int{3, 4})
assert.ElementsMatch(t, []int{1, 2, 3, 4}, s.Values())
assert.ElementsMatch(t, []int{1, 2, 3, 4}, slices.Collect(s.All()))
}
func TestDelete(t *testing.T) {
@ -66,12 +67,20 @@ func TestEmpty(t *testing.T) {
assert.True(t, s.Empty())
}
func TestValues(t *testing.T) {
func TestAll(t *testing.T) {
s := New[int]()
assert.Empty(t, s.Values())
assert.Empty(t, slices.Collect(s.All()))
s.Add(1)
s.Add(2)
// ignore duplicate
s.Add(2)
assert.ElementsMatch(t, []int{1, 2}, s.Values())
assert.ElementsMatch(t, []int{1, 2}, slices.Collect(s.All()))
// Break / return inside the range body (yield function returning false) works
var partial []int
for v := range s.All() {
partial = append(partial, v)
break
}
assert.Len(t, partial, 1)
assert.True(t, partial[0] == 1 || partial[0] == 2)
}

View File

@ -123,7 +123,7 @@ func (ref ociReference) getBlobsToDelete(blobsUsedByDescriptorToDelete map[diges
//
// So, NOTE: the blobPath() call below hard-codes "" even in calls where OCISharedBlobDirPath is set
func (ref ociReference) deleteBlobs(blobsToDelete *set.Set[digest.Digest]) error {
for _, digest := range blobsToDelete.Values() {
for digest := range blobsToDelete.All() {
blobPath, err := ref.blobPath(digest, "") //Only delete in the local directory, see comment above
if err != nil {
return err

View File

@ -240,7 +240,7 @@ func (mem *cache) candidateLocations(transport types.ImageTransport, scope types
if uncompressedDigest = mem.uncompressedDigestLocked(primaryDigest); uncompressedDigest != "" {
otherDigests := mem.digestsByUncompressed[uncompressedDigest] // nil if not present in the map
if otherDigests != nil {
for _, d := range otherDigests.Values() {
for d := range otherDigests.All() {
if d != primaryDigest && d != uncompressedDigest {
res = mem.appendReplacementCandidates(res, transport, scope, d, v2Options)
}

View File

@ -124,7 +124,7 @@ func GetAllCredentials(sys *types.SystemContext) (map[string]types.DockerAuthCon
// Now use `GetCredentials` to the specific auth configs for each
// previously listed registry.
allCreds := make(map[string]types.DockerAuthConfig)
for _, key := range allKeys.Values() {
for key := range allKeys.All() {
creds, err := GetCredentials(sys, key)
if err != nil {
// Note: we rely on the logging in `GetCredentials`.