// vfs/cache/cache.go package cache import ( "io" "s1d3sw1ped/SteamCache2/vfs" "s1d3sw1ped/SteamCache2/vfs/vfserror" "sync" ) // TieredCache implements a two-tier cache with fast (memory) and slow (disk) storage type TieredCache struct { fast vfs.VFS // Memory cache (fast) slow vfs.VFS // Disk cache (slow) mu sync.RWMutex } // New creates a new tiered cache func New() *TieredCache { return &TieredCache{} } // SetFast sets the fast (memory) tier func (tc *TieredCache) SetFast(vfs vfs.VFS) { tc.mu.Lock() defer tc.mu.Unlock() tc.fast = vfs } // SetSlow sets the slow (disk) tier func (tc *TieredCache) SetSlow(vfs vfs.VFS) { tc.mu.Lock() defer tc.mu.Unlock() tc.slow = vfs } // Create creates a new file, preferring the slow tier for persistence testing func (tc *TieredCache) Create(key string, size int64) (io.WriteCloser, error) { tc.mu.RLock() defer tc.mu.RUnlock() // Try slow tier first (disk) for better testability if tc.slow != nil { return tc.slow.Create(key, size) } // Fall back to fast tier (memory) if tc.fast != nil { return tc.fast.Create(key, size) } return nil, vfserror.ErrNotFound } // Open opens a file, checking fast tier first, then slow tier func (tc *TieredCache) Open(key string) (io.ReadCloser, error) { tc.mu.RLock() defer tc.mu.RUnlock() // Try fast tier first (memory) if tc.fast != nil { if reader, err := tc.fast.Open(key); err == nil { return reader, nil } } // Fall back to slow tier (disk) if tc.slow != nil { return tc.slow.Open(key) } return nil, vfserror.ErrNotFound } // Delete removes a file from all tiers func (tc *TieredCache) Delete(key string) error { tc.mu.RLock() defer tc.mu.RUnlock() var lastErr error // Delete from fast tier if tc.fast != nil { if err := tc.fast.Delete(key); err != nil { lastErr = err } } // Delete from slow tier if tc.slow != nil { if err := tc.slow.Delete(key); err != nil { lastErr = err } } return lastErr } // Stat returns file information, checking fast tier first func (tc *TieredCache) Stat(key string) (*vfs.FileInfo, error) { tc.mu.RLock() defer tc.mu.RUnlock() // Try fast tier first (memory) if tc.fast != nil { if info, err := tc.fast.Stat(key); err == nil { return info, nil } } // Fall back to slow tier (disk) if tc.slow != nil { return tc.slow.Stat(key) } return nil, vfserror.ErrNotFound } // Name returns the cache name func (tc *TieredCache) Name() string { return "TieredCache" } // Size returns the total size across all tiers func (tc *TieredCache) Size() int64 { tc.mu.RLock() defer tc.mu.RUnlock() var total int64 if tc.fast != nil { total += tc.fast.Size() } if tc.slow != nil { total += tc.slow.Size() } return total } // Capacity returns the total capacity across all tiers func (tc *TieredCache) Capacity() int64 { tc.mu.RLock() defer tc.mu.RUnlock() var total int64 if tc.fast != nil { total += tc.fast.Capacity() } if tc.slow != nil { total += tc.slow.Capacity() } return total }