99 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
// Package cache provides facilities to speed up access to the storage
 | 
						|
// backend. Typically cache implementations deal with internal implementation
 | 
						|
// details at the backend level, rather than generalized caches for
 | 
						|
// distribution related interfaces. In other words, unless the cache is
 | 
						|
// specific to the storage package, it belongs in another package.
 | 
						|
package cache
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
 | 
						|
	"github.com/docker/distribution/digest"
 | 
						|
	"golang.org/x/net/context"
 | 
						|
)
 | 
						|
 | 
						|
// ErrNotFound is returned when a meta item is not found.
 | 
						|
var ErrNotFound = fmt.Errorf("not found")
 | 
						|
 | 
						|
// LayerMeta describes the backend location and length of layer data.
 | 
						|
type LayerMeta struct {
 | 
						|
	Path   string
 | 
						|
	Length int64
 | 
						|
}
 | 
						|
 | 
						|
// LayerInfoCache is a driver-aware cache of layer metadata. Basically, it
 | 
						|
// provides a fast cache for checks against repository metadata, avoiding
 | 
						|
// round trips to backend storage. Note that this is different from a pure
 | 
						|
// layer cache, which would also provide access to backing data, as well. Such
 | 
						|
// a cache should be implemented as a middleware, rather than integrated with
 | 
						|
// the storage backend.
 | 
						|
//
 | 
						|
// Note that most implementations rely on the caller to do strict checks on on
 | 
						|
// repo and dgst arguments, since these are mostly used behind existing
 | 
						|
// implementations.
 | 
						|
type LayerInfoCache interface {
 | 
						|
	// Contains returns true if the repository with name contains the layer.
 | 
						|
	Contains(ctx context.Context, repo string, dgst digest.Digest) (bool, error)
 | 
						|
 | 
						|
	// Add includes the layer in the given repository cache.
 | 
						|
	Add(ctx context.Context, repo string, dgst digest.Digest) error
 | 
						|
 | 
						|
	// Meta provides the location of the layer on the backend and its size. Membership of a
 | 
						|
	// repository should be tested before using the result, if required.
 | 
						|
	Meta(ctx context.Context, dgst digest.Digest) (LayerMeta, error)
 | 
						|
 | 
						|
	// SetMeta sets the meta data for the given layer.
 | 
						|
	SetMeta(ctx context.Context, dgst digest.Digest, meta LayerMeta) error
 | 
						|
}
 | 
						|
 | 
						|
// base implements common checks between cache implementations. Note that
 | 
						|
// these are not full checks of input, since that should be done by the
 | 
						|
// caller.
 | 
						|
type base struct {
 | 
						|
	LayerInfoCache
 | 
						|
}
 | 
						|
 | 
						|
func (b *base) Contains(ctx context.Context, repo string, dgst digest.Digest) (bool, error) {
 | 
						|
	if repo == "" {
 | 
						|
		return false, fmt.Errorf("cache: cannot check for empty repository name")
 | 
						|
	}
 | 
						|
 | 
						|
	if dgst == "" {
 | 
						|
		return false, fmt.Errorf("cache: cannot check for empty digests")
 | 
						|
	}
 | 
						|
 | 
						|
	return b.LayerInfoCache.Contains(ctx, repo, dgst)
 | 
						|
}
 | 
						|
 | 
						|
func (b *base) Add(ctx context.Context, repo string, dgst digest.Digest) error {
 | 
						|
	if repo == "" {
 | 
						|
		return fmt.Errorf("cache: cannot add empty repository name")
 | 
						|
	}
 | 
						|
 | 
						|
	if dgst == "" {
 | 
						|
		return fmt.Errorf("cache: cannot add empty digest")
 | 
						|
	}
 | 
						|
 | 
						|
	return b.LayerInfoCache.Add(ctx, repo, dgst)
 | 
						|
}
 | 
						|
 | 
						|
func (b *base) Meta(ctx context.Context, dgst digest.Digest) (LayerMeta, error) {
 | 
						|
	if dgst == "" {
 | 
						|
		return LayerMeta{}, fmt.Errorf("cache: cannot get meta for empty digest")
 | 
						|
	}
 | 
						|
 | 
						|
	return b.LayerInfoCache.Meta(ctx, dgst)
 | 
						|
}
 | 
						|
 | 
						|
func (b *base) SetMeta(ctx context.Context, dgst digest.Digest, meta LayerMeta) error {
 | 
						|
	if dgst == "" {
 | 
						|
		return fmt.Errorf("cache: cannot set meta for empty digest")
 | 
						|
	}
 | 
						|
 | 
						|
	if meta.Path == "" {
 | 
						|
		return fmt.Errorf("cache: cannot set empty path for meta")
 | 
						|
	}
 | 
						|
 | 
						|
	return b.LayerInfoCache.SetMeta(ctx, dgst, meta)
 | 
						|
}
 |