mirror of https://github.com/goccy/go-json.git
Use bits.TrailingZeros for bitmap field
This commit is contained in:
parent
e080e515fd
commit
ddd7019dd3
|
@ -3,6 +3,7 @@ package json
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"math/bits"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
@ -22,24 +23,18 @@ type structDecoder struct {
|
||||||
structName string
|
structName string
|
||||||
fieldName string
|
fieldName string
|
||||||
isTriedOptimize bool
|
isTriedOptimize bool
|
||||||
keyBitmapInt8 [][256]int8
|
keyBitmapUint8 [][256]uint8
|
||||||
keyBitmapInt16 [][256]int16
|
keyBitmapUint16 [][256]uint16
|
||||||
sortedFieldSets []*structFieldSet
|
sortedFieldSets []*structFieldSet
|
||||||
keyDecoder func(*structDecoder, []byte, int64) (int64, *structFieldSet, error)
|
keyDecoder func(*structDecoder, []byte, int64) (int64, *structFieldSet, error)
|
||||||
keyStreamDecoder func(*structDecoder, *stream) (*structFieldSet, string, error)
|
keyStreamDecoder func(*structDecoder, *stream) (*structFieldSet, string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
bitHashTable [64]int
|
|
||||||
largeToSmallTable [256]byte
|
largeToSmallTable [256]byte
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
hash := uint64(0x03F566ED27179461)
|
|
||||||
for i := 0; i < 64; i++ {
|
|
||||||
bitHashTable[hash>>58] = i
|
|
||||||
hash <<= 1
|
|
||||||
}
|
|
||||||
for i := 0; i < 256; i++ {
|
for i := 0; i < 256; i++ {
|
||||||
c := i
|
c := i
|
||||||
if 'A' <= c && c <= 'Z' {
|
if 'A' <= c && c <= 'Z' {
|
||||||
|
@ -114,7 +109,7 @@ func (d *structDecoder) tryOptimize() {
|
||||||
// it is possible to avoid the process of comparing the index of the key with the length of the bitmap each time.
|
// it is possible to avoid the process of comparing the index of the key with the length of the bitmap each time.
|
||||||
bitmapLen := maxKeyLen + 1
|
bitmapLen := maxKeyLen + 1
|
||||||
if len(sortedKeys) <= 8 {
|
if len(sortedKeys) <= 8 {
|
||||||
keyBitmap := make([][256]int8, bitmapLen)
|
keyBitmap := make([][256]uint8, bitmapLen)
|
||||||
for i, key := range sortedKeys {
|
for i, key := range sortedKeys {
|
||||||
for j := 0; j < len(key); j++ {
|
for j := 0; j < len(key); j++ {
|
||||||
c := key[j]
|
c := key[j]
|
||||||
|
@ -122,11 +117,11 @@ func (d *structDecoder) tryOptimize() {
|
||||||
}
|
}
|
||||||
d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key])
|
d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key])
|
||||||
}
|
}
|
||||||
d.keyBitmapInt8 = keyBitmap
|
d.keyBitmapUint8 = keyBitmap
|
||||||
d.keyDecoder = decodeKeyByBitmapInt8
|
d.keyDecoder = decodeKeyByBitmapUint8
|
||||||
d.keyStreamDecoder = decodeKeyByBitmapInt8Stream
|
d.keyStreamDecoder = decodeKeyByBitmapUint8Stream
|
||||||
} else {
|
} else {
|
||||||
keyBitmap := make([][256]int16, bitmapLen)
|
keyBitmap := make([][256]uint16, bitmapLen)
|
||||||
for i, key := range sortedKeys {
|
for i, key := range sortedKeys {
|
||||||
for j := 0; j < len(key); j++ {
|
for j := 0; j < len(key); j++ {
|
||||||
c := key[j]
|
c := key[j]
|
||||||
|
@ -134,16 +129,16 @@ func (d *structDecoder) tryOptimize() {
|
||||||
}
|
}
|
||||||
d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key])
|
d.sortedFieldSets = append(d.sortedFieldSets, fieldMap[key])
|
||||||
}
|
}
|
||||||
d.keyBitmapInt16 = keyBitmap
|
d.keyBitmapUint16 = keyBitmap
|
||||||
d.keyDecoder = decodeKeyByBitmapInt16
|
d.keyDecoder = decodeKeyByBitmapUint16
|
||||||
d.keyStreamDecoder = decodeKeyByBitmapInt16Stream
|
d.keyStreamDecoder = decodeKeyByBitmapUint16Stream
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeKeyByBitmapInt8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
|
func decodeKeyByBitmapUint8(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
|
||||||
var (
|
var (
|
||||||
field *structFieldSet
|
field *structFieldSet
|
||||||
curBit int8 = math.MaxInt8
|
curBit uint8 = math.MaxUint8
|
||||||
)
|
)
|
||||||
b := (*sliceHeader)(unsafe.Pointer(&buf)).data
|
b := (*sliceHeader)(unsafe.Pointer(&buf)).data
|
||||||
for {
|
for {
|
||||||
|
@ -161,14 +156,13 @@ func decodeKeyByBitmapInt8(d *structDecoder, buf []byte, cursor int64) (int64, *
|
||||||
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
||||||
}
|
}
|
||||||
keyIdx := 0
|
keyIdx := 0
|
||||||
bitmap := d.keyBitmapInt8
|
bitmap := d.keyBitmapUint8
|
||||||
start := cursor
|
start := cursor
|
||||||
for {
|
for {
|
||||||
c := char(b, cursor)
|
c := char(b, cursor)
|
||||||
switch c {
|
switch c {
|
||||||
case '"':
|
case '"':
|
||||||
x := uint64(curBit & -curBit)
|
fieldSetIndex := bits.TrailingZeros8(curBit)
|
||||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
|
||||||
field = d.sortedFieldSets[fieldSetIndex]
|
field = d.sortedFieldSets[fieldSetIndex]
|
||||||
keyLen := cursor - start
|
keyLen := cursor - start
|
||||||
cursor++
|
cursor++
|
||||||
|
@ -208,10 +202,10 @@ func decodeKeyByBitmapInt8(d *structDecoder, buf []byte, cursor int64) (int64, *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeKeyByBitmapInt16(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
|
func decodeKeyByBitmapUint16(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldSet, error) {
|
||||||
var (
|
var (
|
||||||
field *structFieldSet
|
field *structFieldSet
|
||||||
curBit int16 = math.MaxInt16
|
curBit uint16 = math.MaxUint16
|
||||||
)
|
)
|
||||||
b := (*sliceHeader)(unsafe.Pointer(&buf)).data
|
b := (*sliceHeader)(unsafe.Pointer(&buf)).data
|
||||||
for {
|
for {
|
||||||
|
@ -229,14 +223,13 @@ func decodeKeyByBitmapInt16(d *structDecoder, buf []byte, cursor int64) (int64,
|
||||||
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
||||||
}
|
}
|
||||||
keyIdx := 0
|
keyIdx := 0
|
||||||
bitmap := d.keyBitmapInt16
|
bitmap := d.keyBitmapUint16
|
||||||
start := cursor
|
start := cursor
|
||||||
for {
|
for {
|
||||||
c := char(b, cursor)
|
c := char(b, cursor)
|
||||||
switch c {
|
switch c {
|
||||||
case '"':
|
case '"':
|
||||||
x := uint64(curBit & -curBit)
|
fieldSetIndex := bits.TrailingZeros16(curBit)
|
||||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
|
||||||
field = d.sortedFieldSets[fieldSetIndex]
|
field = d.sortedFieldSets[fieldSetIndex]
|
||||||
keyLen := cursor - start
|
keyLen := cursor - start
|
||||||
cursor++
|
cursor++
|
||||||
|
@ -290,10 +283,10 @@ func decodeKey(d *structDecoder, buf []byte, cursor int64) (int64, *structFieldS
|
||||||
return cursor, field, nil
|
return cursor, field, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeKeyByBitmapInt8Stream(d *structDecoder, s *stream) (*structFieldSet, string, error) {
|
func decodeKeyByBitmapUint8Stream(d *structDecoder, s *stream) (*structFieldSet, string, error) {
|
||||||
var (
|
var (
|
||||||
field *structFieldSet
|
field *structFieldSet
|
||||||
curBit int8 = math.MaxInt8
|
curBit uint8 = math.MaxUint8
|
||||||
)
|
)
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch s.char() {
|
||||||
|
@ -319,13 +312,12 @@ func decodeKeyByBitmapInt8Stream(d *structDecoder, s *stream) (*structFieldSet,
|
||||||
return nil, "", errUnexpectedEndOfJSON("string", s.totalOffset())
|
return nil, "", errUnexpectedEndOfJSON("string", s.totalOffset())
|
||||||
}
|
}
|
||||||
keyIdx := 0
|
keyIdx := 0
|
||||||
bitmap := d.keyBitmapInt8
|
bitmap := d.keyBitmapUint8
|
||||||
for {
|
for {
|
||||||
c := s.char()
|
c := s.char()
|
||||||
switch c {
|
switch c {
|
||||||
case '"':
|
case '"':
|
||||||
x := uint64(curBit & -curBit)
|
fieldSetIndex := bits.TrailingZeros8(curBit)
|
||||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
|
||||||
field = d.sortedFieldSets[fieldSetIndex]
|
field = d.sortedFieldSets[fieldSetIndex]
|
||||||
keyLen := s.cursor - start
|
keyLen := s.cursor - start
|
||||||
s.cursor++
|
s.cursor++
|
||||||
|
@ -374,10 +366,10 @@ func decodeKeyByBitmapInt8Stream(d *structDecoder, s *stream) (*structFieldSet,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func decodeKeyByBitmapInt16Stream(d *structDecoder, s *stream) (*structFieldSet, string, error) {
|
func decodeKeyByBitmapUint16Stream(d *structDecoder, s *stream) (*structFieldSet, string, error) {
|
||||||
var (
|
var (
|
||||||
field *structFieldSet
|
field *structFieldSet
|
||||||
curBit int16 = math.MaxInt16
|
curBit uint16 = math.MaxUint16
|
||||||
)
|
)
|
||||||
for {
|
for {
|
||||||
switch s.char() {
|
switch s.char() {
|
||||||
|
@ -403,13 +395,12 @@ func decodeKeyByBitmapInt16Stream(d *structDecoder, s *stream) (*structFieldSet,
|
||||||
return nil, "", errUnexpectedEndOfJSON("string", s.totalOffset())
|
return nil, "", errUnexpectedEndOfJSON("string", s.totalOffset())
|
||||||
}
|
}
|
||||||
keyIdx := 0
|
keyIdx := 0
|
||||||
bitmap := d.keyBitmapInt16
|
bitmap := d.keyBitmapUint16
|
||||||
for {
|
for {
|
||||||
c := s.char()
|
c := s.char()
|
||||||
switch c {
|
switch c {
|
||||||
case '"':
|
case '"':
|
||||||
x := uint64(curBit & -curBit)
|
fieldSetIndex := bits.TrailingZeros16(curBit)
|
||||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
|
||||||
field = d.sortedFieldSets[fieldSetIndex]
|
field = d.sortedFieldSets[fieldSetIndex]
|
||||||
keyLen := s.cursor - start
|
keyLen := s.cursor - start
|
||||||
s.cursor++
|
s.cursor++
|
||||||
|
|
Loading…
Reference in New Issue