summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2012-02-04 08:58:37 +0100
committerantirez <antirez@gmail.com>2012-02-04 08:58:37 +0100
commit355f859134e6220cb35d7b3fa9ea19ea8d05c02a (patch)
treebff3eafe2939ae86c7c89b822b4c3fd27c146d2e
parentce8b772be7dcd0dec767c7bdfa3b8702806d69c4 (diff)
downloadredis-355f859134e6220cb35d7b3fa9ea19ea8d05c02a.tar.gz
Use less memory when emitting the protocol, by using more shared objects for commonly emitted parts of the protocol.
-rw-r--r--src/db.c5
-rw-r--r--src/networking.c12
-rw-r--r--src/pubsub.c12
-rw-r--r--src/redis.c9
-rw-r--r--src/redis.h9
5 files changed, 34 insertions, 13 deletions
diff --git a/src/db.c b/src/db.c
index fc366b07e..a0775af96 100644
--- a/src/db.c
+++ b/src/db.c
@@ -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);
diff --git a/src/networking.c b/src/networking.c
index 3938f3f64..30c939658 100644
--- a/src/networking.c
+++ b/src/networking.c
@@ -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';
diff --git a/src/pubsub.c b/src/pubsub.c
index 27e6f9a58..984013bbc 100644
--- a/src/pubsub.c
+++ b/src/pubsub.c
@@ -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);
diff --git a/src/redis.c b/src/redis.c
index 765f58dad..45ee07caf 100644
--- a/src/redis.c
+++ b/src/redis.c
@@ -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() {
diff --git a/src/redis.h b/src/redis.h
index 8f19ad37f..ad6241114 100644
--- a/src/redis.h
+++ b/src/redis.h
@@ -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 */