Use less memory when emitting the protocol, by using more shared objects for commonly emitted parts of the protocol.

This commit is contained in:
antirez 2012-02-04 08:58:37 +01:00
parent ce8b772be7
commit 355f859134
5 changed files with 34 additions and 13 deletions

View File

@ -488,9 +488,10 @@ long long getExpire(redisDb *db, robj *key) {
void propagateExpire(redisDb *db, robj *key) {
robj *argv[2];
argv[0] = createStringObject("DEL",3);
argv[0] = shared.del;
argv[1] = key;
incrRefCount(key);
incrRefCount(argv[0]);
incrRefCount(argv[1]);
if (server.aof_state != REDIS_AOF_OFF)
feedAppendOnlyFile(server.delCommand,db->id,argv,2);

View File

@ -363,6 +363,18 @@ void addReplyDouble(redisClient *c, double d) {
void addReplyLongLongWithPrefix(redisClient *c, long long ll, char prefix) {
char buf[128];
int len;
/* Things like $3\r\n or *2\r\n are emitted very often by the protocol
* so we have a few shared objects to use if the integer is small
* like it is most of the times. */
if (prefix == '*' && ll < REDIS_SHARED_BULKHDR_LEN) {
addReply(c,shared.mbulkhdr[ll]);
return;
} else if (prefix == '$' && ll < REDIS_SHARED_BULKHDR_LEN) {
addReply(c,shared.bulkhdr[ll]);
return;
}
buf[0] = prefix;
len = ll2string(buf+1,sizeof(buf)-1,ll);
buf[len+1] = '\r';

View File

@ -41,7 +41,7 @@ int pubsubSubscribeChannel(redisClient *c, robj *channel) {
listAddNodeTail(clients,c);
}
/* Notify the client */
addReply(c,shared.mbulk3);
addReply(c,shared.mbulkhdr[3]);
addReply(c,shared.subscribebulk);
addReplyBulk(c,channel);
addReplyLongLong(c,dictSize(c->pubsub_channels)+listLength(c->pubsub_patterns));
@ -77,7 +77,7 @@ int pubsubUnsubscribeChannel(redisClient *c, robj *channel, int notify) {
}
/* Notify the client */
if (notify) {
addReply(c,shared.mbulk3);
addReply(c,shared.mbulkhdr[3]);
addReply(c,shared.unsubscribebulk);
addReplyBulk(c,channel);
addReplyLongLong(c,dictSize(c->pubsub_channels)+
@ -103,7 +103,7 @@ int pubsubSubscribePattern(redisClient *c, robj *pattern) {
listAddNodeTail(server.pubsub_patterns,pat);
}
/* Notify the client */
addReply(c,shared.mbulk3);
addReply(c,shared.mbulkhdr[3]);
addReply(c,shared.psubscribebulk);
addReplyBulk(c,pattern);
addReplyLongLong(c,dictSize(c->pubsub_channels)+listLength(c->pubsub_patterns));
@ -128,7 +128,7 @@ int pubsubUnsubscribePattern(redisClient *c, robj *pattern, int notify) {
}
/* Notify the client */
if (notify) {
addReply(c,shared.mbulk3);
addReply(c,shared.mbulkhdr[3]);
addReply(c,shared.punsubscribebulk);
addReplyBulk(c,pattern);
addReplyLongLong(c,dictSize(c->pubsub_channels)+
@ -188,7 +188,7 @@ int pubsubPublishMessage(robj *channel, robj *message) {
while ((ln = listNext(&li)) != NULL) {
redisClient *c = ln->value;
addReply(c,shared.mbulk3);
addReply(c,shared.mbulkhdr[3]);
addReply(c,shared.messagebulk);
addReplyBulk(c,channel);
addReplyBulk(c,message);
@ -206,7 +206,7 @@ int pubsubPublishMessage(robj *channel, robj *message) {
sdslen(pat->pattern->ptr),
(char*)channel->ptr,
sdslen(channel->ptr),0)) {
addReply(pat->client,shared.mbulk4);
addReply(pat->client,shared.mbulkhdr[4]);
addReply(pat->client,shared.pmessagebulk);
addReplyBulk(pat->client,pat->pattern);
addReplyBulk(pat->client,channel);

View File

@ -851,12 +851,17 @@ void createSharedObjects(void) {
shared.unsubscribebulk = createStringObject("$11\r\nunsubscribe\r\n",18);
shared.psubscribebulk = createStringObject("$10\r\npsubscribe\r\n",17);
shared.punsubscribebulk = createStringObject("$12\r\npunsubscribe\r\n",19);
shared.mbulk3 = createStringObject("*3\r\n",4);
shared.mbulk4 = createStringObject("*4\r\n",4);
shared.del = createStringObject("DEL",3);
for (j = 0; j < REDIS_SHARED_INTEGERS; j++) {
shared.integers[j] = createObject(REDIS_STRING,(void*)(long)j);
shared.integers[j]->encoding = REDIS_ENCODING_INT;
}
for (j = 0; j < REDIS_SHARED_BULKHDR_LEN; j++) {
shared.mbulkhdr[j] = createObject(REDIS_STRING,
sdscatprintf(sdsempty(),"*%d\r\n",j));
shared.bulkhdr[j] = createObject(REDIS_STRING,
sdscatprintf(sdsempty(),"$%d\r\n",j));
}
}
void initServerConfig() {

View File

@ -46,6 +46,7 @@
#define REDIS_EXPIRELOOKUPS_PER_CRON 10 /* lookup 10 expires per loop */
#define REDIS_MAX_WRITE_PER_EVENT (1024*64)
#define REDIS_SHARED_INTEGERS 10000
#define REDIS_SHARED_BULKHDR_LEN 32
#define REDIS_MAX_LOGMSG_LEN 1024 /* Default maximum length of syslog messages */
#define REDIS_AOF_REWRITE_PERC 100
#define REDIS_AOF_REWRITE_MIN_SIZE (1024*1024)
@ -358,9 +359,11 @@ struct sharedObjectsStruct {
*outofrangeerr, *noscripterr, *loadingerr, *slowscripterr, *plus,
*select0, *select1, *select2, *select3, *select4,
*select5, *select6, *select7, *select8, *select9,
*messagebulk, *pmessagebulk, *subscribebulk, *unsubscribebulk, *mbulk3,
*mbulk4, *psubscribebulk, *punsubscribebulk,
*integers[REDIS_SHARED_INTEGERS];
*messagebulk, *pmessagebulk, *subscribebulk, *unsubscribebulk,
*psubscribebulk, *punsubscribebulk, *del,
*integers[REDIS_SHARED_INTEGERS],
*mbulkhdr[REDIS_SHARED_BULKHDR_LEN], /* "*<value>\r\n" */
*bulkhdr[REDIS_SHARED_BULKHDR_LEN]; /* "$<value>\r\n" */
};
/* ZSETs use a specialized version of Skiplists */