github.com/endocode/docker@v1.4.2-0.20160113120958-46eb4700391e/distribution/metadata/blobsum_service.go (about) 1 package metadata 2 3 import ( 4 "encoding/json" 5 6 "github.com/docker/distribution/digest" 7 "github.com/docker/docker/layer" 8 ) 9 10 // BlobSumService maps layer IDs to a set of known blobsums for 11 // the layer. 12 type BlobSumService struct { 13 store Store 14 } 15 16 // maxBlobSums is the number of blobsums to keep per layer DiffID. 17 const maxBlobSums = 5 18 19 // NewBlobSumService creates a new blobsum mapping service. 20 func NewBlobSumService(store Store) *BlobSumService { 21 return &BlobSumService{ 22 store: store, 23 } 24 } 25 26 func (blobserv *BlobSumService) diffIDNamespace() string { 27 return "blobsum-storage" 28 } 29 30 func (blobserv *BlobSumService) blobSumNamespace() string { 31 return "blobsum-lookup" 32 } 33 34 func (blobserv *BlobSumService) diffIDKey(diffID layer.DiffID) string { 35 return string(digest.Digest(diffID).Algorithm()) + "/" + digest.Digest(diffID).Hex() 36 } 37 38 func (blobserv *BlobSumService) blobSumKey(blobsum digest.Digest) string { 39 return string(blobsum.Algorithm()) + "/" + blobsum.Hex() 40 } 41 42 // GetBlobSums finds the blobsums associated with a layer DiffID. 43 func (blobserv *BlobSumService) GetBlobSums(diffID layer.DiffID) ([]digest.Digest, error) { 44 jsonBytes, err := blobserv.store.Get(blobserv.diffIDNamespace(), blobserv.diffIDKey(diffID)) 45 if err != nil { 46 return nil, err 47 } 48 49 var blobsums []digest.Digest 50 if err := json.Unmarshal(jsonBytes, &blobsums); err != nil { 51 return nil, err 52 } 53 54 return blobsums, nil 55 } 56 57 // GetDiffID finds a layer DiffID from a blobsum hash. 58 func (blobserv *BlobSumService) GetDiffID(blobsum digest.Digest) (layer.DiffID, error) { 59 diffIDBytes, err := blobserv.store.Get(blobserv.blobSumNamespace(), blobserv.blobSumKey(blobsum)) 60 if err != nil { 61 return layer.DiffID(""), err 62 } 63 64 return layer.DiffID(diffIDBytes), nil 65 } 66 67 // Add associates a blobsum with a layer DiffID. If too many blobsums are 68 // present, the oldest one is dropped. 69 func (blobserv *BlobSumService) Add(diffID layer.DiffID, blobsum digest.Digest) error { 70 oldBlobSums, err := blobserv.GetBlobSums(diffID) 71 if err != nil { 72 oldBlobSums = nil 73 } 74 newBlobSums := make([]digest.Digest, 0, len(oldBlobSums)+1) 75 76 // Copy all other blobsums to new slice 77 for _, oldSum := range oldBlobSums { 78 if oldSum != blobsum { 79 newBlobSums = append(newBlobSums, oldSum) 80 } 81 } 82 83 newBlobSums = append(newBlobSums, blobsum) 84 85 if len(newBlobSums) > maxBlobSums { 86 newBlobSums = newBlobSums[len(newBlobSums)-maxBlobSums:] 87 } 88 89 jsonBytes, err := json.Marshal(newBlobSums) 90 if err != nil { 91 return err 92 } 93 94 err = blobserv.store.Set(blobserv.diffIDNamespace(), blobserv.diffIDKey(diffID), jsonBytes) 95 if err != nil { 96 return err 97 } 98 99 return blobserv.store.Set(blobserv.blobSumNamespace(), blobserv.blobSumKey(blobsum), []byte(diffID)) 100 }