diff options
Diffstat (limited to 'src/t_hash.c')
-rw-r--r-- | src/t_hash.c | 112 |
1 files changed, 2 insertions, 110 deletions
diff --git a/src/t_hash.c b/src/t_hash.c index 26089fa72..d0f81c0d7 100644 --- a/src/t_hash.c +++ b/src/t_hash.c @@ -279,8 +279,8 @@ int hashTypeDelete(robj *o, sds field) { if (fptr != NULL) { fptr = lpFind(zl, fptr, (unsigned char*)field, sdslen(field), 1); if (fptr != NULL) { - zl = lpDelete(zl,fptr,&fptr); /* Delete the key. */ - zl = lpDelete(zl,fptr,&fptr); /* Delete the value. */ + /* Delete both of the key and the value. */ + zl = lpDeleteRangeWithEntry(zl,&fptr,2); o->ptr = zl; deleted = 1; } @@ -541,114 +541,6 @@ robj *hashTypeDup(robj *o) { return hobj; } -/* callback for hashZiplistConvertAndValidateIntegrity. - * Check that the ziplist doesn't have duplicate hash field names. - * The ziplist element pointed by 'p' will be converted and stored into listpack. */ -static int _hashZiplistEntryConvertAndValidation(unsigned char *p, void *userdata) { - unsigned char *str; - unsigned int slen; - long long vll; - - struct { - long count; - dict *fields; - unsigned char **lp; - } *data = userdata; - - if (!ziplistGet(p, &str, &slen, &vll)) - return 0; - - /* Even records are field names, add to dict and check that's not a dup */ - if (((data->count) & 1) == 0) { - sds field = str? sdsnewlen(str, slen): sdsfromlonglong(vll); - if (dictAdd(data->fields, field, NULL) != DICT_OK) { - /* Duplicate, return an error */ - sdsfree(field); - return 0; - } - } - - if (str) { - *(data->lp) = lpAppend(*(data->lp), (unsigned char*)str, slen); - } else { - *(data->lp) = lpAppendInteger(*(data->lp), vll); - } - - (data->count)++; - return 1; -} - -/* callback for to check the listpack doesn't have duplicate records */ -static int _hashListpackEntryValidation(unsigned char *p, void *userdata) { - struct { - long count; - dict *fields; - } *data = userdata; - - /* Even records are field names, add to dict and check that's not a dup */ - if (((data->count) & 1) == 0) { - unsigned char *str; - int64_t slen; - unsigned char buf[LP_INTBUF_SIZE]; - - str = lpGet(p, &slen, buf); - sds field = sdsnewlen(str, slen); - if (dictAdd(data->fields, field, NULL) != DICT_OK) { - /* Duplicate, return an error */ - sdsfree(field); - return 0; - } - } - - (data->count)++; - return 1; -} - -/* Validate the integrity of the data structure while converting it to - * listpack and storing it at 'lp'. - * The function is safe to call on non-validated ziplists, it returns 0 - * when encounter an integrity validation issue. */ -int hashZiplistConvertAndValidateIntegrity(unsigned char *zl, size_t size, unsigned char **lp) { - /* Keep track of the field names to locate duplicate ones */ - struct { - long count; - dict *fields; - unsigned char **lp; - } data = {0, dictCreate(&hashDictType), lp}; - - int ret = ziplistValidateIntegrity(zl, size, 1, _hashZiplistEntryConvertAndValidation, &data); - - /* make sure we have an even number of records. */ - if (data.count & 1) - ret = 0; - - dictRelease(data.fields); - return ret; -} - -/* Validate the integrity of the listpack structure. - * when `deep` is 0, only the integrity of the header is validated. - * when `deep` is 1, we scan all the entries one by one. */ -int hashListpackValidateIntegrity(unsigned char *lp, size_t size, int deep) { - if (!deep) - return lpValidateIntegrity(lp, size, 0, NULL, NULL); - - /* Keep track of the field names to locate duplicate ones */ - struct { - long count; - dict *fields; - } data = {0, dictCreate(&hashDictType)}; - - int ret = lpValidateIntegrity(lp, size, 1, _hashListpackEntryValidation, &data); - - /* make sure we have an even number of records. */ - if (data.count & 1) - ret = 0; - - dictRelease(data.fields); - return ret; -} - /* Create a new sds string from the listpack entry. */ sds hashSdsFromListpackEntry(listpackEntry *e) { return e->sval ? sdsnewlen(e->sval, e->slen) : sdsfromlonglong(e->lval); |