summaryrefslogtreecommitdiff
path: root/region_cached.go
diff options
context:
space:
mode:
Diffstat (limited to 'region_cached.go')
-rw-r--r--region_cached.go78
1 files changed, 78 insertions, 0 deletions
diff --git a/region_cached.go b/region_cached.go
new file mode 100644
index 0000000..66cea16
--- /dev/null
+++ b/region_cached.go
@@ -0,0 +1,78 @@
+package main
+
+import (
+ "errors"
+ "fmt"
+ "github.com/kch42/gomcmap/mcmap"
+)
+
+type CachedRegion struct {
+ Region *mcmap.Region
+ cacheChunks []*mcmap.Chunk
+ cachePos []XZPos
+ cachesize int
+}
+
+func NewCachedRegion(reg *mcmap.Region, cachesize int) *CachedRegion {
+ if cachesize <= 0 {
+ panic(errors.New("Cachesize must be >0"))
+ }
+ return &CachedRegion{
+ Region: reg,
+ cacheChunks: make([]*mcmap.Chunk, cachesize),
+ cachePos: make([]XZPos, cachesize),
+ cachesize: cachesize,
+ }
+}
+
+func (cr *CachedRegion) Chunk(x, z int) (*mcmap.Chunk, error) {
+ pos := XZPos{x, z}
+
+ for i, p := range cr.cachePos {
+ if p == pos {
+ if cr.cacheChunks[i] != nil {
+ chunk := cr.cacheChunks[i]
+ for j := i; j >= 1; j-- {
+ cr.cacheChunks[j] = cr.cacheChunks[j-1]
+ cr.cachePos[j] = cr.cachePos[j-1]
+ }
+ return chunk, nil
+ }
+ }
+ }
+
+ chunk, err := cr.Region.Chunk(x, z)
+ if err != nil {
+ return nil, err
+ }
+
+ if cr.cacheChunks[cr.cachesize-1] != nil {
+ if err := cr.cacheChunks[cr.cachesize-1].MarkUnused(); err != nil {
+ return nil, fmt.Errorf("Could not remove oldest cache element: %s", err)
+ }
+ }
+
+ for i := cr.cachesize - 1; i >= 1; i-- {
+ cr.cacheChunks[i] = cr.cacheChunks[i-1]
+ cr.cachePos[i] = cr.cachePos[i-1]
+ }
+ cr.cacheChunks[0] = chunk
+ cr.cachePos[0] = pos
+
+ return chunk, nil
+}
+
+func (cr *CachedRegion) Flush() error {
+ for i, chunk := range cr.cacheChunks {
+ if chunk == nil {
+ continue
+ }
+
+ if err := chunk.MarkUnused(); err != nil {
+ return err
+ }
+ cr.cacheChunks[i] = nil
+ }
+
+ return nil
+}