70 lines
1.3 KiB
Go
70 lines
1.3 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("!q.fs.mu.TryLock()")
|
|
q.log.Info("quota usage", "current", q.cur, "max", q.max)
|
|
defer q.fs.mu.Unlock()
|
|
defer q.log.Info("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()
|
|
}
|
|
}
|