dt_automate/vendor/github.com/Andrew-M-C/go.jsonvalue/jsonvalue_internal.go
2025-02-27 10:48:32 +08:00

113 lines
2.1 KiB
Go

package jsonvalue
import (
"encoding"
"encoding/base64"
"encoding/json"
"reflect"
"sync/atomic"
)
var internal = struct {
b64 *base64.Encoding
defaultMarshalOption *Opt
predict struct {
bytesPerValue uint64
calcStorage uint64 // upper 32 bits - size; lower 32 bits - value count
}
types struct {
JSONMarshaler reflect.Type
TextMarshaler reflect.Type
}
}{}
func init() {
internal.b64 = base64.StdEncoding
internal.defaultMarshalOption = emptyOptions()
internalAddPredictSizePerValue(16, 1)
internal.types.JSONMarshaler = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
internal.types.TextMarshaler = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
}
func internalLoadPredictSizePerValue() int {
if n := atomic.LoadUint64(&internal.predict.bytesPerValue); n > 0 {
return int(n)
}
v := atomic.LoadUint64(&internal.predict.calcStorage)
total := v >> 32
num := v & 0xFFFFFFFF
return int(total / num)
}
func internalAddPredictSizePerValue(total, num int) {
v := atomic.LoadUint64(&internal.predict.calcStorage)
preTotal := v >> 32
preNum := v & 0xFFFFFFFF
nextTotal := uint64(total) + preTotal
nextNum := uint64(num) + preNum
if nextTotal < 0x7FFFFFFF {
v := (nextTotal << 32) + nextNum
atomic.StoreUint64(&internal.predict.calcStorage, v)
return
}
per := nextTotal / nextNum
atomic.StoreUint64(&internal.predict.bytesPerValue, per)
atomic.StoreUint64(&internal.predict.calcStorage, (per<<32)+1)
}
type pool interface {
get() *V
}
type globalPool struct{}
func (globalPool) get() *V {
return &V{}
}
type poolImpl struct {
pool []V
count int
actual int // actual counted values
rawSize int
}
func newPool(rawSize int) *poolImpl {
per := internalLoadPredictSizePerValue()
cnt := rawSize / per
p := &poolImpl{
pool: make([]V, cnt),
count: cnt,
actual: 0,
rawSize: rawSize,
}
return p
}
func (p *poolImpl) get() *V {
if p.actual < p.count {
v := &p.pool[p.actual]
p.actual++
return v
}
p.actual++
return globalPool{}.get()
}
func (p *poolImpl) release() {
internalAddPredictSizePerValue(p.rawSize, p.actual)
}