Skip to content

Commit e1ca805

Browse files
committed
Merge improvements from valyala#101
2 parents 2139e90 + 1932ccd commit e1ca805

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

parser.go

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,80 @@ func (p *Parser) ParseBytes(b []byte) (*Value, error) {
5454

5555
type cache struct {
5656
vs []Value
57+
nx *cache // next
58+
lt *cache // last
5759
}
5860

5961
func (c *cache) reset() {
6062
c.vs = c.vs[:0]
63+
c.lt = nil
64+
if c.nx != nil {
65+
c.nx.reset()
66+
}
6167
}
6268

69+
const (
70+
preAllocatedCacheSize = 409 // 32kb class size
71+
macAllocatedCacheSize = 1024
72+
)
73+
6374
func (c *cache) getValue() *Value {
64-
if cap(c.vs) > len(c.vs) {
65-
c.vs = c.vs[:len(c.vs)+1]
66-
} else {
67-
c.vs = append(c.vs, Value{})
75+
var (
76+
addNext bool
77+
readSrc = c
78+
)
79+
switch {
80+
case cap(c.vs) == 0:
81+
// initial state
82+
c.vs = make([]Value, 1, preAllocatedCacheSize)
83+
84+
case c.lt != nil:
85+
l := c.lt
86+
if cap(l.vs) > len(l.vs) {
87+
l.vs = l.vs[:len(l.vs)+1]
88+
readSrc = l
89+
break
90+
}
91+
addNext = true
92+
93+
default:
94+
if cap(c.vs) > len(c.vs) {
95+
c.vs = c.vs[:len(c.vs)+1]
96+
break
97+
}
98+
addNext = true
99+
}
100+
if addNext {
101+
switch {
102+
case c.lt != nil && c.lt.nx != nil:
103+
c.lt = c.lt.nx
104+
readSrc = c.lt
105+
readSrc.vs = readSrc.vs[:1]
106+
case c.lt == nil && c.nx != nil:
107+
c.lt = c.nx
108+
readSrc = c.lt
109+
readSrc.vs = readSrc.vs[:1]
110+
default:
111+
nextSize := len(c.vs)
112+
if nextSize*2 < macAllocatedCacheSize {
113+
nextSize *= 2
114+
} else {
115+
nextSize = macAllocatedCacheSize
116+
}
117+
readSrc = &cache{
118+
vs: make([]Value, 1, nextSize),
119+
}
120+
if c.lt != nil {
121+
c.lt.nx = readSrc
122+
c.lt = c.lt.nx
123+
} else {
124+
c.nx = readSrc
125+
c.lt = c.nx
126+
}
127+
}
68128
}
69129
// Do not reset the value, since the caller must properly init it.
70-
return &c.vs[len(c.vs)-1]
130+
return &readSrc.vs[len(readSrc.vs)-1]
71131
}
72132

73133
func skipWS(s string) string {

0 commit comments

Comments
 (0)