Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gogen/packages/cache: pkgCache.hash #415

Merged
merged 1 commit into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions packages/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ type depPkg struct {

type pkgCache struct {
expfile string
hash string
deps []depPkg
}

// PkgHash represents a package hash function.
type PkgHash func(pkgPath string) (hash string)
type PkgHash func(pkgPath string, self bool) (hash string)

// Impl represents a cache.
type Impl struct {
Expand Down Expand Up @@ -63,10 +64,12 @@ func (p *Impl) Prepare(dir string, pkgPath ...string) (err error) {
if err != nil {
return
}
h := p.h
for _, v := range ret {
pkg := &pkgCache{expfile: v.expfile, deps: make([]depPkg, 0, len(v.deps))}
deps := make([]depPkg, 0, len(v.deps))
pkg := &pkgCache{expfile: v.expfile, hash: h(v.path, true), deps: deps}
for _, dep := range v.deps {
pkg.deps = append(pkg.deps, depPkg{dep, p.h(dep)})
pkg.deps = append(pkg.deps, depPkg{dep, h(dep, false)})
}
p.cache.Store(v.path, pkg)
}
Expand All @@ -76,7 +79,7 @@ func (p *Impl) Prepare(dir string, pkgPath ...string) (err error) {
// Find finds the cache for a pkgPath.
func (p *Impl) Find(dir, pkgPath string) (expfile string, err error) {
val, ok := p.cache.Load(pkgPath)
if !ok || isDirty(val, p.h) {
if !ok || isDirty(pkgPath, val, p.h) {
err = p.Prepare(dir, pkgPath)
if val, ok = p.cache.Load(pkgPath); !ok {
if err == nil {
Expand All @@ -88,9 +91,13 @@ func (p *Impl) Find(dir, pkgPath string) (expfile string, err error) {
return val.(*pkgCache).expfile, nil
}

func isDirty(val any, h PkgHash) bool {
for _, dep := range val.(*pkgCache).deps {
if dep.hash == "" || h(dep.path) != dep.hash {
func isDirty(pkgPath string, val any, h PkgHash) bool {
pkg := val.(*pkgCache)
if pkg.hash == "" || h(pkgPath, true) != pkg.hash {
return true
}
for _, dep := range pkg.deps {
if h(dep.path, false) != dep.hash {
return true
}
}
Expand Down Expand Up @@ -164,7 +171,7 @@ var (

/*
DiskCache cacheFile format:
<pkgPath> <exportFile> <depPkgNum>
<pkgPath> <exportFile> <pkgHash> <depPkgNum>
<depPkgPath1> <depPkgHash1>
<depPkgPath2> <depPkgHash2>
...
Expand All @@ -188,11 +195,11 @@ func (p *Impl) Load(cacheFile string) (err error) {
func (p *Impl) loadCachePkgs(lines []string) error {
for len(lines) > 0 {
line := lines[0]
parts := strings.SplitN(line, "\t", 3)
if len(parts) != 3 || parts[0] == "" {
parts := strings.SplitN(line, "\t", 4)
if len(parts) != 4 || parts[0] == "" {
return errInvalidFormat
}
n, e := strconv.Atoi(parts[2])
n, e := strconv.Atoi(parts[3])
if e != nil || len(lines) < n+1 {
return errInvalidFormat
}
Expand All @@ -209,7 +216,7 @@ func (p *Impl) loadCachePkgs(lines []string) error {
}
deps = append(deps, depPkg{line[:pos], line[pos+1:]})
}
pkg := &pkgCache{expfile: parts[1], deps: deps}
pkg := &pkgCache{expfile: parts[1], hash: parts[2], deps: deps}
p.cache.Store(parts[0], pkg)
lines = lines[n+1:]
}
Expand All @@ -225,6 +232,8 @@ func (p *Impl) Save(cacheFile string) (err error) {
buf.WriteByte('\t')
buf.WriteString(pkg.expfile)
buf.WriteByte('\t')
buf.WriteString(pkg.hash)
buf.WriteByte('\t')
buf.WriteString(strconv.Itoa(len(pkg.deps)))
buf.WriteByte('\n')
for _, dep := range pkg.deps {
Expand Down
24 changes: 19 additions & 5 deletions packages/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import (
"github.com/goplus/gogen/packages"
)

func dirtyPkgHash(pkgPath string) string {
func dirtyPkgHash(pkgPath string, self bool) string {
return ""
}

func nodirtyPkgHash(pkgPath string) string {
func nodirtyPkgHash(pkgPath string, self bool) string {
return "1"
}

Expand Down Expand Up @@ -105,6 +105,20 @@ func TestBasic(t *testing.T) {
}
}

func TestIsDirty(t *testing.T) {
c := &pkgCache{"1.a", "a", []depPkg{
{"b", "b"},
}}
if !isDirty("a", c, func(pkgPath string, self bool) (hash string) {
if self {
return pkgPath
}
return ""
}) {
t.Fatal("isDirty: is not dirty")
}
}

func TestParseExport(t *testing.T) {
if _, e := parseExports("abc"); e != errInvalidFormat {
t.Fatal("parseExports failed:", e)
Expand All @@ -116,13 +130,13 @@ func TestErrLoadCache(t *testing.T) {
if err := c.loadCachePkgs([]string{"abc"}); err != errInvalidFormat {
t.Fatal("loadCachePkgs failed:", err)
}
if err := c.loadCachePkgs([]string{"abc\tefg\t3"}); err != errInvalidFormat {
if err := c.loadCachePkgs([]string{"abc\tefg\thash\t3"}); err != errInvalidFormat {
t.Fatal("loadCachePkgs failed:", err)
}
if err := c.loadCachePkgs([]string{"abc\tefg\t1", "x"}); err != errInvalidFormat {
if err := c.loadCachePkgs([]string{"abc\tefg\thash\t1", "x"}); err != errInvalidFormat {
t.Fatal("loadCachePkgs failed:", err)
}
if err := c.loadCachePkgs([]string{"abc\tefg\t1", "\tx"}); err != errInvalidFormat {
if err := c.loadCachePkgs([]string{"abc\tefg\thash\t1", "\tx"}); err != errInvalidFormat {
t.Fatal("loadCachePkgs failed:", err)
}
}