This commit is contained in:
2025-01-21 11:52:04 -06:00
parent 2be7b117ea
commit 16dce1f0c2
26 changed files with 1602 additions and 405 deletions

133
vfs/memory/memory.go Normal file
View File

@@ -0,0 +1,133 @@
package memory
import (
"s1d3sw1ped/SteamCache2/vfs"
"s1d3sw1ped/SteamCache2/vfs/vfserror"
"sync"
"time"
)
// Ensure MemoryFS implements VFS.
var _ vfs.VFS = (*MemoryFS)(nil)
// file represents a file in memory.
type file struct {
fileinfo *vfs.FileInfo
data []byte
}
// MemoryFS is a virtual file system that stores files in memory.
type MemoryFS struct {
files map[string]*file
capacity int64
mu sync.Mutex
}
// New creates a new MemoryFS.
func New(capacity int64) *MemoryFS {
return &MemoryFS{
files: make(map[string]*file),
capacity: capacity,
mu: sync.Mutex{},
}
}
func (m *MemoryFS) Capacity() int64 {
return m.capacity
}
func (m *MemoryFS) Name() string {
return "MemoryFS"
}
func (m *MemoryFS) Size() int64 {
var size int64
m.mu.Lock()
defer m.mu.Unlock()
for _, v := range m.files {
size += int64(len(v.data))
}
return size
}
func (m *MemoryFS) Set(key string, src []byte) error {
if m.capacity > 0 {
if size := m.Size() + int64(len(src)); size > m.capacity {
return vfserror.ErrDiskFull
}
}
m.mu.Lock()
defer m.mu.Unlock()
m.files[key] = &file{
fileinfo: vfs.NewFileInfo(
key,
int64(len(src)),
time.Now(),
),
data: make([]byte, len(src)),
}
copy(m.files[key].data, src)
return nil
}
func (m *MemoryFS) Delete(key string) error {
_, err := m.Stat(key)
if err != nil {
return err
}
m.mu.Lock()
defer m.mu.Unlock()
delete(m.files, key)
return nil
}
func (m *MemoryFS) Get(key string) ([]byte, error) {
_, err := m.Stat(key)
if err != nil {
return nil, err
}
m.mu.Lock()
defer m.mu.Unlock()
m.files[key].fileinfo.ATime = time.Now()
dst := make([]byte, len(m.files[key].data))
copy(dst, m.files[key].data)
return dst, nil
}
func (m *MemoryFS) Stat(key string) (*vfs.FileInfo, error) {
m.mu.Lock()
defer m.mu.Unlock()
f, ok := m.files[key]
if !ok {
return nil, vfserror.ErrNotFound
}
return f.fileinfo, nil
}
func (m *MemoryFS) StatAll() []*vfs.FileInfo {
m.mu.Lock()
defer m.mu.Unlock()
// hard copy the file info to prevent modification of the original file info or the other way around
files := make([]*vfs.FileInfo, 0, len(m.files))
for _, v := range m.files {
fi := *v.fileinfo
files = append(files, &fi)
}
return files
}

63
vfs/memory/memory_test.go Normal file
View File

@@ -0,0 +1,63 @@
package memory
import (
"fmt"
"s1d3sw1ped/SteamCache2/vfs/vfserror"
"testing"
)
func TestAllMemory(t *testing.T) {
t.Parallel()
m := New(1024)
if err := m.Set("key", []byte("value")); err != nil {
t.Errorf("Set failed: %v", err)
}
if err := m.Set("key", []byte("value1")); err != nil {
t.Errorf("Set failed: %v", err)
}
if d, err := m.Get("key"); err != nil {
t.Errorf("Get failed: %v", err)
} else if string(d) != "value1" {
t.Errorf("Get failed: got %s, want %s", d, "value1")
}
if err := m.Delete("key"); err != nil {
t.Errorf("Delete failed: %v", err)
}
if _, err := m.Get("key"); err == nil {
t.Errorf("Get failed: got nil, want %v", vfserror.ErrNotFound)
}
if err := m.Delete("key"); err == nil {
t.Errorf("Delete failed: got nil, want %v", vfserror.ErrNotFound)
}
if _, err := m.Stat("key"); err == nil {
t.Errorf("Stat failed: got nil, want %v", vfserror.ErrNotFound)
}
if err := m.Set("key", []byte("value")); err != nil {
t.Errorf("Set failed: %v", err)
}
if _, err := m.Stat("key"); err != nil {
t.Errorf("Stat failed: %v", err)
}
}
func TestLimited(t *testing.T) {
t.Parallel()
m := New(10)
for i := 0; i < 11; i++ {
if err := m.Set(fmt.Sprintf("key%d", i), []byte("1")); err != nil && i < 10 {
t.Errorf("Set failed: %v", err)
} else if i == 10 && err == nil {
t.Errorf("Set succeeded: got nil, want %v", vfserror.ErrDiskFull)
}
}
}