diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-14 15:16:55 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-14 15:16:55 +0200 |
| commit | 0b5d0eb92c5be2f0ddb2fa73990f31e5654e57fe (patch) | |
| tree | 358e331945b8206ed4a72703e3aedfe8ea7cdcdb /internal/engine/match.go | |
| parent | 1d3f2d1e4c59867024470d3444e12698b7ebb22e (diff) | |
| download | krino-0.0.5.tar.gz krino-0.0.5.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.go | 45 |
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, |
