From b215a496a4fcab6b198ce4344b4c1b94c5b1eb12 Mon Sep 17 00:00:00 2001 From: antirez Date: Fri, 10 Dec 2010 17:03:38 +0100 Subject: [PATCH] faster INCR doing far less allocation in common cases --- src/t_string.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/t_string.c b/src/t_string.c index 39ee506d..cc6526fb 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -144,8 +144,23 @@ void incrDecrCommand(redisClient *c, long long incr) { o = lookupKeyWrite(c->db,c->argv[1]); if (o != NULL && checkType(c,o,REDIS_STRING)) return; - if (getLongLongFromObjectOrReply(c,o,&value,NULL) != REDIS_OK) return; + /* Fast path if the object is integer encoded and is not shared. */ + if (o && o->refcount == 1 && o->encoding == REDIS_ENCODING_INT) { + long long newval = ((long)o->ptr) + incr; + + if (newval >= LONG_MIN && newval <= LONG_MAX) { + o->ptr = (void*) (long) newval; + touchWatchedKey(c->db,c->argv[1]); + server.dirty++; + addReplyLongLong(c,newval); + return; + } + /* ... else take the usual safe path */ + } + + /* Otherwise we create a new object and replace the old one. */ + if (getLongLongFromObjectOrReply(c,o,&value,NULL) != REDIS_OK) return; value += incr; o = createStringObjectFromLongLong(value); dbReplace(c->db,c->argv[1],o);