Skip to content

Commit 2156dc1

Browse files
committed
used double-linked list for cache
1 parent a536b72 commit 2156dc1

File tree

1 file changed

+52
-23
lines changed

1 file changed

+52
-23
lines changed

parser.go

Lines changed: 52 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -53,41 +53,70 @@ func (p *Parser) ParseBytes(b []byte) (*Value, error) {
5353
}
5454

5555
type cache struct {
56-
vs [][]Value
57-
allocated int
56+
vs []Value
57+
nx *cache // next
58+
lt *cache // last
5859
}
5960

6061
func (c *cache) reset() {
61-
for i := range c.vs {
62-
c.vs[i] = c.vs[i][:0]
63-
}
6462
c.vs = c.vs[:0]
63+
c.lt = nil
64+
if c.nx != nil {
65+
c.nx.reset()
66+
}
6567
}
6668

67-
const preAllocatedCacheSize = 32768
69+
const (
70+
preAllocatedCacheSize = 409 // 32kb class size
71+
macAllocatedCacheSize = 1024
72+
)
6873

6974
func (c *cache) getValue() *Value {
70-
last := len(c.vs) - 1
71-
needExt := last < 0 || cap(c.vs[last]) == len(c.vs[last])
72-
for {
73-
if needExt {
74-
if cap(c.vs) > len(c.vs) {
75-
c.vs = c.vs[:len(c.vs)+1]
76-
} else {
77-
c.vs = append(c.vs, make([]Value, 0, preAllocatedCacheSize))
78-
}
79-
last = len(c.vs) - 1
80-
needExt = false
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+
nextSize := len(c.vs)
102+
if nextSize*2 < macAllocatedCacheSize {
103+
nextSize *= 2
104+
} else {
105+
nextSize = macAllocatedCacheSize
81106
}
82-
if cap(c.vs[last]) > len(c.vs[last]) {
83-
c.vs[last] = c.vs[last][:len(c.vs[last])+1]
107+
readSrc = &cache{
108+
vs: make([]Value, 1, nextSize),
109+
}
110+
if c.lt != nil {
111+
c.lt.nx = readSrc
112+
c.lt = c.lt.nx
84113
} else {
85-
needExt = true
86-
continue
114+
c.nx = readSrc
115+
c.lt = c.nx
87116
}
88-
// Do not reset the value, since the caller must properly init it.
89-
return &c.vs[last][len(c.vs[last])-1]
90117
}
118+
// Do not reset the value, since the caller must properly init it.
119+
return &readSrc.vs[len(readSrc.vs)-1]
91120
}
92121

93122
func skipWS(s string) string {

0 commit comments

Comments
 (0)