summaryrefslogtreecommitdiff
path: root/src/t_hash.c
diff options
context:
space:
mode:
authorPieter Noordhuis <pcnoordhuis@gmail.com>2012-01-03 15:48:55 -0800
committerPieter Noordhuis <pcnoordhuis@gmail.com>2012-01-03 16:13:42 -0800
commitfe458402014cdd98a10179c85899f1eca0307534 (patch)
tree95e27c817f6652ef2908663fbc74709791e1f02e /src/t_hash.c
parentebd85e9a455df689c9be02a93354f580df4cafd8 (diff)
downloadredis-fe458402014cdd98a10179c85899f1eca0307534.tar.gz
Implements ziplistFind
To improve the performance of the ziplist implementation, some functions have been converted to macros to avoid unnecessary stack movement and duplicate variable assignments.
Diffstat (limited to 'src/t_hash.c')
-rw-r--r--src/t_hash.c68
1 files changed, 28 insertions, 40 deletions
diff --git a/src/t_hash.c b/src/t_hash.c
index 9699223a8..a22de2429 100644
--- a/src/t_hash.c
+++ b/src/t_hash.c
@@ -47,23 +47,18 @@ int hashTypeGetFromZiplist(robj *o, robj *field,
zl = o->ptr;
fptr = ziplistIndex(zl, ZIPLIST_HEAD);
- while (fptr != NULL) {
- /* Grab pointer to the value (fptr points to the field) */
- vptr = ziplistNext(zl, fptr);
- redisAssert(vptr != NULL);
-
- /* Compare field in ziplist with specified field */
- if (ziplistCompare(fptr, field->ptr, sdslen(field->ptr))) {
- break;
+ if (fptr != NULL) {
+ fptr = ziplistFind(fptr, field->ptr, sdslen(field->ptr), 1);
+ if (fptr != NULL) {
+ /* Grab pointer to the value (fptr points to the field) */
+ vptr = ziplistNext(zl, fptr);
+ redisAssert(vptr != NULL);
}
-
- /* Skip over value */
- fptr = ziplistNext(zl, vptr);
}
decrRefCount(field);
- if (fptr != NULL) {
+ if (vptr != NULL) {
ret = ziplistGet(vptr, vstr, vlen, vll);
redisAssert(ret);
return 0;
@@ -164,27 +159,28 @@ int hashTypeSet(robj *o, robj *field, robj *value) {
zl = o->ptr;
fptr = ziplistIndex(zl, ZIPLIST_HEAD);
- while (fptr != NULL) {
- /* Compare field in ziplist with specified field */
- if (ziplistCompare(fptr, field->ptr, sdslen(field->ptr))) {
- zl = ziplistDelete(zl,&fptr);
- zl = ziplistDelete(zl,&fptr);
- o->ptr = zl;
+ if (fptr != NULL) {
+ fptr = ziplistFind(fptr, field->ptr, sdslen(field->ptr), 1);
+ if (fptr != NULL) {
+ /* Grab pointer to the value (fptr points to the field) */
+ vptr = ziplistNext(zl, fptr);
+ redisAssert(vptr != NULL);
update = 1;
- break;
- }
- /* Grab pointer to the value (fptr points to the field) */
- vptr = ziplistNext(zl, fptr);
- redisAssert(vptr != NULL);
+ /* Delete value */
+ zl = ziplistDelete(zl, &vptr);
- /* Grab pointer (if any) to the next field */
- fptr = ziplistNext(zl, vptr);
+ /* Insert new value */
+ zl = ziplistInsert(zl, vptr, value->ptr, sdslen(value->ptr));
+ }
+ }
+
+ if (!update) {
+ /* Push new field/value pair onto the tail of the ziplist */
+ zl = ziplistPush(zl, field->ptr, sdslen(field->ptr), ZIPLIST_TAIL);
+ zl = ziplistPush(zl, value->ptr, sdslen(value->ptr), ZIPLIST_TAIL);
}
- /* Push new field/value pair onto the tail of the ziplist */
- zl = ziplistPush(zl, field->ptr, sdslen(field->ptr), ZIPLIST_TAIL);
- zl = ziplistPush(zl, value->ptr, sdslen(value->ptr), ZIPLIST_TAIL);
o->ptr = zl;
decrRefCount(field);
@@ -217,28 +213,20 @@ int hashTypeDelete(robj *o, robj *field) {
int deleted = 0;
if (o->encoding == REDIS_ENCODING_ZIPLIST) {
- unsigned char *zl, *fptr, *vptr;
+ unsigned char *zl, *fptr;
field = getDecodedObject(field);
zl = o->ptr;
fptr = ziplistIndex(zl, ZIPLIST_HEAD);
- while (fptr != NULL) {
- /* Compare field in ziplist with specified field */
- if (ziplistCompare(fptr, field->ptr, sdslen(field->ptr))) {
+ if (fptr != NULL) {
+ fptr = ziplistFind(fptr, field->ptr, sdslen(field->ptr), 1);
+ if (fptr != NULL) {
zl = ziplistDelete(zl,&fptr);
zl = ziplistDelete(zl,&fptr);
o->ptr = zl;
deleted = 1;
- break;
}
-
- /* Grab pointer to the value (fptr points to the field) */
- vptr = ziplistNext(zl, fptr);
- redisAssert(vptr != NULL);
-
- /* Grab pointer (if any) to the next field */
- fptr = ziplistNext(zl, vptr);
}
decrRefCount(field);