forked from mirror/go-json
Fix algorithm of struct field detection
This commit is contained in:
parent
a75b5e9d93
commit
0c1e7c61e0
|
@ -260,6 +260,8 @@ func (d *Decoder) removeConflictFields(fieldMap map[string]*structFieldSet, conf
|
||||||
dec: v.dec,
|
dec: v.dec,
|
||||||
offset: baseOffset + v.offset,
|
offset: baseOffset + v.offset,
|
||||||
isTaggedKey: v.isTaggedKey,
|
isTaggedKey: v.isTaggedKey,
|
||||||
|
key: k,
|
||||||
|
keyLen: int64(len(k)),
|
||||||
}
|
}
|
||||||
fieldMap[k] = fieldSet
|
fieldMap[k] = fieldSet
|
||||||
lower := strings.ToLower(k)
|
lower := strings.ToLower(k)
|
||||||
|
@ -282,6 +284,8 @@ func (d *Decoder) removeConflictFields(fieldMap map[string]*structFieldSet, conf
|
||||||
dec: v.dec,
|
dec: v.dec,
|
||||||
offset: baseOffset + v.offset,
|
offset: baseOffset + v.offset,
|
||||||
isTaggedKey: v.isTaggedKey,
|
isTaggedKey: v.isTaggedKey,
|
||||||
|
key: k,
|
||||||
|
keyLen: int64(len(k)),
|
||||||
}
|
}
|
||||||
fieldMap[k] = fieldSet
|
fieldMap[k] = fieldSet
|
||||||
lower := strings.ToLower(k)
|
lower := strings.ToLower(k)
|
||||||
|
@ -345,6 +349,8 @@ func (d *Decoder) compileStruct(typ *rtype, structName, fieldName string) (decod
|
||||||
dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
|
dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
|
||||||
offset: field.Offset,
|
offset: field.Offset,
|
||||||
isTaggedKey: v.isTaggedKey,
|
isTaggedKey: v.isTaggedKey,
|
||||||
|
key: k,
|
||||||
|
keyLen: int64(len(k)),
|
||||||
}
|
}
|
||||||
fieldMap[k] = fieldSet
|
fieldMap[k] = fieldSet
|
||||||
lower := strings.ToLower(k)
|
lower := strings.ToLower(k)
|
||||||
|
@ -367,6 +373,8 @@ func (d *Decoder) compileStruct(typ *rtype, structName, fieldName string) (decod
|
||||||
dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
|
dec: newAnonymousFieldDecoder(pdec.typ, v.offset, v.dec),
|
||||||
offset: field.Offset,
|
offset: field.Offset,
|
||||||
isTaggedKey: v.isTaggedKey,
|
isTaggedKey: v.isTaggedKey,
|
||||||
|
key: k,
|
||||||
|
keyLen: int64(len(k)),
|
||||||
}
|
}
|
||||||
fieldMap[k] = fieldSet
|
fieldMap[k] = fieldSet
|
||||||
lower := strings.ToLower(k)
|
lower := strings.ToLower(k)
|
||||||
|
@ -388,22 +396,26 @@ func (d *Decoder) compileStruct(typ *rtype, structName, fieldName string) (decod
|
||||||
if tag.isString {
|
if tag.isString {
|
||||||
dec = newWrappedStringDecoder(dec, structName, field.Name)
|
dec = newWrappedStringDecoder(dec, structName, field.Name)
|
||||||
}
|
}
|
||||||
fieldSet := &structFieldSet{dec: dec, offset: field.Offset, isTaggedKey: tag.isTaggedKey}
|
var key string
|
||||||
if tag.key != "" {
|
if tag.key != "" {
|
||||||
fieldMap[tag.key] = fieldSet
|
key = tag.key
|
||||||
lower := strings.ToLower(tag.key)
|
|
||||||
if _, exists := fieldMap[lower]; !exists {
|
|
||||||
fieldMap[lower] = fieldSet
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
fieldMap[field.Name] = fieldSet
|
key = field.Name
|
||||||
lower := strings.ToLower(field.Name)
|
}
|
||||||
|
fieldSet := &structFieldSet{
|
||||||
|
dec: dec,
|
||||||
|
offset: field.Offset,
|
||||||
|
isTaggedKey: tag.isTaggedKey,
|
||||||
|
key: key,
|
||||||
|
keyLen: int64(len(key)),
|
||||||
|
}
|
||||||
|
fieldMap[key] = fieldSet
|
||||||
|
lower := strings.ToLower(key)
|
||||||
if _, exists := fieldMap[lower]; !exists {
|
if _, exists := fieldMap[lower]; !exists {
|
||||||
fieldMap[lower] = fieldSet
|
fieldMap[lower] = fieldSet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
delete(d.structTypeToDecoder, typeptr)
|
delete(d.structTypeToDecoder, typeptr)
|
||||||
structDec.tryOptimize()
|
structDec.tryOptimize()
|
||||||
return structDec, nil
|
return structDec, nil
|
||||||
|
|
|
@ -12,6 +12,8 @@ type structFieldSet struct {
|
||||||
dec decoder
|
dec decoder
|
||||||
offset uintptr
|
offset uintptr
|
||||||
isTaggedKey bool
|
isTaggedKey bool
|
||||||
|
key string
|
||||||
|
keyLen int64
|
||||||
}
|
}
|
||||||
|
|
||||||
type structDecoder struct {
|
type structDecoder struct {
|
||||||
|
@ -157,6 +159,7 @@ func decodeKeyByBitmapInt8(d *structDecoder, buf []byte, cursor int64) (int64, *
|
||||||
keyIdx := 0
|
keyIdx := 0
|
||||||
bitmap := d.keyBitmapInt8
|
bitmap := d.keyBitmapInt8
|
||||||
keyBitmapLen := len(bitmap)
|
keyBitmapLen := len(bitmap)
|
||||||
|
start := cursor
|
||||||
for {
|
for {
|
||||||
c := char(b, cursor)
|
c := char(b, cursor)
|
||||||
switch c {
|
switch c {
|
||||||
|
@ -164,7 +167,12 @@ func decodeKeyByBitmapInt8(d *structDecoder, buf []byte, cursor int64) (int64, *
|
||||||
x := uint64(curBit & -curBit)
|
x := uint64(curBit & -curBit)
|
||||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
||||||
field = d.sortedFieldSets[fieldSetIndex]
|
field = d.sortedFieldSets[fieldSetIndex]
|
||||||
|
keyLen := cursor - start
|
||||||
cursor++
|
cursor++
|
||||||
|
if keyLen < field.keyLen {
|
||||||
|
// early match
|
||||||
|
return cursor, nil, nil
|
||||||
|
}
|
||||||
return cursor, field, nil
|
return cursor, field, nil
|
||||||
case nul:
|
case nul:
|
||||||
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
||||||
|
@ -237,6 +245,7 @@ func decodeKeyByBitmapInt16(d *structDecoder, buf []byte, cursor int64) (int64,
|
||||||
keyIdx := 0
|
keyIdx := 0
|
||||||
bitmap := d.keyBitmapInt16
|
bitmap := d.keyBitmapInt16
|
||||||
keyBitmapLen := len(bitmap)
|
keyBitmapLen := len(bitmap)
|
||||||
|
start := cursor
|
||||||
for {
|
for {
|
||||||
c := char(b, cursor)
|
c := char(b, cursor)
|
||||||
switch c {
|
switch c {
|
||||||
|
@ -244,7 +253,12 @@ func decodeKeyByBitmapInt16(d *structDecoder, buf []byte, cursor int64) (int64,
|
||||||
x := uint64(curBit & -curBit)
|
x := uint64(curBit & -curBit)
|
||||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
||||||
field = d.sortedFieldSets[fieldSetIndex]
|
field = d.sortedFieldSets[fieldSetIndex]
|
||||||
|
keyLen := cursor - start
|
||||||
cursor++
|
cursor++
|
||||||
|
if keyLen < field.keyLen {
|
||||||
|
// early match
|
||||||
|
return cursor, nil, nil
|
||||||
|
}
|
||||||
return cursor, field, nil
|
return cursor, field, nil
|
||||||
case nul:
|
case nul:
|
||||||
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
return 0, nil, errUnexpectedEndOfJSON("string", cursor)
|
||||||
|
@ -341,10 +355,13 @@ func decodeKeyByBitmapInt8Stream(d *structDecoder, s *stream) (*structFieldSet,
|
||||||
x := uint64(curBit & -curBit)
|
x := uint64(curBit & -curBit)
|
||||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
||||||
field = d.sortedFieldSets[fieldSetIndex]
|
field = d.sortedFieldSets[fieldSetIndex]
|
||||||
b := s.buf[start:s.cursor]
|
keyLen := s.cursor - start
|
||||||
key := *(*string)(unsafe.Pointer(&b))
|
|
||||||
s.cursor++
|
s.cursor++
|
||||||
return field, key, nil
|
if keyLen < field.keyLen {
|
||||||
|
// early match
|
||||||
|
return nil, field.key, nil
|
||||||
|
}
|
||||||
|
return field, field.key, nil
|
||||||
case nul:
|
case nul:
|
||||||
if s.read() {
|
if s.read() {
|
||||||
continue
|
continue
|
||||||
|
@ -441,10 +458,13 @@ func decodeKeyByBitmapInt16Stream(d *structDecoder, s *stream) (*structFieldSet,
|
||||||
x := uint64(curBit & -curBit)
|
x := uint64(curBit & -curBit)
|
||||||
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
fieldSetIndex := bitHashTable[(x*0x03F566ED27179461)>>58]
|
||||||
field = d.sortedFieldSets[fieldSetIndex]
|
field = d.sortedFieldSets[fieldSetIndex]
|
||||||
b := s.buf[start:s.cursor]
|
keyLen := s.cursor - start
|
||||||
key := *(*string)(unsafe.Pointer(&b))
|
|
||||||
s.cursor++
|
s.cursor++
|
||||||
return field, key, nil
|
if keyLen < field.keyLen {
|
||||||
|
// early match
|
||||||
|
return nil, field.key, nil
|
||||||
|
}
|
||||||
|
return field, field.key, nil
|
||||||
case nul:
|
case nul:
|
||||||
if s.read() {
|
if s.read() {
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in New Issue