change: Finished benchmarking and some more features
This commit is contained in:
parent
93c7564c43
commit
2f4303ddb8
8
Makefile
8
Makefile
@ -16,9 +16,13 @@ witchcraft-save:
|
|||||||
mkdir witchcraft-save
|
mkdir witchcraft-save
|
||||||
./spatial-db load worldsave "saves/Witchcraft/region" --output "witchcraft-save"
|
./spatial-db load worldsave "saves/Witchcraft/region" --output "witchcraft-save"
|
||||||
|
|
||||||
|
.PHONY: compile
|
||||||
|
compile:
|
||||||
|
CC=clang go build .
|
||||||
|
|
||||||
.PHONY: bench
|
.PHONY: bench
|
||||||
bench:
|
bench: compile
|
||||||
go test -bench . -benchtime=10s -count 10
|
CC=clang go test -bench . -benchtime=2s -count 10
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
|
@ -2,13 +2,14 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.nicholasnovak.io/nnovak/spatial-db/storage"
|
"git.nicholasnovak.io/nnovak/spatial-db/storage"
|
||||||
"git.nicholasnovak.io/nnovak/spatial-db/world"
|
"git.nicholasnovak.io/nnovak/spatial-db/world"
|
||||||
)
|
)
|
||||||
|
|
||||||
var server storage.SimpleServer
|
var server storage.InMemoryServer
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
server.SetStorageRoot("skygrid-save")
|
server.SetStorageRoot("skygrid-save")
|
||||||
@ -20,7 +21,7 @@ func readBlockTemplate(rootDir string, b *testing.B, pointSpread int) {
|
|||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
pos := world.RandomBlockPosWithRange(float64(pointSpread))
|
pos := world.RandomBlockPosWithRange(float64(pointSpread))
|
||||||
if _, err := server.ReadBlockAt(pos); err != nil {
|
if _, err := server.ReadBlockAt(pos); err != nil {
|
||||||
if errors.Is(err, storage.ChunkNotFoundError) {
|
if errors.Is(err, storage.ChunkNotFoundError) || errors.Is(err, io.EOF) {
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
b.Error(err)
|
b.Error(err)
|
||||||
@ -49,3 +50,7 @@ func BenchmarkReadClusteredPoints(b *testing.B) {
|
|||||||
func BenchmarkReadSparserPoints(b *testing.B) {
|
func BenchmarkReadSparserPoints(b *testing.B) {
|
||||||
readBlockTemplate("skygrid-test", b, 2048)
|
readBlockTemplate("skygrid-test", b, 2048)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkReadSparserPoints1(b *testing.B) {
|
||||||
|
readBlockTemplate("skygrid-test", b, 65536)
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ package storage
|
|||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A `FileCache` stores open file descriptors for all files that have been
|
// A `FileCache` stores open file descriptors for all files that have been
|
||||||
@ -12,6 +13,8 @@ type FileCache struct {
|
|||||||
fileNames map[string]int
|
fileNames map[string]int
|
||||||
indexesOfFiles map[int]string
|
indexesOfFiles map[int]string
|
||||||
files []*os.File
|
files []*os.File
|
||||||
|
|
||||||
|
randSource *rand.Rand
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFileCache(cacheSize int) FileCache {
|
func NewFileCache(cacheSize int) FileCache {
|
||||||
@ -22,6 +25,8 @@ func NewFileCache(cacheSize int) FileCache {
|
|||||||
c.indexesOfFiles = make(map[int]string)
|
c.indexesOfFiles = make(map[int]string)
|
||||||
c.files = make([]*os.File, cacheSize)
|
c.files = make([]*os.File, cacheSize)
|
||||||
|
|
||||||
|
c.randSource = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
|
||||||
return c
|
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
|
// 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
|
// Random cache eviction
|
||||||
indexToRemove := rand.Intn(fc.cacheSize)
|
indexToRemove := fc.randSource.Intn(fc.cacheSize)
|
||||||
|
|
||||||
// Remove the old value
|
// Remove the old value
|
||||||
oldName, present := fc.indexesOfFiles[indexToRemove]
|
oldName, present := fc.indexesOfFiles[indexToRemove]
|
||||||
@ -48,11 +58,6 @@ func (fc *FileCache) FetchFile(fileName string) (*os.File, error) {
|
|||||||
delete(fc.indexesOfFiles, indexToRemove)
|
delete(fc.indexesOfFiles, indexToRemove)
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Open(fileName)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert the new value
|
// Insert the new value
|
||||||
fc.files[indexToRemove] = f
|
fc.files[indexToRemove] = f
|
||||||
fc.fileNames[fileName] = indexToRemove
|
fc.fileNames[fileName] = indexToRemove
|
||||||
|
@ -69,7 +69,7 @@ func (hs *HashServer) ChangeBlockRange(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (hs *HashServer) ReadBlockAt(pos world.BlockPos) (world.BlockID, error) {
|
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) {
|
func (hs *HashServer) ReadChunkAt(pos world.ChunkPos) (world.ChunkData, error) {
|
||||||
|
@ -18,10 +18,12 @@ var (
|
|||||||
|
|
||||||
type SimpleServer struct {
|
type SimpleServer struct {
|
||||||
StorageDir string
|
StorageDir string
|
||||||
|
cache FileCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SimpleServer) SetStorageRoot(path string) {
|
func (s *SimpleServer) SetStorageRoot(path string) {
|
||||||
s.StorageDir = path
|
s.StorageDir = path
|
||||||
|
s.cache = NewFileCache(256)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filesystem operations
|
// Filesystem operations
|
||||||
@ -57,12 +59,13 @@ func (s *SimpleServer) FetchOrCreateChunk(pos world.ChunkPos) (world.ChunkData,
|
|||||||
return ReadChunkFromFile(chunkFile)
|
return ReadChunkFromFile(chunkFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// `FetchChunk' fetches the chunk's data, given the chunk's position
|
||||||
func (s *SimpleServer) FetchChunk(pos world.ChunkPos) (world.ChunkData, error) {
|
func (s *SimpleServer) FetchChunk(pos world.ChunkPos) (world.ChunkData, error) {
|
||||||
chunkFileName := filepath.Join(s.StorageDir, pos.ToFileName())
|
chunkFileName := filepath.Join(s.StorageDir, pos.ToFileName())
|
||||||
|
|
||||||
var chunkData world.ChunkData
|
var chunkData world.ChunkData
|
||||||
|
|
||||||
chunkFile, err := os.Open(chunkFileName)
|
chunkFile, err := s.cache.FetchFile(chunkFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, fs.ErrNotExist) {
|
if errors.Is(err, fs.ErrNotExist) {
|
||||||
return chunkData, ChunkNotFoundError
|
return chunkData, ChunkNotFoundError
|
||||||
@ -70,7 +73,6 @@ func (s *SimpleServer) FetchChunk(pos world.ChunkPos) (world.ChunkData, error) {
|
|||||||
return chunkData, err
|
return chunkData, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defer chunkFile.Close()
|
|
||||||
|
|
||||||
return ReadChunkFromFile(chunkFile)
|
return ReadChunkFromFile(chunkFile)
|
||||||
}
|
}
|
||||||
@ -99,7 +101,7 @@ func (s *SimpleServer) ChangeBlockRange(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *SimpleServer) ReadBlockAt(pos world.BlockPos) (world.BlockID, error) {
|
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 {
|
if err != nil {
|
||||||
return world.Empty, err
|
return world.Empty, err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user