1
0
mirror of https://github.com/json-iterator/go.git synced 2025-05-13 21:36:29 +02:00

use iterator from cache for any

This commit is contained in:
Tao Wen 2017-06-17 21:10:08 +08:00
parent 50e4910c63
commit 55fc498d27
8 changed files with 82 additions and 121 deletions

View File

@ -29,7 +29,6 @@ type Any interface {
SetObject(map[string]Any) bool SetObject(map[string]Any) bool
GetInterface() interface{} GetInterface() interface{}
WriteTo(stream *Stream) WriteTo(stream *Stream)
Parse() *Iterator
} }
type baseAny struct{} type baseAny struct{}
@ -147,14 +146,14 @@ func Wrap(val interface{}) Any {
} }
func (iter *Iterator) ReadAny() Any { func (iter *Iterator) ReadAny() Any {
return iter.readAny(nil) return iter.readAny()
} }
func (iter *Iterator) readAny(reusableIter *Iterator) Any { func (iter *Iterator) readAny() Any {
c := iter.nextToken() c := iter.nextToken()
switch c { switch c {
case '"': case '"':
return iter.readStringAny(reusableIter) return iter.readStringAny()
case 'n': case 'n':
iter.skipFixedBytes(3) // null iter.skipFixedBytes(3) // null
return &nilAny{} return &nilAny{}
@ -165,15 +164,15 @@ func (iter *Iterator) readAny(reusableIter *Iterator) Any {
iter.skipFixedBytes(4) // false iter.skipFixedBytes(4) // false
return &falseAny{} return &falseAny{}
case '{': case '{':
return iter.readObjectAny(reusableIter) return iter.readObjectAny()
case '[': case '[':
return iter.readArrayAny(reusableIter) return iter.readArrayAny()
default: default:
return iter.readNumberAny(reusableIter, c) return iter.readNumberAny(c)
} }
} }
func (iter *Iterator) readNumberAny(reusableIter *Iterator, firstByte byte) Any { func (iter *Iterator) readNumberAny(firstByte byte) Any {
dotFound := false dotFound := false
lazyBuf := make([]byte, 1, 8) lazyBuf := make([]byte, 1, 8)
lazyBuf[0] = firstByte lazyBuf[0] = firstByte
@ -189,12 +188,12 @@ func (iter *Iterator) readNumberAny(reusableIter *Iterator, firstByte byte) Any
lazyBuf = append(lazyBuf, iter.buf[iter.head:i]...) lazyBuf = append(lazyBuf, iter.buf[iter.head:i]...)
iter.head = i iter.head = i
if dotFound { if dotFound {
return &float64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0} return &float64LazyAny{baseAny{}, iter.cfg, lazyBuf, nil, 0}
} else { } else {
if firstByte == '-' { if firstByte == '-' {
return &int64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0} return &int64LazyAny{baseAny{}, iter.cfg, lazyBuf, nil, 0}
} else { } else {
return &uint64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0} return &uint64LazyAny{baseAny{}, iter.cfg, lazyBuf, nil, 0}
} }
} }
} }
@ -203,19 +202,19 @@ func (iter *Iterator) readNumberAny(reusableIter *Iterator, firstByte byte) Any
if !iter.loadMore() { if !iter.loadMore() {
iter.head = iter.tail iter.head = iter.tail
if dotFound { if dotFound {
return &float64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0} return &float64LazyAny{baseAny{}, iter.cfg, lazyBuf, nil, 0}
} else { } else {
if firstByte == '-' { if firstByte == '-' {
return &int64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0} return &int64LazyAny{baseAny{}, iter.cfg, lazyBuf, nil, 0}
} else { } else {
return &uint64LazyAny{baseAny{}, lazyBuf, reusableIter, nil, 0} return &uint64LazyAny{baseAny{}, iter.cfg, lazyBuf, nil, 0}
} }
} }
} }
} }
} }
func (iter *Iterator) readStringAny(reusableIter *Iterator) Any { func (iter *Iterator) readStringAny() Any {
lazyBuf := make([]byte, 1, 8) lazyBuf := make([]byte, 1, 8)
lazyBuf[0] = '"' lazyBuf[0] = '"'
for { for {
@ -232,12 +231,12 @@ func (iter *Iterator) readStringAny(reusableIter *Iterator) Any {
} else { } else {
lazyBuf = append(lazyBuf, iter.buf[iter.head:end]...) lazyBuf = append(lazyBuf, iter.buf[iter.head:end]...)
iter.head = end iter.head = end
return &stringLazyAny{baseAny{}, lazyBuf, reusableIter, nil, ""} return &stringLazyAny{baseAny{}, iter.cfg, lazyBuf, nil, ""}
} }
} }
} }
func (iter *Iterator) readObjectAny(reusableIter *Iterator) Any { func (iter *Iterator) readObjectAny() Any {
level := 1 level := 1
lazyBuf := make([]byte, 1, 32) lazyBuf := make([]byte, 1, 32)
lazyBuf[0] = '{' lazyBuf[0] = '{'
@ -258,7 +257,7 @@ func (iter *Iterator) readObjectAny(reusableIter *Iterator) Any {
if level == 0 { if level == 0 {
iter.head = i + 1 iter.head = i + 1
lazyBuf = append(lazyBuf, iter.buf[start:iter.head]...) lazyBuf = append(lazyBuf, iter.buf[start:iter.head]...)
return &objectLazyAny{baseAny{}, lazyBuf, reusableIter, nil, nil, lazyBuf} return &objectLazyAny{baseAny{}, iter.cfg, lazyBuf, nil, nil, lazyBuf}
} }
} }
} }
@ -270,7 +269,7 @@ func (iter *Iterator) readObjectAny(reusableIter *Iterator) Any {
} }
} }
func (iter *Iterator) readArrayAny(reusableIter *Iterator) Any { func (iter *Iterator) readArrayAny() Any {
level := 1 level := 1
lazyBuf := make([]byte, 1, 32) lazyBuf := make([]byte, 1, 32)
lazyBuf[0] = '[' lazyBuf[0] = '['
@ -291,7 +290,7 @@ func (iter *Iterator) readArrayAny(reusableIter *Iterator) Any {
if level == 0 { if level == 0 {
iter.head = i + 1 iter.head = i + 1
lazyBuf = append(lazyBuf, iter.buf[start:iter.head]...) lazyBuf = append(lazyBuf, iter.buf[start:iter.head]...)
return &arrayLazyAny{baseAny{}, lazyBuf, reusableIter, nil, nil, lazyBuf} return &arrayLazyAny{baseAny{}, iter.cfg, lazyBuf, nil, nil, lazyBuf}
} }
} }
} }

View File

@ -8,8 +8,8 @@ import (
type arrayLazyAny struct { type arrayLazyAny struct {
baseAny baseAny
cfg *frozenConfig
buf []byte buf []byte
iter *Iterator
err error err error
cache []Any cache []Any
remaining []byte remaining []byte
@ -19,16 +19,6 @@ func (any *arrayLazyAny) ValueType() ValueType {
return Array return Array
} }
func (any *arrayLazyAny) Parse() *Iterator {
iter := any.iter
if iter == nil {
iter = NewIterator(ConfigDefault)
any.iter = iter
}
iter.ResetBytes(any.remaining)
return iter
}
func (any *arrayLazyAny) fillCacheUntil(target int) Any { func (any *arrayLazyAny) fillCacheUntil(target int) Any {
if any.remaining == nil { if any.remaining == nil {
if target >= len(any.cache) { if target >= len(any.cache) {
@ -43,13 +33,14 @@ func (any *arrayLazyAny) fillCacheUntil(target int) Any {
if target < i { if target < i {
return any.cache[target] return any.cache[target]
} }
iter := any.Parse() iter := any.cfg.BorrowIterator(any.remaining)
defer any.cfg.ReturnIterator(iter)
if len(any.remaining) == len(any.buf) { if len(any.remaining) == len(any.buf) {
iter.head++ iter.head++
c := iter.nextToken() c := iter.nextToken()
if c != ']' { if c != ']' {
iter.unreadByte() iter.unreadByte()
element := iter.readAny(iter) element := iter.readAny()
any.cache = append(any.cache, element) any.cache = append(any.cache, element)
if target == 0 { if target == 0 {
any.remaining = iter.buf[iter.head:] any.remaining = iter.buf[iter.head:]
@ -64,7 +55,7 @@ func (any *arrayLazyAny) fillCacheUntil(target int) Any {
} }
} }
for iter.nextToken() == ',' { for iter.nextToken() == ',' {
element := iter.readAny(iter) element := iter.readAny()
any.cache = append(any.cache, element) any.cache = append(any.cache, element)
if i == target { if i == target {
any.remaining = iter.buf[iter.head:] any.remaining = iter.buf[iter.head:]
@ -85,13 +76,14 @@ func (any *arrayLazyAny) fillCache() {
if any.cache == nil { if any.cache == nil {
any.cache = make([]Any, 0, 8) any.cache = make([]Any, 0, 8)
} }
iter := any.Parse() iter := any.cfg.BorrowIterator(any.remaining)
defer any.cfg.ReturnIterator(iter)
if len(any.remaining) == len(any.buf) { if len(any.remaining) == len(any.buf) {
iter.head++ iter.head++
c := iter.nextToken() c := iter.nextToken()
if c != ']' { if c != ']' {
iter.unreadByte() iter.unreadByte()
any.cache = append(any.cache, iter.readAny(iter)) any.cache = append(any.cache, iter.readAny())
} else { } else {
any.remaining = nil any.remaining = nil
any.err = iter.Error any.err = iter.Error
@ -99,7 +91,7 @@ func (any *arrayLazyAny) fillCache() {
} }
} }
for iter.nextToken() == ',' { for iter.nextToken() == ',' {
any.cache = append(any.cache, iter.readAny(iter)) any.cache = append(any.cache, iter.readAny())
} }
any.remaining = nil any.remaining = nil
any.err = iter.Error any.err = iter.Error
@ -254,12 +246,13 @@ func (any *arrayLazyAny) IterateArray() (func() (Any, bool), bool) {
} }
remaining := any.remaining remaining := any.remaining
if len(remaining) == len(any.buf) { if len(remaining) == len(any.buf) {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.remaining)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
c := iter.nextToken() c := iter.nextToken()
if c != ']' { if c != ']' {
iter.unreadByte() iter.unreadByte()
v := iter.readAny(iter) v := iter.readAny()
any.cache = append(any.cache, v) any.cache = append(any.cache, v)
remaining = iter.buf[iter.head:] remaining = iter.buf[iter.head:]
any.remaining = remaining any.remaining = remaining
@ -285,15 +278,11 @@ func (any *arrayLazyAny) IterateArray() (func() (Any, bool), bool) {
return value, true return value, true
} else { } else {
// read from buffer // read from buffer
iter := any.iter iter := any.cfg.BorrowIterator(any.remaining)
if iter == nil { defer any.cfg.ReturnIterator(iter)
iter = NewIterator(ConfigDefault)
any.iter = iter
}
iter.ResetBytes(remaining)
c := iter.nextToken() c := iter.nextToken()
if c == ',' { if c == ',' {
nextValue = iter.readAny(iter) nextValue = iter.readAny()
any.cache = append(any.cache, nextValue) any.cache = append(any.cache, nextValue)
remaining = iter.buf[iter.head:] remaining = iter.buf[iter.head:]
any.remaining = remaining any.remaining = remaining

View File

@ -8,21 +8,12 @@ import (
type float64LazyAny struct { type float64LazyAny struct {
baseAny baseAny
cfg *frozenConfig
buf []byte buf []byte
iter *Iterator
err error err error
cache float64 cache float64
} }
func (any *float64LazyAny) Parse() *Iterator {
iter := any.iter
if iter == nil {
iter = NewIterator(ConfigDefault)
}
iter.ResetBytes(any.buf)
return iter
}
func (any *float64LazyAny) ValueType() ValueType { func (any *float64LazyAny) ValueType() ValueType {
return Number return Number
} }
@ -31,7 +22,8 @@ func (any *float64LazyAny) fillCache() {
if any.err != nil { if any.err != nil {
return return
} }
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
any.cache = iter.ReadFloat64() any.cache = iter.ReadFloat64()
if iter.Error != io.EOF { if iter.Error != io.EOF {
iter.reportError("floatLazyAny", "there are bytes left") iter.reportError("floatLazyAny", "there are bytes left")

View File

@ -8,8 +8,8 @@ import (
type int64LazyAny struct { type int64LazyAny struct {
baseAny baseAny
cfg *frozenConfig
buf []byte buf []byte
iter *Iterator
err error err error
cache int64 cache int64
} }
@ -19,7 +19,8 @@ func (any *int64LazyAny) ValueType() ValueType {
} }
func (any *int64LazyAny) Parse() *Iterator { func (any *int64LazyAny) Parse() *Iterator {
iter := any.iter iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
if iter == nil { if iter == nil {
iter = NewIterator(ConfigDefault) iter = NewIterator(ConfigDefault)
} }

View File

@ -8,8 +8,8 @@ import (
type objectLazyAny struct { type objectLazyAny struct {
baseAny baseAny
cfg *frozenConfig
buf []byte buf []byte
iter *Iterator
err error err error
cache map[string]Any cache map[string]Any
remaining []byte remaining []byte
@ -19,16 +19,6 @@ func (any *objectLazyAny) ValueType() ValueType {
return Object return Object
} }
func (any *objectLazyAny) Parse() *Iterator {
iter := any.iter
if iter == nil {
iter = NewIterator(ConfigDefault)
any.iter = iter
}
iter.ResetBytes(any.remaining)
return iter
}
func (any *objectLazyAny) fillCacheUntil(target string) Any { func (any *objectLazyAny) fillCacheUntil(target string) Any {
if any.remaining == nil { if any.remaining == nil {
return any.cache[target] return any.cache[target]
@ -40,14 +30,15 @@ func (any *objectLazyAny) fillCacheUntil(target string) Any {
if val != nil { if val != nil {
return val return val
} }
iter := any.Parse() iter := any.cfg.BorrowIterator(any.remaining)
defer any.cfg.ReturnIterator(iter)
if len(any.remaining) == len(any.buf) { if len(any.remaining) == len(any.buf) {
iter.head++ iter.head++
c := iter.nextToken() c := iter.nextToken()
if c != '}' { if c != '}' {
iter.unreadByte() iter.unreadByte()
k := string(iter.readObjectFieldAsBytes()) k := string(iter.readObjectFieldAsBytes())
v := iter.readAny(iter) v := iter.readAny()
any.cache[k] = v any.cache[k] = v
if target == k { if target == k {
any.remaining = iter.buf[iter.head:] any.remaining = iter.buf[iter.head:]
@ -62,7 +53,7 @@ func (any *objectLazyAny) fillCacheUntil(target string) Any {
} }
for iter.nextToken() == ',' { for iter.nextToken() == ',' {
k := string(iter.readObjectFieldAsBytes()) k := string(iter.readObjectFieldAsBytes())
v := iter.readAny(iter) v := iter.readAny()
any.cache[k] = v any.cache[k] = v
if target == k { if target == k {
any.remaining = iter.buf[iter.head:] any.remaining = iter.buf[iter.head:]
@ -82,14 +73,15 @@ func (any *objectLazyAny) fillCache() {
if any.cache == nil { if any.cache == nil {
any.cache = map[string]Any{} any.cache = map[string]Any{}
} }
iter := any.Parse() iter := any.cfg.BorrowIterator(any.remaining)
defer any.cfg.ReturnIterator(iter)
if len(any.remaining) == len(any.buf) { if len(any.remaining) == len(any.buf) {
iter.head++ iter.head++
c := iter.nextToken() c := iter.nextToken()
if c != '}' { if c != '}' {
iter.unreadByte() iter.unreadByte()
k := string(iter.readObjectFieldAsBytes()) k := string(iter.readObjectFieldAsBytes())
v := iter.readAny(iter) v := iter.readAny()
any.cache[k] = v any.cache[k] = v
} else { } else {
any.remaining = nil any.remaining = nil
@ -99,7 +91,7 @@ func (any *objectLazyAny) fillCache() {
} }
for iter.nextToken() == ',' { for iter.nextToken() == ',' {
k := string(iter.readObjectFieldAsBytes()) k := string(iter.readObjectFieldAsBytes())
v := iter.readAny(iter) v := iter.readAny()
any.cache[k] = v any.cache[k] = v
} }
any.remaining = nil any.remaining = nil
@ -266,13 +258,14 @@ func (any *objectLazyAny) IterateObject() (func() (string, Any, bool), bool) {
} }
remaining := any.remaining remaining := any.remaining
if len(remaining) == len(any.buf) { if len(remaining) == len(any.buf) {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.remaining)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
c := iter.nextToken() c := iter.nextToken()
if c != '}' { if c != '}' {
iter.unreadByte() iter.unreadByte()
k := string(iter.readObjectFieldAsBytes()) k := string(iter.readObjectFieldAsBytes())
v := iter.readAny(iter) v := iter.readAny()
any.cache[k] = v any.cache[k] = v
remaining = iter.buf[iter.head:] remaining = iter.buf[iter.head:]
any.remaining = remaining any.remaining = remaining
@ -306,16 +299,12 @@ func (any *objectLazyAny) IterateObject() (func() (string, Any, bool), bool) {
return key, value, true return key, value, true
} else { } else {
// read from buffer // read from buffer
iter := any.iter iter := any.cfg.BorrowIterator(any.remaining)
if iter == nil { defer any.cfg.ReturnIterator(iter)
iter = NewIterator(ConfigDefault)
any.iter = iter
}
iter.ResetBytes(remaining)
c := iter.nextToken() c := iter.nextToken()
if c == ',' { if c == ',' {
nextKey = string(iter.readObjectFieldAsBytes()) nextKey = string(iter.readObjectFieldAsBytes())
nextValue = iter.readAny(iter) nextValue = iter.readAny()
any.cache[nextKey] = nextValue any.cache[nextKey] = nextValue
remaining = iter.buf[iter.head:] remaining = iter.buf[iter.head:]
any.remaining = remaining any.remaining = remaining

View File

@ -7,8 +7,8 @@ import (
type stringLazyAny struct { type stringLazyAny struct {
baseAny baseAny
cfg *frozenConfig
buf []byte buf []byte
iter *Iterator
err error err error
cache string cache string
} }
@ -17,21 +17,12 @@ func (any *stringLazyAny) ValueType() ValueType {
return String return String
} }
func (any *stringLazyAny) Parse() *Iterator {
iter := any.iter
if iter == nil {
iter = NewIterator(ConfigDefault)
any.iter = iter
}
iter.ResetBytes(any.buf)
return iter
}
func (any *stringLazyAny) fillCache() { func (any *stringLazyAny) fillCache() {
if any.err != nil { if any.err != nil {
return return
} }
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
any.cache = iter.ReadString() any.cache = iter.ReadString()
if iter.Error != io.EOF { if iter.Error != io.EOF {
iter.reportError("stringLazyAny", "there are bytes left") iter.reportError("stringLazyAny", "there are bytes left")
@ -59,7 +50,8 @@ func (any *stringLazyAny) ToBool() bool {
} }
func (any *stringLazyAny) ToInt() int { func (any *stringLazyAny) ToInt() int {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
val := iter.ReadInt() val := iter.ReadInt()
any.err = iter.Error any.err = iter.Error
@ -67,7 +59,8 @@ func (any *stringLazyAny) ToInt() int {
} }
func (any *stringLazyAny) ToInt32() int32 { func (any *stringLazyAny) ToInt32() int32 {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
val := iter.ReadInt32() val := iter.ReadInt32()
any.err = iter.Error any.err = iter.Error
@ -75,7 +68,8 @@ func (any *stringLazyAny) ToInt32() int32 {
} }
func (any *stringLazyAny) ToInt64() int64 { func (any *stringLazyAny) ToInt64() int64 {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
val := iter.ReadInt64() val := iter.ReadInt64()
any.err = iter.Error any.err = iter.Error
@ -83,7 +77,8 @@ func (any *stringLazyAny) ToInt64() int64 {
} }
func (any *stringLazyAny) ToUint() uint { func (any *stringLazyAny) ToUint() uint {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
val := iter.ReadUint() val := iter.ReadUint()
any.err = iter.Error any.err = iter.Error
@ -91,7 +86,8 @@ func (any *stringLazyAny) ToUint() uint {
} }
func (any *stringLazyAny) ToUint32() uint32 { func (any *stringLazyAny) ToUint32() uint32 {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
val := iter.ReadUint32() val := iter.ReadUint32()
any.err = iter.Error any.err = iter.Error
@ -99,7 +95,8 @@ func (any *stringLazyAny) ToUint32() uint32 {
} }
func (any *stringLazyAny) ToUint64() uint64 { func (any *stringLazyAny) ToUint64() uint64 {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
val := iter.ReadUint64() val := iter.ReadUint64()
any.err = iter.Error any.err = iter.Error
@ -107,7 +104,8 @@ func (any *stringLazyAny) ToUint64() uint64 {
} }
func (any *stringLazyAny) ToFloat32() float32 { func (any *stringLazyAny) ToFloat32() float32 {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
val := iter.ReadFloat32() val := iter.ReadFloat32()
any.err = iter.Error any.err = iter.Error
@ -115,7 +113,8 @@ func (any *stringLazyAny) ToFloat32() float32 {
} }
func (any *stringLazyAny) ToFloat64() float64 { func (any *stringLazyAny) ToFloat64() float64 {
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
iter.head++ iter.head++
val := iter.ReadFloat64() val := iter.ReadFloat64()
any.err = iter.Error any.err = iter.Error

View File

@ -8,8 +8,8 @@ import (
type uint64LazyAny struct { type uint64LazyAny struct {
baseAny baseAny
cfg *frozenConfig
buf []byte buf []byte
iter *Iterator
err error err error
cache uint64 cache uint64
} }
@ -18,20 +18,12 @@ func (any *uint64LazyAny) ValueType() ValueType {
return Number return Number
} }
func (any *uint64LazyAny) Parse() *Iterator {
iter := any.iter
if iter == nil {
iter = NewIterator(ConfigDefault)
}
iter.ResetBytes(any.buf)
return iter
}
func (any *uint64LazyAny) fillCache() { func (any *uint64LazyAny) fillCache() {
if any.err != nil { if any.err != nil {
return return
} }
iter := any.Parse() iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
any.cache = iter.ReadUint64() any.cache = iter.ReadUint64()
if iter.Error != io.EOF { if iter.Error != io.EOF {
iter.reportError("intLazyAny", "there are bytes left") iter.reportError("intLazyAny", "there are bytes left")