add import storage and test

This commit is contained in:
adman
2026-04-23 22:36:34 +02:00
parent 841d91b91d
commit bd3139754d
5 changed files with 116 additions and 2 deletions
+3 -2
View File
@@ -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)
+40
View File
@@ -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
}
+51
View File
@@ -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())
}
+6
View File
@@ -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)))
}
+16
View File
@@ -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
}