feat: Finished testing Unity files and got retrieval working

This commit is contained in:
Nicholas Novak 2023-12-11 09:22:50 -08:00
parent 5c4ee2bc2e
commit e0f1cd2436
3 changed files with 137 additions and 6 deletions

View File

@ -3,6 +3,7 @@ package storage
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"io"
"os" "os"
"git.nicholasnovak.io/nnovak/spatial-db/world" "git.nicholasnovak.io/nnovak/spatial-db/world"
@ -16,7 +17,12 @@ type UnityFile struct {
fd *os.File fd *os.File
fileSize int fileSize int
// metadata maps the position of a chunk to its start index within the file // metadata maps the position of a chunk to its start index within the file
metadata map[world.ChunkPos]int metadata map[world.ChunkPos]fileMetadata
}
type fileMetadata struct {
startOffset int
fileSize int
} }
func CreateUnityFile(fileName string) (UnityFile, error) { func CreateUnityFile(fileName string) (UnityFile, error) {
@ -28,7 +34,7 @@ func CreateUnityFile(fileName string) (UnityFile, error) {
} }
u.fd = f u.fd = f
u.metadata = make(map[world.ChunkPos]int) u.metadata = make(map[world.ChunkPos]fileMetadata)
return u, nil return u, nil
} }
@ -55,7 +61,10 @@ func (u *UnityFile) WriteChunk(data world.ChunkData) error {
} }
// Update the metadata with the new file // Update the metadata with the new file
u.metadata[data.Pos] = u.fileSize u.metadata[data.Pos] = fileMetadata{
startOffset: u.fileSize,
fileSize: encodedSize,
}
u.fileSize += encodedSize u.fileSize += encodedSize
return nil return nil
@ -88,6 +97,17 @@ func (u *UnityFile) ReadMetadataFile(fileName string) error {
return nil return nil
} }
func (u UnityFile) ReadChunk() world.ChunkData { func (u UnityFile) ReadChunk(pos world.ChunkPos) (world.ChunkData, error) {
return world.ChunkData{} m := u.metadata[pos]
u.fd.Seek(0, m.startOffset)
fileReader := io.LimitReader(u.fd, int64(m.fileSize))
var data world.ChunkData
if err := json.NewDecoder(fileReader).Decode(&data); err != nil {
return world.ChunkData{}, err
}
return data, nil
} }

View File

@ -3,7 +3,10 @@ package storage
import ( import (
"os" "os"
"path" "path"
"reflect"
"testing" "testing"
"git.nicholasnovak.io/nnovak/spatial-db/world"
) )
func TestCreateUnityFile(t *testing.T) { func TestCreateUnityFile(t *testing.T) {
@ -28,3 +31,91 @@ func TestCreateUnityFile(t *testing.T) {
t.Fatalf("Got an error saving the empty metadata: %v", err) t.Fatalf("Got an error saving the empty metadata: %v", err)
} }
} }
func TestWriteSingleFile(t *testing.T) {
tempDir, err := os.MkdirTemp("", "unity")
if err != nil {
t.Fatalf("Error creating temporary directory: %v", err)
}
defer os.RemoveAll(tempDir)
u, err := CreateUnityFile(path.Join(tempDir, "test-unity"))
if err != nil {
t.Fatalf("Error creating unity file: %v", err)
}
// Write a single file
var data world.ChunkData
data.Sections[0].BlockStates[0] = 2
if err := u.WriteChunk(data); err != nil {
t.Fatalf("Error writing chunk: %v", err)
}
// Read the chunk back
readChunk, err := u.ReadChunk(data.Pos)
if err != nil {
t.Fatalf("Error reading chunk: %v", err)
}
// Compare the chunks directly
if !reflect.DeepEqual(data, readChunk) {
t.Fatalf("Chunks differed, sent %v, received %v", data, readChunk)
}
}
func TestWriteMultipleFiles(t *testing.T) {
tempDir, err := os.MkdirTemp("", "unity")
if err != nil {
t.Fatalf("Error creating temporary directory: %v", err)
}
defer os.RemoveAll(tempDir)
u, err := CreateUnityFile(path.Join(tempDir, "test-unity"))
if err != nil {
t.Fatalf("Error creating unity file: %v", err)
}
var (
chunk1 world.ChunkData
chunk2 world.ChunkData
chunk3 world.ChunkData
)
chunk1.Pos = world.ChunkPos{
X: 0,
Z: 0,
}
chunk1.Sections[0].BlockStates[0] = 2
chunk2.Sections[0].BlockStates[0] = 3
chunk2.Pos = world.ChunkPos{
X: 1,
Z: 0,
}
chunk3.Sections[0].BlockStates[0] = 4
chunk3.Pos = world.ChunkPos{
X: 2,
Z: 0,
}
chunks := []world.ChunkData{chunk1, chunk2, chunk3}
// Write all chunks
for _, data := range chunks {
if err := u.WriteChunk(data); err != nil {
t.Fatalf("Error writing chunk: %v", err)
}
}
// Read the chunks back
for _, data := range chunks {
readChunk, err := u.ReadChunk(data.Pos)
if err != nil {
t.Fatalf("Error reading chunk: %v", err)
}
// Compare the chunks directly
if !reflect.DeepEqual(data, readChunk) {
t.Fatalf("Chunks differed, sent %v, received %v", data, readChunk)
}
}
}

View File

@ -3,6 +3,8 @@ package world
import ( import (
"fmt" "fmt"
"math/rand" "math/rand"
"strconv"
"strings"
) )
type BlockPos struct { type BlockPos struct {
@ -36,7 +38,25 @@ type ChunkPos struct {
} }
func (cp ChunkPos) MarshalText() ([]byte, error) { func (cp ChunkPos) MarshalText() ([]byte, error) {
return []byte(fmt.Sprintf("%d %d", cp.Z, cp.Z)), nil return []byte(fmt.Sprintf("%d %d", cp.X, cp.Z)), nil
}
func (cp *ChunkPos) UnmarshalText(text []byte) error {
words := strings.Split(string(text), " ")
x, err := strconv.Atoi(words[0])
if err != nil {
return err
}
z, err := strconv.Atoi(words[1])
if err != nil {
return err
}
cp.X = x
cp.Z = z
return nil
} }
func (cp ChunkPos) ToFileName() string { func (cp ChunkPos) ToFileName() string {