refactor shit
This commit is contained in:
@@ -1,219 +0,0 @@
|
||||
package level
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"math"
|
||||
"slices"
|
||||
)
|
||||
|
||||
type DynamicPalletLookup[T comparable] interface {
|
||||
GetIndex(T) uint32
|
||||
GetT(uint33 uint32) T
|
||||
Resize(storage *Storage[T]) error
|
||||
}
|
||||
|
||||
type Storage[T comparable] struct {
|
||||
Palette []T
|
||||
CustomPallet DynamicPalletLookup[T]
|
||||
Data []uint64
|
||||
PossibleBitsPerEntryValues []uint8 // These should be sorted
|
||||
BitsPerEntry uint8
|
||||
Len int
|
||||
MaxAtCurrentBpe int
|
||||
ElementsPerLong int
|
||||
Mask uint64
|
||||
}
|
||||
|
||||
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]) {
|
||||
s = new(Storage[T])
|
||||
s.Len = len
|
||||
s.PossibleBitsPerEntryValues = possibleBpe
|
||||
s.Resize(possibleBpe[0])
|
||||
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 ImportStoragePaletteFunc[T comparable](data []uint64, bpe uint8, paletteF DynamicPalletLookup[T], len int, possibleBpe []uint8) (s *Storage[T], err error) {
|
||||
s = new(Storage[T])
|
||||
s.Resize(bpe)
|
||||
s.Data = data
|
||||
s.CustomPallet = paletteF
|
||||
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) {
|
||||
if bpe == 0 {
|
||||
s.Data = nil
|
||||
s.BitsPerEntry = 0
|
||||
s.ElementsPerLong = 0
|
||||
s.Mask = 0
|
||||
s.MaxAtCurrentBpe = 1
|
||||
return
|
||||
}
|
||||
elementsPerLong := int(64 / int(bpe))
|
||||
numberOfLongs := int(math.Ceil(float64(s.Len) / float64(elementsPerLong)))
|
||||
newData := make([]uint64, numberOfLongs)
|
||||
if s.BitsPerEntry == 0 {
|
||||
s.Data = newData
|
||||
s.BitsPerEntry = bpe
|
||||
s.ElementsPerLong = elementsPerLong
|
||||
s.Mask = (uint64(1) << uint32(bpe)) - 1
|
||||
s.MaxAtCurrentBpe = 1 << s.BitsPerEntry
|
||||
return
|
||||
}
|
||||
for i := range s.Len {
|
||||
v := s.GetLow(i)
|
||||
newData[i/elementsPerLong] |= uint64(v) << ((i % elementsPerLong) * int(bpe))
|
||||
}
|
||||
s.Data = newData
|
||||
s.BitsPerEntry = bpe
|
||||
s.ElementsPerLong = elementsPerLong
|
||||
s.Mask = (uint64(1) << uint32(bpe)) - 1
|
||||
s.MaxAtCurrentBpe = 1 << s.BitsPerEntry
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Storage[T]) GrowPallet(v T) (index int, err error) {
|
||||
index = len(s.Palette)
|
||||
if index+1 > s.MaxAtCurrentBpe {
|
||||
if s.PossibleBitsPerEntryValues == nil {
|
||||
err = CannotGrowPalletNoPossibleBpeErr
|
||||
return
|
||||
}
|
||||
|
||||
bpei := slices.Index(s.PossibleBitsPerEntryValues, s.BitsPerEntry)
|
||||
if bpei == len(s.PossibleBitsPerEntryValues)-1 {
|
||||
err = CannotGrowPalletErr
|
||||
return
|
||||
}
|
||||
newBpe := s.PossibleBitsPerEntryValues[bpei+1]
|
||||
s.Resize(newBpe)
|
||||
}
|
||||
s.Palette = append(s.Palette, v)
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Storage[T]) Set(i int, v T) (err error) {
|
||||
pi := slices.Index(s.Palette, v)
|
||||
if pi != -1 {
|
||||
if s.BitsPerEntry == 0 {
|
||||
return
|
||||
}
|
||||
s.SetLow(i, uint32(pi))
|
||||
return
|
||||
}
|
||||
pi, err = s.GrowPallet(v)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s.SetLow(i, uint32(pi))
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Storage[T]) Get(i int) (v T) {
|
||||
if s.BitsPerEntry == 0 {
|
||||
return s.Palette[0]
|
||||
}
|
||||
return s.Palette[s.GetLow(i)]
|
||||
}
|
||||
|
||||
func (s *Storage[T]) GetLow(i int) (j uint32) {
|
||||
j = uint32((s.Data[i/s.ElementsPerLong] >> ((i % s.ElementsPerLong) * int(s.BitsPerEntry))) & s.Mask)
|
||||
return
|
||||
}
|
||||
|
||||
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] |= 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
|
||||
}
|
||||
|
||||
func (s *Storage[T]) SetMany(i, j int, v T) (err error) {
|
||||
if i == 0 && j == s.Len-1 && slices.Contains(s.PossibleBitsPerEntryValues, 0) {
|
||||
s.Resize(0)
|
||||
s.Palette = []T{v}
|
||||
return
|
||||
}
|
||||
pi := slices.Index(s.Palette, v)
|
||||
if pi != -1 {
|
||||
if s.BitsPerEntry == 0 {
|
||||
return
|
||||
}
|
||||
s.SetLow(i, uint32(pi))
|
||||
return
|
||||
}
|
||||
pi, err = s.GrowPallet(v)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
s.SetManyLow(i, j, uint32(pi))
|
||||
return
|
||||
}
|
||||
|
||||
func (s *Storage[T]) SetManyLow(i, j int, v uint32) {
|
||||
n := j - i
|
||||
if n > s.ElementsPerLong*2 {
|
||||
for k := i; k < j; k++ {
|
||||
s.SetLow(k, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
for i%s.ElementsPerLong == 0 {
|
||||
s.SetLow(i, v)
|
||||
i++
|
||||
}
|
||||
|
||||
var vFilled uint64
|
||||
for k := range s.ElementsPerLong {
|
||||
vFilled |= uint64(v) << (k * int(s.BitsPerEntry))
|
||||
}
|
||||
|
||||
t := i / s.ElementsPerLong
|
||||
for k := range (j - i) / s.ElementsPerLong {
|
||||
s.Data[t+k] = vFilled
|
||||
}
|
||||
|
||||
for j%s.ElementsPerLong != 0 {
|
||||
s.SetLow(j, v)
|
||||
j--
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user