X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/8f8eeffec1fe1c0d40b6d078121661d7cfb02c08..4c5f0966b2e582981d9fdaf3b511c6cf4ac4d4d5:/src/t_string.c diff --git a/src/t_string.c b/src/t_string.c index 324e01ab..64b6f0c5 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -1,4 +1,3 @@ -#include #include "redis.h" /*----------------------------------------------------------------------------- @@ -38,7 +37,7 @@ void setGenericCommand(redisClient *c, int nx, robj *key, robj *val, robj *expir } else { incrRefCount(val); } - touchWatchedKey(c->db,key); + signalModifiedKey(c->db,key); server.dirty++; removeExpire(c->db,key); if (expire) setExpire(c->db,key,time(NULL)+seconds); @@ -84,7 +83,7 @@ void getsetCommand(redisClient *c) { c->argv[2] = tryObjectEncoding(c->argv[2]); dbReplace(c->db,c->argv[1],c->argv[2]); incrRefCount(c->argv[2]); - touchWatchedKey(c->db,c->argv[1]); + signalModifiedKey(c->db,c->argv[1]); server.dirty++; removeExpire(c->db,c->argv[1]); } @@ -156,7 +155,7 @@ void setbitCommand(redisClient *c) { byteval &= ~(1 << bit); byteval |= ((on & 0x1) << bit); ((char*)o->ptr)[byte] = byteval; - touchWatchedKey(c->db,c->argv[1]); + signalModifiedKey(c->db,c->argv[1]); server.dirty++; addReply(c, bitval ? shared.cone : shared.czero); } @@ -215,21 +214,14 @@ void setrangeCommand(redisClient *c) { o = createObject(REDIS_STRING,sdsempty()); dbAdd(c->db,c->argv[1],o); } else { - int olen; + size_t olen; /* Key exists, check type */ if (checkType(c,o,REDIS_STRING)) return; - /* Find out existing value length */ - if (o->encoding == REDIS_ENCODING_INT) { - char llbuf[32]; - olen = ll2string(llbuf,sizeof(llbuf),(long)o->ptr); - } else { - olen = sdslen(o->ptr); - } - /* Return existing string length when setting nothing */ + olen = stringObjectLen(o); if (sdslen(value) == 0) { addReplyLongLong(c,olen); return; @@ -251,7 +243,7 @@ void setrangeCommand(redisClient *c) { if (sdslen(value) > 0) { o->ptr = sdsgrowzero(o->ptr,offset+sdslen(value)); memcpy((char*)o->ptr+offset,value,sdslen(value)); - touchWatchedKey(c->db,c->argv[1]); + signalModifiedKey(c->db,c->argv[1]); server.dirty++; } addReplyLongLong(c,sdslen(o->ptr)); @@ -267,7 +259,7 @@ void getrangeCommand(redisClient *c) { return; if (getLongFromObjectOrReply(c,c->argv[3],&end,NULL) != REDIS_OK) return; - if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL || + if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptybulk)) == NULL || checkType(c,o,REDIS_STRING)) return; if (o->encoding == REDIS_ENCODING_INT) { @@ -288,7 +280,7 @@ void getrangeCommand(redisClient *c) { /* Precondition: end >= 0 && end < strlen, so the only condition where * nothing can be returned is: start > end. */ if (start > end) { - addReply(c,shared.nullbulk); + addReply(c,shared.emptybulk); } else { addReplyBulkCBuffer(c,(char*)str+start,end-start+1); } @@ -338,7 +330,7 @@ void msetGenericCommand(redisClient *c, int nx) { dbReplace(c->db,c->argv[j],c->argv[j+1]); incrRefCount(c->argv[j+1]); removeExpire(c->db,c->argv[j]); - touchWatchedKey(c->db,c->argv[j]); + signalModifiedKey(c->db,c->argv[j]); } server.dirty += (c->argc-1)/2; addReply(c, nx ? shared.cone : shared.ok); @@ -353,17 +345,22 @@ void msetnxCommand(redisClient *c) { } void incrDecrCommand(redisClient *c, long long incr) { - long long value; + long long value, oldvalue; robj *o; 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; + oldvalue = value; value += incr; + if ((incr < 0 && value > oldvalue) || (incr > 0 && value < oldvalue)) { + addReplyError(c,"increment or decrement would overflow"); + return; + } o = createStringObjectFromLongLong(value); dbReplace(c->db,c->argv[1],o); - touchWatchedKey(c->db,c->argv[1]); + signalModifiedKey(c->db,c->argv[1]); server.dirty++; addReply(c,shared.colon); addReply(c,o); @@ -393,31 +390,26 @@ void decrbyCommand(redisClient *c) { } void appendCommand(redisClient *c) { - int retval; size_t totlen; robj *o, *append; o = lookupKeyWrite(c->db,c->argv[1]); - c->argv[2] = tryObjectEncoding(c->argv[2]); if (o == NULL) { /* Create the key */ - retval = dbAdd(c->db,c->argv[1],c->argv[2]); + c->argv[2] = tryObjectEncoding(c->argv[2]); + dbAdd(c->db,c->argv[1],c->argv[2]); incrRefCount(c->argv[2]); totlen = stringObjectLen(c->argv[2]); } else { - if (o->type != REDIS_STRING) { - addReply(c,shared.wrongtypeerr); + /* Key exists, check type */ + if (checkType(c,o,REDIS_STRING)) return; - } - append = getDecodedObject(c->argv[2]); - if (o->encoding == REDIS_ENCODING_RAW && - (sdslen(o->ptr) + sdslen(append->ptr)) > 512*1024*1024) - { - addReplyError(c,"string exceeds maximum allowed size (512MB)"); - decrRefCount(append); + /* "append" is an argument, so always an sds */ + append = c->argv[2]; + totlen = stringObjectLen(o)+sdslen(append->ptr); + if (checkStringLength(c,totlen) != REDIS_OK) return; - } /* If the object is shared or encoded, we have to make a copy */ if (o->refcount != 1 || o->encoding != REDIS_ENCODING_RAW) { @@ -429,28 +421,17 @@ void appendCommand(redisClient *c) { /* Append the value */ o->ptr = sdscatlen(o->ptr,append->ptr,sdslen(append->ptr)); - decrRefCount(append); totlen = sdslen(o->ptr); } - touchWatchedKey(c->db,c->argv[1]); + signalModifiedKey(c->db,c->argv[1]); server.dirty++; addReplyLongLong(c,totlen); } void strlenCommand(redisClient *c) { robj *o; - if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL || checkType(c,o,REDIS_STRING)) return; - - if (o->encoding == REDIS_ENCODING_RAW) { - addReplyLongLong(c,sdslen(o->ptr)); - } else if (o->encoding == REDIS_ENCODING_INT) { - char llbuf[32]; - int len = ll2string(llbuf,sizeof(llbuf),(long)o->ptr); - addReplyLongLong(c,len); - } else { - redisPanic("Unknown string encoding"); - } + addReplyLongLong(c,stringObjectLen(o)); }