refactor: moved the GC stuff around and corrected all tests
All checks were successful
PR Check / check-and-test (pull_request) Successful in 30s

This commit is contained in:
2025-07-13 04:20:12 -05:00
parent 1673e9554a
commit 539f14e8ec
9 changed files with 368 additions and 376 deletions

View File

@@ -4,10 +4,76 @@ package gc
import (
"fmt"
"io"
"s1d3sw1ped/SteamCache2/steamcache/logger"
"s1d3sw1ped/SteamCache2/vfs"
"s1d3sw1ped/SteamCache2/vfs/cachestate"
"s1d3sw1ped/SteamCache2/vfs/disk"
"s1d3sw1ped/SteamCache2/vfs/memory"
"s1d3sw1ped/SteamCache2/vfs/vfserror"
"time"
)
// LRUGC deletes files in LRU order until enough space is reclaimed.
func LRUGC(vfss vfs.VFS, size uint) {
attempts := 0
deletions := 0
var reclaimed uint
for reclaimed < size {
if attempts > 10 {
logger.Logger.Debug().
Int("attempts", attempts).
Msg("GC: Too many attempts to reclaim space, giving up")
return
}
attempts++
switch fs := vfss.(type) {
case *disk.DiskFS:
fi := fs.LRU.Back()
if fi == nil {
break
}
sz := uint(fi.Size())
err := fs.Delete(fi.Name())
if err != nil {
continue
}
reclaimed += sz
deletions++
case *memory.MemoryFS:
fi := fs.LRU.Back()
if fi == nil {
break
}
sz := uint(fi.Size())
err := fs.Delete(fi.Name())
if err != nil {
continue
}
reclaimed += sz
deletions++
default:
// Fallback to old method if not supported
stats := vfss.StatAll()
if len(stats) == 0 {
break
}
fi := stats[0] // Assume sorted or pick first
sz := uint(fi.Size())
err := vfss.Delete(fi.Name())
if err != nil {
continue
}
reclaimed += sz
deletions++
}
}
}
func PromotionDecider(fi *vfs.FileInfo, cs cachestate.CacheState) bool {
return time.Since(fi.AccessTime()) < time.Second*60 // Put hot files in the fast vfs if equipped
}
// Ensure GCFS implements VFS.
var _ vfs.VFS = (*GCFS)(nil)
@@ -39,7 +105,7 @@ func (g *GCFS) Create(key string, size int64) (io.WriteCloser, error) {
w, err := g.VFS.Create(key, size) // try to create the key
// if it fails due to disk full error, call the GC handler and try again in a loop that will continue until it succeeds or the error is not disk full
for err == vfserror.ErrDiskFull && g.gcHanderFunc != nil { // if the error is disk full and there is a GC handler
if err == vfserror.ErrDiskFull && g.gcHanderFunc != nil { // if the error is disk full and there is a GC handler
g.gcHanderFunc(g.VFS, uint(size*int64(g.multiplier))) // call the GC handler
w, err = g.VFS.Create(key, size)
}