forked from TrueCloudLab/distribution
Merge pull request #3775 from thaJeztah/remove_digestset
This commit is contained in:
commit
9bb63e6e46
4 changed files with 67 additions and 372 deletions
51
digestset/deprecated.go
Normal file
51
digestset/deprecated.go
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
package digestset
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/opencontainers/go-digest"
|
||||||
|
"github.com/opencontainers/go-digest/digestset"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrDigestNotFound is used when a matching digest
|
||||||
|
// could not be found in a set.
|
||||||
|
//
|
||||||
|
// Deprecated: use [digestset.ErrDigestNotFound].
|
||||||
|
var ErrDigestNotFound = digestset.ErrDigestNotFound
|
||||||
|
|
||||||
|
// ErrDigestAmbiguous is used when multiple digests
|
||||||
|
// are found in a set. None of the matching digests
|
||||||
|
// should be considered valid matches.
|
||||||
|
//
|
||||||
|
// Deprecated: use [digestset.ErrDigestAmbiguous].
|
||||||
|
var ErrDigestAmbiguous = digestset.ErrDigestAmbiguous
|
||||||
|
|
||||||
|
// Set is used to hold a unique set of digests which
|
||||||
|
// may be easily referenced by a string
|
||||||
|
// representation of the digest as well as short representation.
|
||||||
|
// The uniqueness of the short representation is based on other
|
||||||
|
// digests in the set. If digests are omitted from this set,
|
||||||
|
// collisions in a larger set may not be detected, therefore it
|
||||||
|
// is important to always do short representation lookups on
|
||||||
|
// the complete set of digests. To mitigate collisions, an
|
||||||
|
// appropriately long short code should be used.
|
||||||
|
//
|
||||||
|
// Deprecated: use [digestset.Set].
|
||||||
|
type Set = digestset.Set
|
||||||
|
|
||||||
|
// NewSet creates an empty set of digests
|
||||||
|
// which may have digests added.
|
||||||
|
//
|
||||||
|
// Deprecated: use [digestset.NewSet].
|
||||||
|
func NewSet() *digestset.Set {
|
||||||
|
return digestset.NewSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShortCodeTable returns a map of Digest to unique short codes. The
|
||||||
|
// length represents the minimum value, the maximum length may be the
|
||||||
|
// entire value of digest if uniqueness cannot be achieved without the
|
||||||
|
// full value. This function will attempt to make short codes as short
|
||||||
|
// as possible to be unique.
|
||||||
|
//
|
||||||
|
// Deprecated: use [digestset.ShortCodeTable].
|
||||||
|
func ShortCodeTable(dst *digestset.Set, length int) map[digest.Digest]string {
|
||||||
|
return digestset.ShortCodeTable(dst, length)
|
||||||
|
}
|
|
@ -1,372 +0,0 @@
|
||||||
package digestset
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/sha256"
|
|
||||||
_ "crypto/sha512"
|
|
||||||
"encoding/binary"
|
|
||||||
"math/rand"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
digest "github.com/opencontainers/go-digest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func assertEqualDigests(t *testing.T, d1, d2 digest.Digest) {
|
|
||||||
if d1 != d2 {
|
|
||||||
t.Fatalf("Digests do not match:\n\tActual: %s\n\tExpected: %s", d1, d2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLookup(t *testing.T) {
|
|
||||||
digests := []digest.Digest{
|
|
||||||
"sha256:1234511111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:1234111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:1234611111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:5432111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:6543111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:6432111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:6542111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:6532111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
}
|
|
||||||
|
|
||||||
dset := NewSet()
|
|
||||||
for i := range digests {
|
|
||||||
if err := dset.Add(digests[i]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dgst, err := dset.Lookup("54")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
assertEqualDigests(t, dgst, digests[3])
|
|
||||||
|
|
||||||
_, err = dset.Lookup("1234")
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("Expected ambiguous error looking up: 1234")
|
|
||||||
}
|
|
||||||
if err != ErrDigestAmbiguous {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = dset.Lookup("9876")
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("Expected not found error looking up: 9876")
|
|
||||||
}
|
|
||||||
if err != ErrDigestNotFound {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = dset.Lookup("sha256:1234")
|
|
||||||
if err == nil {
|
|
||||||
t.Fatal("Expected ambiguous error looking up: sha256:1234")
|
|
||||||
}
|
|
||||||
if err != ErrDigestAmbiguous {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dgst, err = dset.Lookup("sha256:12345")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
assertEqualDigests(t, dgst, digests[0])
|
|
||||||
|
|
||||||
dgst, err = dset.Lookup("sha256:12346")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
assertEqualDigests(t, dgst, digests[2])
|
|
||||||
|
|
||||||
dgst, err = dset.Lookup("12346")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
assertEqualDigests(t, dgst, digests[2])
|
|
||||||
|
|
||||||
dgst, err = dset.Lookup("12345")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
assertEqualDigests(t, dgst, digests[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAddDuplication(t *testing.T) {
|
|
||||||
digests := []digest.Digest{
|
|
||||||
"sha256:1234111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:1234511111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:1234611111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:5432111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:6543111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha512:65431111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha512:65421111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha512:65321111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
}
|
|
||||||
|
|
||||||
dset := NewSet()
|
|
||||||
for i := range digests {
|
|
||||||
if err := dset.Add(digests[i]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(dset.entries) != 8 {
|
|
||||||
t.Fatal("Invalid dset size")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := dset.Add(digest.Digest("sha256:1234511111111111111111111111111111111111111111111111111111111111")); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(dset.entries) != 8 {
|
|
||||||
t.Fatal("Duplicate digest insert should not increase entries size")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := dset.Add(digest.Digest("sha384:123451111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(dset.entries) != 9 {
|
|
||||||
t.Fatal("Insert with different algorithm should be allowed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRemove(t *testing.T) {
|
|
||||||
digests, err := createDigests(10)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dset := NewSet()
|
|
||||||
for i := range digests {
|
|
||||||
if err := dset.Add(digests[i]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dgst, err := dset.Lookup(digests[0].String())
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if dgst != digests[0] {
|
|
||||||
t.Fatalf("Unexpected digest value:\n\tExpected: %s\n\tActual: %s", digests[0], dgst)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := dset.Remove(digests[0]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := dset.Lookup(digests[0].String()); err != ErrDigestNotFound {
|
|
||||||
t.Fatalf("Expected error %v when looking up removed digest, got %v", ErrDigestNotFound, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAll(t *testing.T) {
|
|
||||||
digests, err := createDigests(100)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dset := NewSet()
|
|
||||||
for i := range digests {
|
|
||||||
if err := dset.Add(digests[i]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
all := map[digest.Digest]struct{}{}
|
|
||||||
for _, dgst := range dset.All() {
|
|
||||||
all[dgst] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(all) != len(digests) {
|
|
||||||
t.Fatalf("Unexpected number of unique digests found:\n\tExpected: %d\n\tActual: %d", len(digests), len(all))
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, dgst := range digests {
|
|
||||||
if _, ok := all[dgst]; !ok {
|
|
||||||
t.Fatalf("Missing element at position %d: %s", i, dgst)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func assertEqualShort(t *testing.T, actual, expected string) {
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("Unexpected short value:\n\tExpected: %s\n\tActual: %s", expected, actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestShortCodeTable(t *testing.T) {
|
|
||||||
digests := []digest.Digest{
|
|
||||||
"sha256:1234111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:1234511111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:1234611111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:5432111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:6543111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:6432111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:6542111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
"sha256:6532111111111111111111111111111111111111111111111111111111111111",
|
|
||||||
}
|
|
||||||
|
|
||||||
dset := NewSet()
|
|
||||||
for i := range digests {
|
|
||||||
if err := dset.Add(digests[i]); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dump := ShortCodeTable(dset, 2)
|
|
||||||
|
|
||||||
if len(dump) < len(digests) {
|
|
||||||
t.Fatalf("Error unexpected size: %d, expecting %d", len(dump), len(digests))
|
|
||||||
}
|
|
||||||
assertEqualShort(t, dump[digests[0]], "12341")
|
|
||||||
assertEqualShort(t, dump[digests[1]], "12345")
|
|
||||||
assertEqualShort(t, dump[digests[2]], "12346")
|
|
||||||
assertEqualShort(t, dump[digests[3]], "54")
|
|
||||||
assertEqualShort(t, dump[digests[4]], "6543")
|
|
||||||
assertEqualShort(t, dump[digests[5]], "64")
|
|
||||||
assertEqualShort(t, dump[digests[6]], "6542")
|
|
||||||
assertEqualShort(t, dump[digests[7]], "653")
|
|
||||||
}
|
|
||||||
|
|
||||||
func createDigests(count int) ([]digest.Digest, error) {
|
|
||||||
r := rand.New(rand.NewSource(25823))
|
|
||||||
digests := make([]digest.Digest, count)
|
|
||||||
for i := range digests {
|
|
||||||
h := sha256.New()
|
|
||||||
if err := binary.Write(h, binary.BigEndian, r.Int63()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
digests[i] = digest.NewDigest("sha256", h)
|
|
||||||
}
|
|
||||||
return digests, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchAddNTable(b *testing.B, n int) {
|
|
||||||
digests, err := createDigests(n)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
|
|
||||||
for j := range digests {
|
|
||||||
if err = dset.Add(digests[j]); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchLookupNTable(b *testing.B, n int, shortLen int) {
|
|
||||||
digests, err := createDigests(n)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
|
|
||||||
for i := range digests {
|
|
||||||
if err := dset.Add(digests[i]); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
shorts := make([]string, 0, n)
|
|
||||||
for _, short := range ShortCodeTable(dset, shortLen) {
|
|
||||||
shorts = append(shorts, short)
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
if _, err = dset.Lookup(shorts[i%n]); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchRemoveNTable(b *testing.B, n int) {
|
|
||||||
digests, err := createDigests(n)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
|
|
||||||
b.StopTimer()
|
|
||||||
for j := range digests {
|
|
||||||
if err = dset.Add(digests[j]); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b.StartTimer()
|
|
||||||
for j := range digests {
|
|
||||||
if err = dset.Remove(digests[j]); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchShortCodeNTable(b *testing.B, n int, shortLen int) {
|
|
||||||
digests, err := createDigests(n)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
|
|
||||||
for i := range digests {
|
|
||||||
if err := dset.Add(digests[i]); err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
ShortCodeTable(dset, shortLen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkAdd10(b *testing.B) {
|
|
||||||
benchAddNTable(b, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkAdd100(b *testing.B) {
|
|
||||||
benchAddNTable(b, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkAdd1000(b *testing.B) {
|
|
||||||
benchAddNTable(b, 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkRemove10(b *testing.B) {
|
|
||||||
benchRemoveNTable(b, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkRemove100(b *testing.B) {
|
|
||||||
benchRemoveNTable(b, 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkRemove1000(b *testing.B) {
|
|
||||||
benchRemoveNTable(b, 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLookup10(b *testing.B) {
|
|
||||||
benchLookupNTable(b, 10, 12)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLookup100(b *testing.B) {
|
|
||||||
benchLookupNTable(b, 100, 12)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkLookup1000(b *testing.B) {
|
|
||||||
benchLookupNTable(b, 1000, 12)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkShortCode10(b *testing.B) {
|
|
||||||
benchShortCodeNTable(b, 10, 12)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkShortCode100(b *testing.B) {
|
|
||||||
benchShortCodeNTable(b, 100, 12)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkShortCode1000(b *testing.B) {
|
|
||||||
benchShortCodeNTable(b, 1000, 12)
|
|
||||||
}
|
|
15
digestset/set.go → vendor/github.com/opencontainers/go-digest/digestset/set.go
generated
vendored
15
digestset/set.go → vendor/github.com/opencontainers/go-digest/digestset/set.go
generated
vendored
|
@ -1,3 +1,18 @@
|
||||||
|
// Copyright 2020, 2020 OCI Contributors
|
||||||
|
// Copyright 2017 Docker, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
package digestset
|
package digestset
|
||||||
|
|
||||||
import (
|
import (
|
1
vendor/modules.txt
vendored
1
vendor/modules.txt
vendored
|
@ -181,6 +181,7 @@ github.com/ncw/swift/swifttest
|
||||||
# github.com/opencontainers/go-digest v1.0.0
|
# github.com/opencontainers/go-digest v1.0.0
|
||||||
## explicit; go 1.13
|
## explicit; go 1.13
|
||||||
github.com/opencontainers/go-digest
|
github.com/opencontainers/go-digest
|
||||||
|
github.com/opencontainers/go-digest/digestset
|
||||||
# github.com/opencontainers/image-spec v1.0.2
|
# github.com/opencontainers/image-spec v1.0.2
|
||||||
## explicit
|
## explicit
|
||||||
github.com/opencontainers/image-spec/specs-go
|
github.com/opencontainers/image-spec/specs-go
|
||||||
|
|
Loading…
Reference in a new issue