diff --git a/cache/instructioncache/union.go b/cache/instructioncache/union.go new file mode 100644 index 00000000..47454e45 --- /dev/null +++ b/cache/instructioncache/union.go @@ -0,0 +1,57 @@ +package instructioncache + +import ( + "golang.org/x/net/context" + + digest "github.com/opencontainers/go-digest" +) + +// Union creates a union of two caches. +// Set operations affects only on the base one. +func Union(base, another InstructionCache) InstructionCache { + return &union{base: base, another: another} +} + +type union struct { + base InstructionCache + another InstructionCache +} + +func (u *union) Probe(ctx context.Context, key digest.Digest) (bool, error) { + v, err := u.base.Probe(ctx, key) + if err != nil { + return false, err + } + if v { + return v, nil + } + return u.another.Probe(ctx, key) +} + +func (u *union) Lookup(ctx context.Context, key digest.Digest, msg string) (interface{}, error) { + v, err := u.base.Probe(ctx, key) + if err != nil { + return false, err + } + if v { + return u.base.Lookup(ctx, key, msg) + } + return u.another.Lookup(ctx, key, msg) +} +func (u *union) Set(key digest.Digest, ref interface{}) error { + return u.base.Set(key, ref) +} +func (u *union) SetContentMapping(contentKey, key digest.Digest) error { + return u.base.SetContentMapping(contentKey, key) +} +func (u *union) GetContentMapping(dgst digest.Digest) ([]digest.Digest, error) { + localKeys, err := u.base.GetContentMapping(dgst) + if err != nil { + return nil, err + } + remoteKeys, err := u.another.GetContentMapping(dgst) + if err != nil { + return nil, err + } + return append(localKeys, remoteKeys...), nil +} diff --git a/solver/solver.go b/solver/solver.go index 5c701a90..8744f4e7 100644 --- a/solver/solver.go +++ b/solver/solver.go @@ -137,7 +137,7 @@ func (s *Solver) Solve(ctx context.Context, id string, req SolveRequest) error { if err != nil { return err } - defaultWorker.InstructionCache = mergeRemoteCache(defaultWorker.InstructionCache, cache) + defaultWorker.InstructionCache = instructioncache.Union(defaultWorker.InstructionCache, cache) } // register a build job. vertex needs to be loaded to a job to run @@ -780,51 +780,3 @@ type VertexResult struct { func cacheKeyForIndex(dgst digest.Digest, index Index) digest.Digest { return digest.FromBytes([]byte(fmt.Sprintf("%s.%d", dgst, index))) } - -func mergeRemoteCache(local, remote instructioncache.InstructionCache) instructioncache.InstructionCache { - return &mergedCache{local: local, remote: remote} -} - -type mergedCache struct { - local instructioncache.InstructionCache - remote instructioncache.InstructionCache -} - -func (mc *mergedCache) Probe(ctx context.Context, key digest.Digest) (bool, error) { - v, err := mc.local.Probe(ctx, key) - if err != nil { - return false, err - } - if v { - return v, nil - } - return mc.remote.Probe(ctx, key) -} - -func (mc *mergedCache) Lookup(ctx context.Context, key digest.Digest, msg string) (interface{}, error) { - v, err := mc.local.Probe(ctx, key) - if err != nil { - return false, err - } - if v { - return mc.local.Lookup(ctx, key, msg) - } - return mc.remote.Lookup(ctx, key, msg) -} -func (mc *mergedCache) Set(key digest.Digest, ref interface{}) error { - return mc.local.Set(key, ref) -} -func (mc *mergedCache) SetContentMapping(contentKey, key digest.Digest) error { - return mc.local.SetContentMapping(contentKey, key) -} -func (mc *mergedCache) GetContentMapping(dgst digest.Digest) ([]digest.Digest, error) { - localKeys, err := mc.local.GetContentMapping(dgst) - if err != nil { - return nil, err - } - remoteKeys, err := mc.remote.GetContentMapping(dgst) - if err != nil { - return nil, err - } - return append(localKeys, remoteKeys...), nil -}