// Copyright (C) 2022 Marius Schellenberger package fs import ( "errors" "sync" "sync/atomic" "github.com/go-logr/logr" ) var InvalidMaxQuota = errors.New("invalid max quota") type Quota struct { mu sync.Mutex log logr.Logger fs *FS cur int64 max int64 } func NewQuota(cur, max int64, fs *FS, log logr.Logger) (q *Quota, err error) { if max <= 0 { err = InvalidMaxQuota return } q = &Quota{log: log, fs: fs, cur: cur, max: max} q.log.Info("quota usage", "current", q.cur, "max", q.max) return } func (q *Quota) Usage() (cur, max int64) { cur = atomic.LoadInt64(&q.cur) max = q.max return } func (q *Quota) cleanup() { if !q.mu.TryLock() { return } q.log.Info("quota usage", "current", atomic.LoadInt64(&q.cur), "max", q.max) defer q.mu.Unlock() size := q.fs.mh.DeleteOldest() atomic.AddInt64(&q.cur, -size) } func (q *Quota) Add(n int) { if q.max < atomic.AddInt64(&q.cur, int64(n)) { q.cleanup() } }