diff options
author | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2010-12-10 11:58:14 +0100 |
---|---|---|
committer | Pieter Noordhuis <pcnoordhuis@gmail.com> | 2010-12-10 11:58:21 +0100 |
commit | eae33c1c813953e27dc37dfe7c3dcc246fda294f (patch) | |
tree | a57e1d8c24bd6a2e9061e1485ce38013084850c8 /src/t_string.c | |
parent | 076f88d65769788113c8d4db582a7b3ec8d0fefa (diff) | |
download | redis-eae33c1c813953e27dc37dfe7c3dcc246fda294f.tar.gz |
Add generic function to grow an sds value
Move logic concerned with setting a bit in an sds to the SETBIT command
instead of keeping it in sds.c. The function to grow an sds can and will
be reused for a command to set a range within a string value.
Diffstat (limited to 'src/t_string.c')
-rw-r--r-- | src/t_string.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/t_string.c b/src/t_string.c index b77bcf0a0..b41a1522b 100644 --- a/src/t_string.c +++ b/src/t_string.c @@ -103,22 +103,26 @@ static int getBitOffsetFromArgument(redisClient *c, robj *o, size_t *offset) { void setbitCommand(redisClient *c) { robj *o; + char *err = "bit is not an integer or out of range"; size_t bitoffset; - int on; + long long bitvalue; + int byte, bit, on; if (getBitOffsetFromArgument(c,c->argv[2],&bitoffset) != REDIS_OK) return; - on = ((sds)c->argv[3]->ptr)[0] - '0'; - if (sdslen(c->argv[3]->ptr) != 1 || (on & ~1)) { - addReplyError(c,"bit should be 0 or 1"); + if (getLongLongFromObjectOrReply(c,c->argv[3],&bitvalue,err) != REDIS_OK) + return; + + /* A bit can only be set to be on or off... */ + if (bitvalue & ~1) { + addReplyError(c,err); return; } o = lookupKeyWrite(c->db,c->argv[1]); if (o == NULL) { - sds value = sdssetbit(sdsempty(),bitoffset,on); - o = createObject(REDIS_STRING,value); + o = createObject(REDIS_STRING,sdsempty()); dbAdd(c->db,c->argv[1],o); } else { if (checkType(c,o,REDIS_STRING)) return; @@ -130,9 +134,15 @@ void setbitCommand(redisClient *c) { decrRefCount(decoded); dbReplace(c->db,c->argv[1],o); } - - o->ptr = sdssetbit(o->ptr,bitoffset,on); } + + byte = bitoffset >> 3; + bit = 7 - (bitoffset & 0x7); + on = bitvalue & 0x1; + o->ptr = sdsgrowsafe(o->ptr,byte+1); + ((char*)o->ptr)[byte] |= on << bit; + ((char*)o->ptr)[byte] &= ~((!on) << bit); + touchWatchedKey(c->db,c->argv[1]); server.dirty++; addReply(c,shared.cone); |