@@ -63,13 +63,15 @@ function parseStringNumbers (parser) {
6363/**
6464 * Returns a string or buffer of the provided offset start and
6565 * end ranges. Checks `optionReturnBuffers`.
66+ *
67+ * If returnBuffers is active, all return values are returned as buffers besides numbers and errors
68+ *
6669 * @param parser
6770 * @param start
6871 * @param end
6972 * @returns {* }
7073 */
7174function convertBufferRange ( parser , start , end ) {
72- // If returnBuffers is active, all return values are returned as buffers besides numbers and errors
7375 parser . offset = end + 2
7476 if ( parser . optionReturnBuffers === true ) {
7577 return parser . buffer . slice ( start , end )
@@ -111,13 +113,15 @@ function parseLength (parser) {
111113
112114/**
113115 * Parse a ':' redis integer response
116+ *
117+ * If stringNumbers is activated the parser always returns numbers as string
118+ * This is important for big numbers (number > Math.pow(2, 53)) as js numbers
119+ * are 64bit floating point numbers with reduced precision
120+ *
114121 * @param parser
115122 * @returns {* }
116123 */
117124function parseInteger ( parser ) {
118- // If stringNumbers is activated the parser always returns numbers as string
119- // This is important for big numbers (number > Math.pow(2, 53)) as js numbers
120- // are 64bit floating point numbers with reduced precision
121125 if ( parser . optionStringNumbers ) {
122126 return parseStringNumbers ( parser )
123127 }
@@ -223,7 +227,10 @@ function parseType (parser, type) {
223227 case 45 : // -
224228 return parseError ( parser )
225229 default :
226- return handleError ( parser , new ReplyError ( 'Protocol error, got ' + JSON . stringify ( String . fromCharCode ( type ) ) + ' as reply type byte' ) )
230+ const err = new ReplyError ( 'Protocol error, got ' + JSON . stringify ( String . fromCharCode ( type ) ) + ' as reply type byte' , 20 )
231+ err . offset = parser . offset
232+ err . buffer = JSON . stringify ( parser . buffer )
233+ return handleError ( parser , err )
227234 }
228235}
229236
@@ -250,7 +257,7 @@ function JavascriptRedisParser (options) {
250257 throw new TypeError ( 'Please provide all return functions while initiating the parser' )
251258 }
252259 for ( var key in options ) {
253- if ( typeof options [ key ] !== optionTypes [ key ] ) {
260+ if ( optionTypes . hasOwnProperty ( key ) && typeof options [ key ] !== optionTypes [ key ] ) {
254261 throw new TypeError ( 'The options argument contains the property "' + key + '" that is either unkown or of a wrong type' )
255262 }
256263 }
@@ -280,13 +287,17 @@ function JavascriptRedisParser (options) {
280287
281288/**
282289 * Concat a bulk string containing multiple chunks
290+ *
291+ * Notes:
292+ * 1) The first chunk might contain the whole bulk string including the \r
293+ * 2) We are only safe to fully add up elements that are neither the first nor any of the last two elements
294+ *
283295 * @param parser
284296 * @param buffer
285297 * @returns {String }
286298 */
287299function concatBulkString ( parser ) {
288300 var list = parser . bufferCache
289- // The first chunk might contain the whole bulk string including the \r
290301 var chunks = list . length
291302 var offset = parser . bigStrSize - parser . totalChunkSize
292303 parser . offset = offset
@@ -299,7 +310,6 @@ function concatBulkString (parser) {
299310 }
300311 var res = decoder . write ( list [ 0 ] . slice ( parser . bigOffset ) )
301312 for ( var i = 1 ; i < chunks - 2 ; i ++ ) {
302- // We are only safe to fully add up elements that are neither the first nor any of the last two elements
303313 res += decoder . write ( list [ i ] )
304314 }
305315 res += decoder . end ( list [ i ] . slice ( 0 , offset === 1 ? list [ i ] . length - 1 : offset - 2 ) )
@@ -314,8 +324,14 @@ function decreaseBufferPool () {
314324 if ( bufferPool . length > 50 * 1024 ) {
315325 // Balance between increasing and decreasing the bufferPool
316326 if ( counter === 1 || notDecreased > counter * 2 ) {
317- // Decrease the bufferPool by 16kb by removing the first 16kb of the current pool
318- bufferPool = bufferPool . slice ( Math . floor ( bufferPool . length / 10 ) , bufferPool . length )
327+ // Decrease the bufferPool by 10% by removing the first 10% of the current pool
328+ var sliceLength = Math . floor ( bufferPool . length / 10 )
329+ if ( bufferOffset <= sliceLength ) {
330+ bufferOffset = 0
331+ } else {
332+ bufferOffset -= sliceLength
333+ }
334+ bufferPool = bufferPool . slice ( sliceLength , bufferPool . length )
319335 } else {
320336 notDecreased ++
321337 counter --
@@ -339,18 +355,17 @@ function concatBuffer (parser, length) {
339355 var pos = bufferOffset
340356 length -= parser . offset
341357 if ( bufferPool . length < length + bufferOffset ) {
342- // Increase the bufferPool size by three times the current needed length
343- var multiplier = 3
344- if ( bufferOffset > 1024 * 1024 * 200 ) {
358+ // Increase the bufferPool size
359+ var multiplier = length > 1024 * 1024 * 75 ? 2 : 3
360+ if ( bufferOffset > 1024 * 1024 * 120 ) {
345361 bufferOffset = 1024 * 1024 * 50
346- multiplier = 2
347362 }
348363 bufferPool = new Buffer ( length * multiplier + bufferOffset )
349364 bufferOffset = 0
350365 counter ++
351366 pos = 0
352367 if ( interval === null ) {
353- interval = setInterval ( decreaseBufferPool , 50 )
368+ interval = setInterval ( decreaseBufferPool , 50 ) . unref ( )
354369 }
355370 }
356371 list [ 0 ] . copy ( bufferPool , pos , parser . offset , list [ 0 ] . length )
@@ -369,7 +384,7 @@ function concatBuffer (parser, length) {
369384 * @param buffer
370385 * @returns {undefined }
371386 */
372- JavascriptRedisParser . prototype . execute = function ( buffer ) {
387+ JavascriptRedisParser . prototype . execute = function execute ( buffer ) {
373388 if ( this . buffer === null ) {
374389 this . buffer = buffer
375390 this . offset = 0
@@ -410,9 +425,9 @@ JavascriptRedisParser.prototype.execute = function (buffer) {
410425 }
411426
412427 if ( type === 45 ) {
413- this . returnError ( response ) // Errors -
428+ this . returnError ( response )
414429 } else {
415- this . returnReply ( response ) // Strings + // Integers : // Bulk strings $ // Arrays *
430+ this . returnReply ( response )
416431 }
417432 }
418433
0 commit comments