@@ -119,7 +119,7 @@ public struct RESPParser {
119119 }
120120 else {
121121 if countValue > 0 {
122- arrayContexts . append ( ArrayParseContext ( countValue) )
122+ pushArrayContext ( expectedCount : countValue)
123123 }
124124 else {
125125 decoded ( value: . array( [ ] ) , yield: yield)
@@ -231,30 +231,52 @@ public struct RESPParser {
231231 }
232232 }
233233
234- assert ( ! ( arrayContexts . last ? . isDone ?? false ) ,
235- " array context on stack which is done? \( arrayContexts ) " )
234+ assert ( ctxIndex < 0 || !arrayContextBuffer [ ctxIndex ] . isDone,
235+ " array context on stack which is done? \( arrayContextBuffer ) " )
236236 }
237237
238238
239239 // MARK: - Parsing
240240
241+ @inline ( __always)
242+ private mutating func pushArrayContext( expectedCount: Int ) {
243+ if ctxIndex == ctxCapacity {
244+ for _ in 0 ..< 4 {
245+ arrayContextBuffer. append ( ArrayParseContext ( expectedCount: - 44 ) )
246+ }
247+ ctxCapacity = arrayContextBuffer. count
248+ }
249+ assert ( ctxIndex < ctxCapacity, " index overflow " )
250+ ctxIndex += 1
251+ arrayContextBuffer [ ctxIndex] . expectedCount = expectedCount
252+ arrayContextBuffer [ ctxIndex] . values. reserveCapacity ( expectedCount)
253+ }
254+
241255 @inline ( __always)
242256 private mutating func decoded( value: RESPValue , yield: Yield ) {
243- if arrayContexts . isEmpty {
257+ if ctxIndex < 0 {
244258 return yield ( value)
245259 }
246260
247- let idx = arrayContexts. endIndex. advanced ( by: - 1 )
248- let isDone = arrayContexts [ idx] . append ( value: value)
249-
261+ let idx = ctxIndex
262+ let isDone = arrayContextBuffer [ idx] . append ( value: value)
250263 if isDone {
251- let v = RESPValue . array ( arrayContexts [ idx] . values)
264+ let value = RESPValue . array ( arrayContextBuffer [ idx] . values)
265+ arrayContextBuffer [ idx] . values = emptyValueArray
266+ arrayContextBuffer [ idx] . expectedCount = - 1337
252267
253- _ = arrayContexts. popLast ( )
254- decoded ( value: v, yield: yield)
268+ ctxIndex -= 1
269+ if ctxIndex < 0 {
270+ yield( value)
271+ }
272+ else {
273+ decoded ( value: value, yield: yield)
274+ }
255275 }
256276 }
257277
278+ let emptyValueArray = ContiguousArray < RESPValue > ( )
279+
258280 private enum ParserState {
259281 case protocolError
260282 case start
@@ -267,14 +289,26 @@ public struct RESPParser {
267289 case telnet
268290 }
269291
270- private var arrayContexts = ContiguousArray < ArrayParseContext > ( )
292+ private var ctxIndex : Int
293+ private var ctxCapacity : Int
294+ private var arrayContextBuffer : ContiguousArray < ArrayParseContext >
295+
296+ init ( ) {
297+ ctxIndex = - 1
298+ ctxCapacity = 2
299+ arrayContextBuffer = ContiguousArray < ArrayParseContext > ( )
300+ arrayContextBuffer. reserveCapacity ( 8 )
301+ for _ in 0 ..< ctxCapacity {
302+ arrayContextBuffer. append ( ArrayParseContext ( expectedCount: - 42 ) )
303+ }
304+ }
271305
272306 private struct ArrayParseContext {
273307
274308 var values = ContiguousArray < RESPValue > ( )
275309 var expectedCount : Int
276310
277- init ( _ expectedCount: Int ) {
311+ init ( expectedCount: Int ) {
278312 self . expectedCount = expectedCount
279313 values. reserveCapacity ( expectedCount + 1 )
280314 }
0 commit comments