aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/match.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 15:16:55 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 15:16:55 +0200
commit0b5d0eb92c5be2f0ddb2fa73990f31e5654e57fe (patch)
tree358e331945b8206ed4a72703e3aedfe8ea7cdcdb /internal/engine/match.go
parent1d3f2d1e4c59867024470d3444e12698b7ebb22e (diff)
downloadkrino-0b5d0eb92c5be2f0ddb2fa73990f31e5654e57fe.tar.gz
krino-0b5d0eb92c5be2f0ddb2fa73990f31e5654e57fe.zip
krino: 0.0.5 — keyword cache, t and d in reviewv0.0.5
Diffstat (limited to 'internal/engine/match.go')
-rw-r--r--internal/engine/match.go45
1 files changed, 36 insertions, 9 deletions
diff --git a/internal/engine/match.go b/internal/engine/match.go
index 8daea9d..1a8077a 100644
--- a/internal/engine/match.go
+++ b/internal/engine/match.go
@@ -16,6 +16,7 @@ import (
"krino/internal/cond"
"krino/internal/config"
+ "krino/internal/kwcache"
"krino/internal/plan"
"krino/internal/scan"
"krino/internal/xdg"
@@ -70,6 +71,7 @@ func (e *Engine) Match(ctx context.Context, d *Dir) (*Result, error) {
}
run := newMatchRun(e, d, ctx, now, wres.Files)
+ cacheWarn := e.openCache(run)
fileMatches := make([]FileMatch, len(wres.Files))
workers := runtime.GOMAXPROCS(0)
@@ -103,7 +105,18 @@ func (e *Engine) Match(ctx context.Context, d *Dir) (*Result, error) {
}
}
- warnings := run.warnings()
+ warnings := append(run.warnings(), cacheWarn...)
+ if run.cache != nil {
+ ids := make([]kwcache.ID, 0, len(wres.Files))
+ for _, f := range wres.Files {
+ if f.Ino != 0 {
+ ids = append(ids, fileCacheID(f))
+ }
+ }
+ if err := run.cache.Save(e.cacheFile(d), ids); err != nil {
+ warnings = append(warnings, "cache: "+err.Error())
+ }
+ }
sort.Strings(warnings)
return &Result{
@@ -242,20 +255,14 @@ func (e *Engine) Explain(ctx context.Context, path string) (*Explanation, error)
}
rel = filepath.ToSlash(rel)
- sf := scan.File{
- Path: abs,
- Rel: rel,
- Name: filepath.Base(abs),
- Size: info.Size(),
- ModTime: info.ModTime(),
- Mode: info.Mode(),
- }
+ sf := scan.NewFile(abs, rel, info)
now := e.Now()
excl := e.excludeDirs(d)
skip := explainSkip(d, sf, excl, now)
run := newMatchRun(e, d, ctx, now, e.filesForExplain(d, sf, excl, now))
+ e.openCache(run) // read only: Explain never writes the cache
f := newFacts(run, sf)
var excludes []ExcludeTrace
@@ -289,6 +296,26 @@ func (e *Engine) Explain(ctx context.Context, path string) (*Explanation, error)
return &Explanation{Dir: d, File: sf, Skip: skip, Excludes: excludes, Excluded: excluded, Rules: rules}, nil
}
+// cacheFile is d's keyword cache file.
+func (e *Engine) cacheFile(d *Dir) string {
+ return filepath.Join(e.CacheDir, d.Name+".cache")
+}
+
+// openCache loads run's directory keyword cache into run.cache, when the
+// engine has a CacheDir and the directory has content tests at all. A cache
+// that cannot be read is replaced by an empty one, reported as a warning.
+func (e *Engine) openCache(run *matchRun) []string {
+ if e.CacheDir == "" || len(run.d.ContentKeywords) == 0 {
+ return nil
+ }
+ c, err := kwcache.Load(e.cacheFile(run.d), e.Extract.Fingerprint())
+ run.cache = c
+ if err != nil {
+ return []string{"cache: " + err.Error() + " (starting a new one)"}
+ }
+ return nil
+}
+
// filesForExplain returns the file set Explain's duplicate checks run
// against: the directory's ordinary scan, plus the explained file itself
// when that scan would not have reached it (it is busy, ignored, too new,