@@ -54,20 +54,80 @@ func (p *Parser) ParseBytes(b []byte) (*Value, error) {
5454
5555type cache struct {
5656 vs []Value
57+ nx * cache // next
58+ lt * cache // last
5759}
5860
5961func (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+
6374func (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
73133func skipWS (s string ) string {
0 commit comments