Skip to content
This repository has been archived by the owner on Sep 9, 2020. It is now read-only.

Commit

Permalink
Merge pull request #1138 from jmank88/multi_cache
Browse files Browse the repository at this point in the history
gps: source cache: adding multiCache
  • Loading branch information
sdboyer authored Sep 18, 2017
2 parents 92657ba + 902ea2b commit 166626d
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 2 deletions.
120 changes: 120 additions & 0 deletions internal/gps/source_cache_multi.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gps

import (
"github.com/golang/dep/internal/gps/pkgtree"
)

// A multiCache manages two cache levels, ephemeral in-memory and persistent on-disk.
//
// The in-memory cache is always checked first, with the on-disk used as a fallback.
// Values read from disk are set in-memory when an appropriate method exists.
//
// Set values are cached both in-memory and on-disk.
type multiCache struct {
mem, disk singleSourceCache
}

func (c *multiCache) setManifestAndLock(r Revision, ai ProjectAnalyzerInfo, m Manifest, l Lock) {
c.mem.setManifestAndLock(r, ai, m, l)
c.disk.setManifestAndLock(r, ai, m, l)
}

func (c *multiCache) getManifestAndLock(r Revision, ai ProjectAnalyzerInfo) (Manifest, Lock, bool) {
m, l, ok := c.mem.getManifestAndLock(r, ai)
if ok {
return m, l, true
}

m, l, ok = c.disk.getManifestAndLock(r, ai)
if ok {
c.mem.setManifestAndLock(r, ai, m, l)
return m, l, true
}

return nil, nil, false
}

func (c *multiCache) setPackageTree(r Revision, ptree pkgtree.PackageTree) {
c.mem.setPackageTree(r, ptree)
c.disk.setPackageTree(r, ptree)
}

func (c *multiCache) getPackageTree(r Revision) (pkgtree.PackageTree, bool) {
ptree, ok := c.mem.getPackageTree(r)
if ok {
return ptree, true
}

ptree, ok = c.disk.getPackageTree(r)
if ok {
c.mem.setPackageTree(r, ptree)
return ptree, true
}

return pkgtree.PackageTree{}, false
}

func (c *multiCache) markRevisionExists(r Revision) {
c.mem.markRevisionExists(r)
c.disk.markRevisionExists(r)
}

func (c *multiCache) setVersionMap(pvs []PairedVersion) {
c.mem.setVersionMap(pvs)
c.disk.setVersionMap(pvs)
}

func (c *multiCache) getVersionsFor(rev Revision) ([]UnpairedVersion, bool) {
uvs, ok := c.mem.getVersionsFor(rev)
if ok {
return uvs, true
}

return c.disk.getVersionsFor(rev)
}

func (c *multiCache) getAllVersions() []PairedVersion {
pvs := c.mem.getAllVersions()
if pvs != nil {
return pvs
}

pvs = c.disk.getAllVersions()
if pvs != nil {
c.mem.setVersionMap(pvs)
return pvs
}

return nil
}

func (c *multiCache) getRevisionFor(uv UnpairedVersion) (Revision, bool) {
rev, ok := c.mem.getRevisionFor(uv)
if ok {
return rev, true
}

return c.disk.getRevisionFor(uv)
}

func (c *multiCache) toRevision(v Version) (Revision, bool) {
rev, ok := c.mem.toRevision(v)
if ok {
return rev, true
}

return c.disk.toRevision(v)
}

func (c *multiCache) toUnpaired(v Version) (UnpairedVersion, bool) {
uv, ok := c.mem.toUnpaired(v)
if ok {
return uv, true
}

return c.disk.toUnpaired(v)
}
64 changes: 62 additions & 2 deletions internal/gps/source_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,29 @@ func Test_singleSourceCache(t *testing.T) {
}
return bc.newSingleSourceCache(pi), bc.close
}
t.Run("bolt/open", singleSourceCacheTest{newCache: newBolt}.run)
t.Run("bolt/refresh", singleSourceCacheTest{newCache: newBolt, persistent: true}.run)
t.Run("bolt/keepOpen", singleSourceCacheTest{newCache: newBolt}.run)
t.Run("bolt/reOpen", singleSourceCacheTest{newCache: newBolt, persistent: true}.run)

newMulti := func(t *testing.T, cachedir, root string) (singleSourceCache, func() error) {
disk, close := newBolt(t, cachedir, root)
return &multiCache{mem: newMemoryCache(), disk: disk}, close
}
t.Run("multi/keepOpen", singleSourceCacheTest{newCache: newMulti}.run)
t.Run("multi/reOpen", singleSourceCacheTest{persistent: true, newCache: newMulti}.run)

t.Run("multi/keepOpen/noDisk", singleSourceCacheTest{
newCache: func(*testing.T, string, string) (singleSourceCache, func() error) {
return &multiCache{mem: newMemoryCache(), disk: discardCache{}}, func() error { return nil }
},
}.run)

t.Run("multi/reOpen/noMem", singleSourceCacheTest{
persistent: true,
newCache: func(t *testing.T, cachedir, root string) (singleSourceCache, func() error) {
disk, close := newBolt(t, cachedir, root)
return &multiCache{mem: discardCache{}, disk: disk}, close
},
}.run)
}

var testAnalyzerInfo = ProjectAnalyzerInfo{
Expand Down Expand Up @@ -521,3 +542,42 @@ func packageOrErrEqual(a, b pkgtree.PackageOrErr) bool {

return true
}

// discardCache discards set values and returns nothing.
type discardCache struct{}

func (discardCache) setManifestAndLock(Revision, ProjectAnalyzerInfo, Manifest, Lock) {}

func (discardCache) getManifestAndLock(Revision, ProjectAnalyzerInfo) (Manifest, Lock, bool) {
return nil, nil, false
}

func (discardCache) setPackageTree(Revision, pkgtree.PackageTree) {}

func (discardCache) getPackageTree(Revision) (pkgtree.PackageTree, bool) {
return pkgtree.PackageTree{}, false
}

func (discardCache) markRevisionExists(r Revision) {}

func (discardCache) setVersionMap(versionList []PairedVersion) {}

func (discardCache) getVersionsFor(Revision) ([]UnpairedVersion, bool) {
return nil, false
}

func (discardCache) getAllVersions() []PairedVersion {
return nil
}

func (discardCache) getRevisionFor(UnpairedVersion) (Revision, bool) {
return "", false
}

func (discardCache) toRevision(v Version) (Revision, bool) {
return "", false
}

func (discardCache) toUnpaired(v Version) (UnpairedVersion, bool) {
return nil, false
}

0 comments on commit 166626d

Please sign in to comment.