Created
October 6, 2011 17:25
-
-
Save erickdavidson/1268015 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/memcached.js b/lib/memcached.js | |
index c3e4f26..64a7a01 100644 | |
--- a/lib/memcached.js | |
+++ b/lib/memcached.js | |
@@ -78,7 +78,8 @@ Client.config = { | |
, BUFFER = 1E2 | |
, CONTINUE = 1E1 | |
, FLAG_JSON = 1<<1 | |
- , FLAG_BINARY = 2<<1; | |
+ , FLAG_BINARY = 2<<1 | |
+ , FLAG_COMPRESSED = 3; | |
var memcached = nMemcached.prototype = new EventEmitter | |
, private = {} | |
@@ -192,10 +193,14 @@ Client.config = { | |
if (error) return query.callback && query.callback(error); | |
if (S.readyState !== 'open') return query.callback && query.callback('Connection readyState is set to ' + S.readySate); | |
+ var lineBreakValue = new Buffer((new Buffer(query.command, 'binary')).length + 2); | |
+ lineBreakValue.write(query.command, 0, 'binary'); | |
+ lineBreakValue.write(LINEBREAK, query.command.length, 'binary'); | |
+ | |
// used for request timing | |
query.start = Date.now(); | |
S.metaData.push(query); | |
- S.write(query.command + LINEBREAK); | |
+ S.write(new Buffer(lineBreakValue.toString('binary'), 'binary')); | |
}); | |
// if we have redundancy enabled and the query is used for redundancy, than we are going loop over | |
@@ -300,6 +305,9 @@ Client.config = { | |
case FLAG_JSON: | |
dataSet = JSON.parse(dataSet); | |
break; | |
+ case FLAG_COMPRESSED: | |
+ dataSet = zlib.inflate(new Buffer(dataSet, 'binary')); | |
+ break; | |
case FLAG_BINARY: | |
tmp = new Buffer(dataSet.length); | |
tmp.write(dataSet, 0, 'binary'); | |
@@ -410,7 +418,7 @@ Client.config = { | |
// or even right in the middle of a line-break, so we need to make sure, the last piece in the buffer is a LINEBREAK | |
// because that is all what is sure about the Memcached Protocol, all responds end with them. | |
private.buffer = function BufferBuffer(S, BufferStream){ | |
- S.responseBuffer += BufferStream; | |
+ S.responseBuffer += BufferStream.toString('binary'); | |
// only call transform the data once we are sure, 100% sure, that we valid response ending | |
if (S.responseBuffer.substr(S.responseBuffer.length - 2) === LINEBREAK){ | |
@@ -588,26 +596,45 @@ Client.config = { | |
// function to ease maintenance. This is possible because most set commands will use the same | |
// syntax for the Memcached server. Some commands do not require a lifetime and a flag, but the | |
// memcached server is smart enough to ignore those. | |
- private.setters = function setters(type, validate, key, value, lifetime, callback, cas){ | |
+ private.setters = function setters(type, validate, key, value, lifetime, compress, callback, cas){ | |
var flag = 0 | |
, memcached = this | |
, valuetype = typeof value | |
, length; | |
if (Buffer.isBuffer(value)){ | |
- flag = FLAG_BINARY; | |
+ if (compress) { | |
+ flag = FLAG_COMPRESSED; | |
+ value = new Buffer(zlib.deflate(value), 'binary'); | |
+ } else { | |
+ flag = FLAG_BINARY; | |
+ } | |
+ length = value.length; | |
value = value.toString('binary'); | |
} else if (valuetype !== 'string' && valuetype !== 'number'){ | |
flag = FLAG_JSON; | |
value = JSON.stringify(value); | |
+ length = Buffer.byteLength(value); | |
} else { | |
value = value.toString(); | |
+ length = Buffer.byteLength(value); | |
} | |
length = Buffer.byteLength(value); | |
if (length > memcached.maxValue) return private.errorResponse('The length of the value is greater than ' + memcached.maxValue, callback); | |
- memcached.command(function settersCommand(noreply){ return { | |
+ var lineBreakValue = new Buffer((new Buffer(value, 'binary')).length + 2); | |
+ lineBreakValue.write(LINEBREAK, 0, 'binary'); | |
+ lineBreakValue.write(value, 2, 'binary'); | |
+ | |
+ memcached.command(function settersCommand(noreply){ | |
+ | |
+ var commandBuffer = new Buffer([type, key, flag, lifetime, length].join(' ') + (cas ? ' ' + cas : '') + (noreply ? NOREPLY : ''), 'binary'); | |
+ var commandWithValue = new Buffer(commandBuffer.length + lineBreakValue.length); | |
+ commandBuffer.copy(commandWithValue, 0, 0); | |
+ lineBreakValue.copy(commandWithValue, commandBuffer.length, 0); | |
+ | |
+ return { | |
key: key | |
, callback: callback | |
, lifetime: lifetime | |
@@ -616,15 +643,11 @@ Client.config = { | |
, validate: validate | |
, type: type | |
, redundancyEnabled: true | |
- , command: [type, key, flag, lifetime, length].join(' ') + | |
- (cas ? ' ' + cas : '') + | |
- (noreply ? NOREPLY : '') + | |
- LINEBREAK + value | |
- }}); | |
+ , command: commandWithValue.toString('binary') }}); | |
}; | |
// Curry the function and so we can tell the type our private set function | |
- memcached.set = Utils.curry(false, private.setters, 'set', [['key', String], ['lifetime', Number], ['value', String], ['callback', Function]]); | |
+ memcached.set = Utils.curry(false, private.setters, 'set', [['key', String], ['lifetime', Number], ['value', String], ['compress', Boolean], ['callback', Function]]); | |
memcached.replace = Utils.curry(false, private.setters, 'replace', [['key', String], ['lifetime', Number], ['value', String], ['callback', Function]]); | |
memcached.add = Utils.curry(false, private.setters, 'add', [['key', String], ['lifetime', Number], ['value', String], ['callback', Function]]); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment