add import storage and test
This commit is contained in:
+3
-2
@@ -13,6 +13,7 @@ import (
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
ChunkWidth = 16
|
ChunkWidth = 16
|
||||||
|
ChunkColumns = ChunkWidth * ChunkWidth
|
||||||
BlocksPerChunkSection = ChunkWidth * ChunkWidth * ChunkWidth
|
BlocksPerChunkSection = ChunkWidth * ChunkWidth * ChunkWidth
|
||||||
BiomesPerChunkSection = 4 * 4 * 4
|
BiomesPerChunkSection = 4 * 4 * 4
|
||||||
)
|
)
|
||||||
@@ -182,10 +183,10 @@ func UnpackBlockData(r io.Reader) (blocks []int32, err error) {
|
|||||||
|
|
||||||
func PackBlockData(blocks []int32, version string, w io.Writer) (err error) {
|
func PackBlockData(blocks []int32, version string, w io.Writer) (err error) {
|
||||||
unique := util.GetUniqueSlice(blocks)
|
unique := util.GetUniqueSlice(blocks)
|
||||||
bpe := uint8(math.Ceil(math.Log2(float64(len(unique)))))
|
bpe := util.BpeByNum(float64(len(unique)))
|
||||||
|
|
||||||
if bpe > 8 {
|
if bpe > 8 {
|
||||||
bpe = uint8(math.Ceil(math.Log2(float64(len(data.BlocksForVersion(version))))))
|
bpe = util.BpeByNum(float64(len(data.BlocksForVersion(version))))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = binary.Write(w, binary.BigEndian, bpe)
|
err = binary.Write(w, binary.BigEndian, bpe)
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ type Storage[T comparable] struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var CannotGrowPalletErr = errors.New("cannot grow pallet")
|
var CannotGrowPalletErr = errors.New("cannot grow pallet")
|
||||||
|
var CannotGrowPalletNoPossibleBpeErr = errors.New("cannot grow pallet, no possible bpe provided")
|
||||||
|
var Bpe0ButNot1LenPaletteErr = errors.New("bpe 0 but not 1, len palette")
|
||||||
|
var InvalidPaletteIndexErr = errors.New("invalid palette index")
|
||||||
|
|
||||||
func NewStorage[T comparable](len int, possibleBpe []uint8) (s *Storage[T]) {
|
func NewStorage[T comparable](len int, possibleBpe []uint8) (s *Storage[T]) {
|
||||||
s = new(Storage[T])
|
s = new(Storage[T])
|
||||||
@@ -27,6 +30,30 @@ func NewStorage[T comparable](len int, possibleBpe []uint8) (s *Storage[T]) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ImportStorage[T comparable](data []uint64, bpe uint8, palette []T, len int, possibleBpe []uint8) (s *Storage[T], err error) {
|
||||||
|
s = new(Storage[T])
|
||||||
|
s.Resize(bpe)
|
||||||
|
s.Data = data
|
||||||
|
s.Palette = palette
|
||||||
|
s.Len = len
|
||||||
|
s.PossibleBitsPerEntryValues = possibleBpe
|
||||||
|
err = s.CheckData()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Storage[T]) CheckData() (err error) {
|
||||||
|
if s.BitsPerEntry == 0 && len(s.Palette) != 1 {
|
||||||
|
err = Bpe0ButNot1LenPaletteErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := range s.Len {
|
||||||
|
if s.GetLow(i) >= uint32(len(s.Palette)) {
|
||||||
|
err = InvalidPaletteIndexErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
func (s *Storage[T]) Resize(bpe uint8) {
|
func (s *Storage[T]) Resize(bpe uint8) {
|
||||||
if bpe == 0 {
|
if bpe == 0 {
|
||||||
s.Data = nil
|
s.Data = nil
|
||||||
@@ -62,6 +89,11 @@ func (s *Storage[T]) Resize(bpe uint8) {
|
|||||||
func (s *Storage[T]) GrowPallet(v T) (index int, err error) {
|
func (s *Storage[T]) GrowPallet(v T) (index int, err error) {
|
||||||
index = len(s.Palette)
|
index = len(s.Palette)
|
||||||
if index+1 > s.MaxAtCurrentBpe {
|
if index+1 > s.MaxAtCurrentBpe {
|
||||||
|
if s.PossibleBitsPerEntryValues == nil {
|
||||||
|
err = CannotGrowPalletNoPossibleBpeErr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
bpei := slices.Index(s.PossibleBitsPerEntryValues, s.BitsPerEntry)
|
bpei := slices.Index(s.PossibleBitsPerEntryValues, s.BitsPerEntry)
|
||||||
if bpei == len(s.PossibleBitsPerEntryValues)-1 {
|
if bpei == len(s.PossibleBitsPerEntryValues)-1 {
|
||||||
err = CannotGrowPalletErr
|
err = CannotGrowPalletErr
|
||||||
@@ -110,3 +142,11 @@ func (s *Storage[T]) SetLow(i int, v uint32) {
|
|||||||
s.Data[i/s.ElementsPerLong] &= ^(s.Mask << ((i % s.ElementsPerLong) * int(s.BitsPerEntry)))
|
s.Data[i/s.ElementsPerLong] &= ^(s.Mask << ((i % s.ElementsPerLong) * int(s.BitsPerEntry)))
|
||||||
s.Data[i/s.ElementsPerLong] |= uint64(v) << ((i % s.ElementsPerLong) * int(s.BitsPerEntry))
|
s.Data[i/s.ElementsPerLong] |= uint64(v) << ((i % s.ElementsPerLong) * int(s.BitsPerEntry))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Storage[T]) RealValues() []T {
|
||||||
|
ret := make([]T, s.Len)
|
||||||
|
for i := range s.Len {
|
||||||
|
ret[i] = s.Get(i)
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package level_test
|
package level_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/admin-else/strom/level"
|
"github.com/admin-else/strom/level"
|
||||||
|
"github.com/admin-else/strom/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
var possibleBpe = []uint8{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
var possibleBpe = []uint8{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
|
||||||
@@ -133,3 +135,52 @@ func TestResizeElementsPerLong(t *testing.T) {
|
|||||||
t.Errorf("ElementsPerLong = %d, want 16 (Resize stores old ElementsPerLong)", s.ElementsPerLong)
|
t.Errorf("ElementsPerLong = %d, want 16 (Resize stores old ElementsPerLong)", s.ElementsPerLong)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestImportData(t *testing.T) {
|
||||||
|
data := []uint64{
|
||||||
|
2924043581155788451,
|
||||||
|
3014291839833165474,
|
||||||
|
2924008396783439527,
|
||||||
|
3014291770978157730,
|
||||||
|
2905993930227668138,
|
||||||
|
2978157076574191776,
|
||||||
|
2888296810347582631,
|
||||||
|
2941952219986869920,
|
||||||
|
3122589749976320164,
|
||||||
|
2833795322612367018,
|
||||||
|
3086525630071259805,
|
||||||
|
2833830575707083949,
|
||||||
|
3014115504847927964,
|
||||||
|
2851845594302469291,
|
||||||
|
2905958400778123933,
|
||||||
|
3014291839833162913,
|
||||||
|
2815745670742620830,
|
||||||
|
2942057979530264736,
|
||||||
|
2815745670876841123,
|
||||||
|
2887944277684467868,
|
||||||
|
2815745740402934945,
|
||||||
|
2887944277549201564,
|
||||||
|
3032094718851891360,
|
||||||
|
2887908817896552616,
|
||||||
|
2887944277684469920,
|
||||||
|
2869788867884569248,
|
||||||
|
2869894626083422368,
|
||||||
|
2834183176950988960,
|
||||||
|
2869894625949204127,
|
||||||
|
3032376331669946015,
|
||||||
|
2869894694802636456,
|
||||||
|
2996136153003671199,
|
||||||
|
2869929879174992040,
|
||||||
|
2869894625948941983,
|
||||||
|
2887944277684735139,
|
||||||
|
2869894625948941983,
|
||||||
|
22322953887,
|
||||||
|
}
|
||||||
|
n := int32(384 + 1)
|
||||||
|
bpe := util.BpeByNum(float64(n)) // overworld world height
|
||||||
|
s, err := level.ImportStorage[int32](data, bpe, util.SliceRange(0, n), level.ChunkColumns, nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Println(s.RealValues())
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
func FloorDiv(a, b int32) int32 {
|
func FloorDiv(a, b int32) int32 {
|
||||||
return (a - ((a%b + b) % b)) / b
|
return (a - ((a%b + b) % b)) / b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BpeByNum(x float64) uint8 {
|
||||||
|
return uint8(math.Ceil(math.Log2(x)))
|
||||||
|
}
|
||||||
|
|||||||
@@ -65,3 +65,19 @@ func MinSlice[T cmp.Ordered](s []T) (ret T) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Numeric interface {
|
||||||
|
~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
||||||
|
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
|
||||||
|
~float32 | ~float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func SliceRange[T Numeric](s, e T) (ret []T) {
|
||||||
|
if s > e {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for v := s; v < e; v++ {
|
||||||
|
ret = append(ret, v)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user