initial commit
This commit is contained in:
133
vfs/memory/memory.go
Normal file
133
vfs/memory/memory.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user