change: Finished benchmarking and some more features
This commit is contained in:
@@ -3,6 +3,7 @@ package storage
|
||||
import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// A `FileCache` stores open file descriptors for all files that have been
|
||||
@@ -12,6 +13,8 @@ type FileCache struct {
|
||||
fileNames map[string]int
|
||||
indexesOfFiles map[int]string
|
||||
files []*os.File
|
||||
|
||||
randSource *rand.Rand
|
||||
}
|
||||
|
||||
func NewFileCache(cacheSize int) FileCache {
|
||||
@@ -22,6 +25,8 @@ func NewFileCache(cacheSize int) FileCache {
|
||||
c.indexesOfFiles = make(map[int]string)
|
||||
c.files = make([]*os.File, cacheSize)
|
||||
|
||||
c.randSource = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -36,8 +41,13 @@ func (fc *FileCache) FetchFile(fileName string) (*os.File, error) {
|
||||
|
||||
// The file was not in the cache, try and insert it
|
||||
|
||||
f, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Random cache eviction
|
||||
indexToRemove := rand.Intn(fc.cacheSize)
|
||||
indexToRemove := fc.randSource.Intn(fc.cacheSize)
|
||||
|
||||
// Remove the old value
|
||||
oldName, present := fc.indexesOfFiles[indexToRemove]
|
||||
@@ -48,11 +58,6 @@ func (fc *FileCache) FetchFile(fileName string) (*os.File, error) {
|
||||
delete(fc.indexesOfFiles, indexToRemove)
|
||||
}
|
||||
|
||||
f, err := os.Open(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Insert the new value
|
||||
fc.files[indexToRemove] = f
|
||||
fc.fileNames[fileName] = indexToRemove
|
||||
|
||||
@@ -69,7 +69,7 @@ func (hs *HashServer) ChangeBlockRange(
|
||||
}
|
||||
|
||||
func (hs *HashServer) ReadBlockAt(pos world.BlockPos) (world.BlockID, error) {
|
||||
panic("Unimplemented")
|
||||
return hs.blocks[pos], nil
|
||||
}
|
||||
|
||||
func (hs *HashServer) ReadChunkAt(pos world.ChunkPos) (world.ChunkData, error) {
|
||||
|
||||
@@ -18,10 +18,12 @@ var (
|
||||
|
||||
type SimpleServer struct {
|
||||
StorageDir string
|
||||
cache FileCache
|
||||
}
|
||||
|
||||
func (s *SimpleServer) SetStorageRoot(path string) {
|
||||
s.StorageDir = path
|
||||
s.cache = NewFileCache(256)
|
||||
}
|
||||
|
||||
// Filesystem operations
|
||||
@@ -57,12 +59,13 @@ func (s *SimpleServer) FetchOrCreateChunk(pos world.ChunkPos) (world.ChunkData,
|
||||
return ReadChunkFromFile(chunkFile)
|
||||
}
|
||||
|
||||
// `FetchChunk' fetches the chunk's data, given the chunk's position
|
||||
func (s *SimpleServer) FetchChunk(pos world.ChunkPos) (world.ChunkData, error) {
|
||||
chunkFileName := filepath.Join(s.StorageDir, pos.ToFileName())
|
||||
|
||||
var chunkData world.ChunkData
|
||||
|
||||
chunkFile, err := os.Open(chunkFileName)
|
||||
chunkFile, err := s.cache.FetchFile(chunkFileName)
|
||||
if err != nil {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
return chunkData, ChunkNotFoundError
|
||||
@@ -70,7 +73,6 @@ func (s *SimpleServer) FetchChunk(pos world.ChunkPos) (world.ChunkData, error) {
|
||||
return chunkData, err
|
||||
}
|
||||
}
|
||||
defer chunkFile.Close()
|
||||
|
||||
return ReadChunkFromFile(chunkFile)
|
||||
}
|
||||
@@ -99,7 +101,7 @@ func (s *SimpleServer) ChangeBlockRange(
|
||||
}
|
||||
|
||||
func (s *SimpleServer) ReadBlockAt(pos world.BlockPos) (world.BlockID, error) {
|
||||
chunk, err := s.FetchOrCreateChunk(pos.ToChunkPos())
|
||||
chunk, err := s.FetchChunk(pos.ToChunkPos())
|
||||
if err != nil {
|
||||
return world.Empty, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user