document for BitStorage
This commit is contained in:
@ -5,6 +5,8 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// BitStorage implement the compacted data array used in chunk storage.
|
||||||
|
// https://wiki.vg/Chunk_Format
|
||||||
// This implement the format since Minecraft 1.16
|
// This implement the format since Minecraft 1.16
|
||||||
type BitStorage struct {
|
type BitStorage struct {
|
||||||
data []uint64
|
data []uint64
|
||||||
@ -14,7 +16,11 @@ type BitStorage struct {
|
|||||||
valuesPerLong int
|
valuesPerLong int
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBitStorage create a new BitStorage, // TODO: document
|
// NewBitStorage create a new BitStorage.
|
||||||
|
// bits is the number of bits per value.
|
||||||
|
// size is the number of values.
|
||||||
|
// arrl is optional data for initializing.
|
||||||
|
// It's length must match the bits and size if it's not nil.
|
||||||
func NewBitStorage(bits, size int, arrl []uint64) (b *BitStorage) {
|
func NewBitStorage(bits, size int, arrl []uint64) (b *BitStorage) {
|
||||||
b = &BitStorage{
|
b = &BitStorage{
|
||||||
mask: 1<<bits - 1,
|
mask: 1<<bits - 1,
|
||||||
@ -25,7 +31,7 @@ func NewBitStorage(bits, size int, arrl []uint64) (b *BitStorage) {
|
|||||||
dataLen := (size + b.valuesPerLong - 1) / b.valuesPerLong
|
dataLen := (size + b.valuesPerLong - 1) / b.valuesPerLong
|
||||||
if arrl != nil {
|
if arrl != nil {
|
||||||
if len(arrl) != dataLen {
|
if len(arrl) != dataLen {
|
||||||
panic(fmt.Errorf("invalid length given for storage, got: %d but expected: %d", len(arrl), dataLen))
|
panic(initBitStorageErr{ArrlLen: len(arrl), WantLen: dataLen})
|
||||||
}
|
}
|
||||||
b.data = arrl
|
b.data = arrl
|
||||||
} else {
|
} else {
|
||||||
@ -34,11 +40,21 @@ func NewBitStorage(bits, size int, arrl []uint64) (b *BitStorage) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type initBitStorageErr struct {
|
||||||
|
ArrlLen int
|
||||||
|
WantLen int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i initBitStorageErr) Error() string {
|
||||||
|
return fmt.Sprintf("invalid length given for storage, got: %d but expected: %d", i.ArrlLen, i.WantLen)
|
||||||
|
}
|
||||||
|
|
||||||
func (b *BitStorage) cellIndex(n int) int {
|
func (b *BitStorage) cellIndex(n int) int {
|
||||||
elemPerLong := 64 / b.bits
|
elemPerLong := 64 / b.bits
|
||||||
return n / elemPerLong
|
return n / elemPerLong
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Swap sets v into [i], and return the previous [i] value.
|
||||||
func (b *BitStorage) Swap(i, v int) (old int) {
|
func (b *BitStorage) Swap(i, v int) (old int) {
|
||||||
if i < 0 || i > b.size-1 ||
|
if i < 0 || i > b.size-1 ||
|
||||||
v < 0 || uint64(v) > b.mask {
|
v < 0 || uint64(v) > b.mask {
|
||||||
@ -52,6 +68,7 @@ func (b *BitStorage) Swap(i, v int) (old int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set sets v into [i]
|
||||||
func (b *BitStorage) Set(i, v int) {
|
func (b *BitStorage) Set(i, v int) {
|
||||||
if i < 0 || i > b.size-1 ||
|
if i < 0 || i > b.size-1 ||
|
||||||
v < 0 || uint64(v) > b.mask {
|
v < 0 || uint64(v) > b.mask {
|
||||||
@ -63,6 +80,7 @@ func (b *BitStorage) Set(i, v int) {
|
|||||||
b.data[c] = l&(b.mask<<offset^math.MaxUint64) | (uint64(v)&b.mask)<<offset
|
b.data[c] = l&(b.mask<<offset^math.MaxUint64) | (uint64(v)&b.mask)<<offset
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get gets [i] value.
|
||||||
func (b *BitStorage) Get(i int) int {
|
func (b *BitStorage) Get(i int) int {
|
||||||
if i < 0 || i > b.size-1 {
|
if i < 0 || i > b.size-1 {
|
||||||
panic("out of bounds")
|
panic("out of bounds")
|
||||||
|
Reference in New Issue
Block a user