Bitops: Stop overallocating storage space on set

Previously the string was created empty then re-sized
to fit the offset, but sds resize causes the sds to
over-allocate by at least 1 MB (which is a lot when
you are operating at bit-level access).

This also improves the speed of initial sets by 2% to 6%
based on quick testing.

Patch logic provided by @oranagra

Fixes #1918
This commit is contained in:
Matt Stancliff 2014-08-07 09:43:16 -04:00
parent 3cd36a4dd9
commit badf0f008b
2 changed files with 4 additions and 6 deletions

View File

@ -229,19 +229,17 @@ void setbitCommand(redisClient *c) {
return;
}
byte = bitoffset >> 3;
o = lookupKeyWrite(c->db,c->argv[1]);
if (o == NULL) {
o = createObject(REDIS_STRING,sdsempty());
o = createObject(REDIS_STRING,sdsnewlen(NULL, byte+1));
dbAdd(c->db,c->argv[1],o);
} else {
if (checkType(c,o,REDIS_STRING)) return;
o = dbUnshareStringValue(c->db,c->argv[1],o);
o->ptr = sdsgrowzero(o->ptr,byte+1);
}
/* Grow sds value to the right length if necessary */
byte = bitoffset >> 3;
o->ptr = sdsgrowzero(o->ptr,byte+1);
/* Get current values */
byteval = ((uint8_t*)o->ptr)[byte];
bit = 7 - (bitoffset & 0x7);

View File

@ -194,7 +194,7 @@ void setrangeCommand(redisClient *c) {
if (checkStringLength(c,offset+sdslen(value)) != REDIS_OK)
return;
o = createObject(REDIS_STRING,sdsempty());
o = createObject(REDIS_STRING,sdsnewlen(NULL, offset+sdslen(value)));
dbAdd(c->db,c->argv[1],o);
} else {
size_t olen;