cachefs/pkg/fs/quota.go
2022-03-19 15:49:04 +01:00

68 lines
1.2 KiB
Go

// Copyright (C) 2022 Marius Schellenberger
package fs
import (
"errors"
"math"
"sync/atomic"
"github.com/go-logr/logr"
)
var InvalidMaxQuota = errors.New("invalid max quota")
type Quota struct {
log logr.Logger
fs *FS
max int64
cur int64
}
func NewQuota(max int64, fs *FS, log logr.Logger) (q *Quota, err error) {
if max <= 0 {
err = InvalidMaxQuota
return
}
q = &Quota{log: log, fs: fs, max: max}
return
}
func (q *Quota) Init() {
for _, v := range q.fs.md {
q.cur += v.Chunks.Size()
}
q.log.Info("quota usage", "current", q.cur, "max", q.max)
}
func (q *Quota) cleanup() {
if !q.fs.mu.TryLock() {
return
}
q.log.Info("quota usage", "current", q.cur, "max", q.max)
defer q.fs.mu.Unlock()
atime := int64(math.MaxInt64)
var m *Metadata
for _, v := range q.fs.md {
if v.Atime != 0 && v.f != nil && v.Atime < atime {
atime = v.Atime
m = v
}
}
if m != nil {
log := q.log.WithValues("file", m.name)
log.Info("deleting oldest file")
err := m.Delete()
if err != nil {
q.log.Error(err, "error deleting oldest file")
return
}
atomic.AddInt64(&q.cur, -m.Size)
}
}
func (q *Quota) Add(n int) {
if q.max < atomic.AddInt64(&q.cur, int64(n)) {
q.cleanup()
}
}