fix PaletteContainer bug

This commit is contained in:
Tnze
2022-11-20 23:21:53 +08:00
parent da56ec88d5
commit 65d3a2687a
2 changed files with 54 additions and 18 deletions

View File

@ -1,11 +1,12 @@
package level package level
import ( import (
"github.com/Tnze/go-mc/level/block"
pk "github.com/Tnze/go-mc/net/packet"
"io" "io"
"math/bits" "math/bits"
"strconv" "strconv"
"github.com/Tnze/go-mc/level/block"
pk "github.com/Tnze/go-mc/net/packet"
) )
type State interface { type State interface {
@ -102,30 +103,25 @@ func (p *PaletteContainer[T]) Set(i int, v T) {
if vv, ok := p.palette.id(v); ok { if vv, ok := p.palette.id(v); ok {
p.data.Set(i, vv) p.data.Set(i, vv)
} else { } else {
length := p.data.Len()
// resize // resize
oldLen := p.data.Len() newContainer := PaletteContainer[T]{
newPalette := PaletteContainer[T]{
bits: vv, bits: vv,
config: p.config, config: p.config,
palette: p.config.create(vv), palette: p.config.create(vv),
data: NewBitStorage(p.config.bits(vv), oldLen, nil), data: NewBitStorage(p.config.bits(vv), length, nil),
} }
// copy // copy
for i := 0; i < oldLen; i++ { for i := 0; i < length; i++ {
raw := p.data.Get(i) newContainer.Set(i, p.Get(i))
if vv, ok := newPalette.palette.id(T(raw)); !ok {
panic("not reachable")
} else {
newPalette.data.Set(i, vv)
}
} }
if vv, ok := newPalette.palette.id(v); !ok { if vv, ok := newContainer.palette.id(v); !ok {
panic("not reachable") panic("not reachable")
} else { } else {
newPalette.data.Set(i, vv) newContainer.data.Set(i, vv)
} }
*p = newPalette *p = newContainer
} }
} }

View File

@ -1,12 +1,14 @@
package level package level
import ( import (
"math/rand"
"testing" "testing"
"github.com/Tnze/go-mc/level/block"
) )
func TestPaletteResize(t *testing.T) { func TestPaletteContainer_seq(t *testing.T) {
container := NewStatesPaletteContainer(16*16*16, 0) container := NewStatesPaletteContainer(4096, 0)
for i := 0; i < 4096; i++ { for i := 0; i < 4096; i++ {
container.Set(i, BlocksState(i)) container.Set(i, BlocksState(i))
} }
@ -16,3 +18,41 @@ func TestPaletteResize(t *testing.T) {
} }
} }
} }
func TestPaletteContainer_rand(t *testing.T) {
data := make([]BlocksState, 4096)
for i := range data {
data[i] = BlocksState(rand.Intn(1 << block.BitsPerBlock))
}
container := NewStatesPaletteContainer(4096, 0)
for i, v := range data {
container.Set(i, v)
}
for i, v := range data {
if v2 := container.Get(i); v != v2 {
t.Errorf("value not match: got %v, except: %v", v2, v)
}
}
}
func BenchmarkPaletteContainer(b *testing.B) {
data := make([]BlocksState, 4096)
for i := range data {
data[i] = BlocksState(rand.Intn(1 << block.BitsPerBlock))
}
rand.Shuffle(len(data), func(i, j int) { data[i], data[j] = data[j], data[i] })
container := NewStatesPaletteContainer(4096, 0)
b.ResetTimer()
b.Run("Set", func(b *testing.B) {
for i := 0; i < b.N; i++ {
index := i % 4096
container.Set(index, data[index])
}
})
b.Run("Get", func(b *testing.B) {
for i := 0; i < b.N; i++ {
index := i % 4096
container.Get(index)
}
})
}