From e0dddff176a01d410904b6750b3395de4f7e54db Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 14 Sep 2026 21:39:00 +0200 Subject: plan 9: keyword cache keys on extension, max-read and Unicode tables, trims removed keywords --- internal/engine/match.go | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'internal/engine/match.go') diff --git a/internal/engine/match.go b/internal/engine/match.go index b922829..08d75af 100644 --- a/internal/engine/match.go +++ b/internal/engine/match.go @@ -114,7 +114,11 @@ func (e *Engine) Match(ctx context.Context, d *Dir) (*Result, error) { ids = append(ids, fileCacheID(f)) } } - if err := run.cache.Save(e.cacheFile(d), ids); err != nil { + keys := make([]string, len(d.ContentKeywords)) + for i, k := range d.ContentKeywords { + keys[i] = k.Key() + } + if err := run.cache.Save(e.cacheFile(d), ids, keys); err != nil { warnings = append(warnings, "cache: "+err.Error()) } } @@ -297,11 +301,12 @@ 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 } -// cacheFingerprint identifies what a cached keyword answer depends on -// besides the file: the extractor (its version and tools) and the -// normalisation version. A cache written under any other is discarded. -func (e *Engine) cacheFingerprint() string { - return fmt.Sprintf("%s norm%d", e.Extract.Fingerprint(), norm.Version) +// cacheFingerprint identifies what a cached keyword answer of d depends on +// besides the file: the extractor (its version and tools), normalisation +// and its Unicode tables, the Go release, and d's max-read, which caps what +// is read. A cache written under any other is discarded. +func (e *Engine) cacheFingerprint(d *Dir) string { + return fmt.Sprintf("%s %s %s max-read=%d", e.Extract.Fingerprint(), norm.Fingerprint(), runtime.Version(), d.Settings.MaxRead) } // cacheFile is d's keyword cache file. @@ -313,10 +318,18 @@ func (e *Engine) cacheFile(d *Dir) string { // 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 { + if e.CacheDir == "" { + return nil + } + if len(run.d.ContentKeywords) == 0 { + // No content test left: a cache from an earlier configuration only + // holds keywords this directory no longer uses (review cache F6). + if err := os.Remove(e.cacheFile(run.d)); err != nil && !os.IsNotExist(err) { + return []string{"cache: " + err.Error()} + } return nil } - c, err := kwcache.Load(e.cacheFile(run.d), e.cacheFingerprint()) + c, err := kwcache.Load(e.cacheFile(run.d), e.cacheFingerprint(run.d)) run.cache = c if err != nil { return []string{"cache: " + err.Error() + " (starting a new one)"} -- cgit v1.3