cachefs/pkg/fs/stat.go
2022-03-20 10:19:03 +01:00

64 lines
1.1 KiB
Go

// Copyright (C) 2022 Marius Schellenberger
package fs
import (
"context"
"os"
"sync"
"time"
)
const statExpiry = time.Minute * 5
type statCacheEntry struct {
mtime time.Time
fi os.FileInfo
}
type StatCache struct {
mu sync.RWMutex
ctx context.Context
m map[string]*statCacheEntry
}
func NewStatCache(ctx context.Context) *StatCache {
sc := &StatCache{ctx: ctx, m: make(map[string]*statCacheEntry)}
go sc.cleanup()
return sc
}
func (sc *StatCache) cleanup() {
t := time.NewTicker(statExpiry)
defer t.Stop()
for {
select {
case <-sc.ctx.Done():
return
case <-t.C:
}
sc.mu.Lock()
now := time.Now()
for k, sce := range sc.m {
if now.After(sce.mtime) {
delete(sc.m, k)
}
}
sc.mu.Unlock()
}
}
func (sc *StatCache) Get(name string) (os.FileInfo, error) {
sc.mu.RLock()
defer sc.mu.RUnlock()
if sce, ok := sc.m[name]; ok {
return sce.fi, nil
}
return nil, NoCacheEntry
}
func (sc *StatCache) Set(name string, fi os.FileInfo) {
sc.mu.Lock()
defer sc.mu.Unlock()
sc.m[name] = &statCacheEntry{time.Now().Add(statExpiry), fi}
}