Documentation
¶
Overview ¶
Package hashcache provides a size-bounded, TTL-evicting cache of security scan results keyed on the SHA-256 digest of scanned content. It is a self-contained leaf (stdlib only, no Culvert coupling) extracted from the flat package main per ADR-0002.
Avoids redundant ClamAV / YARA scans by caching the outcome of each scan keyed on the SHA-256 digest of the scanned content. The same executable or document delivered from multiple hosts is therefore scanned only once per TTL window, dramatically reducing CPU load on busy proxies.
Design:
- Fixed-capacity map with TTL expiry.
- On capacity overflow: expired entries are evicted first; if still full, ~25 % of entries are dropped (simple, avoids per-entry LRU bookkeeping).
- All operations are mutex-protected; hit/miss counters use atomic int64.
Index ¶
- func SHA256Hex(data []byte) string
- type HashCache
- func (c *HashCache) Clear()
- func (c *HashCache) Evict(hash string) bool
- func (c *HashCache) Get(hash string) (ScanCacheResult, bool)
- func (c *HashCache) Set(hash string, result ScanCacheResult)
- func (c *HashCache) SetTTL(hash string, result ScanCacheResult, ttl time.Duration)
- func (c *HashCache) SetTTLUnless(hash string, result ScanCacheResult, ttl time.Duration, ...) bool
- func (c *HashCache) Stats() (hits, misses int64, currentSize int)
- type ScanCacheResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type HashCache ¶
type HashCache struct {
// contains filtered or unexported fields
}
HashCache is a size-bounded, TTL-evicting cache of SHA-256 scan results.
func New ¶
New returns a HashCache with the given capacity and TTL. Sensible defaults are used when size ≤ 0 or ttl ≤ 0.
func (*HashCache) Evict ¶
Evict removes a specific hash from the cache. Returns true if the entry existed (regardless of expiry).
func (*HashCache) Get ¶
func (c *HashCache) Get(hash string) (ScanCacheResult, bool)
Get retrieves a cached result for the given hash. Returns (result, true) on a valid, non-expired cache hit.
func (*HashCache) Set ¶
func (c *HashCache) Set(hash string, result ScanCacheResult)
Set stores a scan result under the given content hash, with the cache's configured TTL.
func (*HashCache) SetTTL ¶ added in v1.0.209
func (c *HashCache) SetTTL(hash string, result ScanCacheResult, ttl time.Duration)
SetTTL stores a scan result with an explicit lifetime; ttl ≤ 0 uses the cache's configured TTL.
It exists for verdicts that are ABOUT THE SCANNER rather than about the content — a fail-closed scan-timeout refusal, for instance. Those must not inherit the content TTL: a scanner that was briefly slow would otherwise keep blocking a specific object for the rest of the hour, long after it recovered.
func (*HashCache) SetTTLUnless ¶ added in v1.0.209
func (c *HashCache) SetTTLUnless(hash string, result ScanCacheResult, ttl time.Duration, keep func(existing ScanCacheResult) bool) bool
SetTTLUnless stores result under hash with the given lifetime unless keep reports that the entry already present must be preserved. It returns whether the write happened; ttl ≤ 0 uses the cache's configured TTL.
The test and the write are one atomic step under the cache lock. A caller doing Get-then-Set instead would leave a window in which a stronger verdict lands between the two and is overwritten anyway — which is the exact race this exists to close. keep is called only with a present, unexpired entry (an expired one counts as absent), and hit/miss counters are untouched: this is a write path, not a lookup.