首先,在redis当中(我读的是4.0.11)没有实现由hashtable转为ziplist的可能,具体见代码:
点击(此处)折叠或打开
-
void hashTypeConvert(robj *o, int enc) {
-
if (o->encoding == OBJ_ENCODING_ZIPLIST) {
-
hashTypeConvertZiplist(o, enc);
-
} else if (o->encoding == OBJ_ENCODING_HT) {
-
serverPanic("Not implemented");
-
} else {
-
serverPanic("Unknown hash encoding");
-
}
- }
点击(此处)折叠或打开
-
void hashTypeTryConversion(robj *o, robj **argv, int start, int end) {
-
int i;
-
-
if (o->encoding != OBJ_ENCODING_ZIPLIST) return;
-
-
for (i = start; i <= end; i++) {
-
if (sdsEncodedObject(argv[i]) &&
-
sdslen(argv[i]->ptr) > server.hash_max_ziplist_value)
-
{
-
hashTypeConvert(o, OBJ_ENCODING_HT);
-
break;
-
}
-
}
- }
点击(此处)折叠或打开
-
# Hashes are encoded using a memory efficient data structure when they have a
-
# small number of entries, and the biggest entry does not exceed a given
-
# threshold. These thresholds can be configured using the following directives.
-
hash-max-ziplist-entries 512
- hash-max-ziplist-value 64
点击(此处)折叠或打开
-
void hashTypeConvertZiplist(robj *o, int enc) {
-
serverAssert(o->encoding == OBJ_ENCODING_ZIPLIST);
-
-
if (enc == OBJ_ENCODING_ZIPLIST) {
-
/* Nothing to do... */
-
-
} else if (enc == OBJ_ENCODING_HT) {
-
hashTypeIterator *hi;
-
dict *dict;
-
int ret;
-
-
hi = hashTypeInitIterator(o);
-
dict = dictCreate(&hashDictType, NULL);
-
-
while (hashTypeNext(hi) != C_ERR) {
-
sds key, value;
-
-
key = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_KEY);
-
value = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_VALUE);
-
ret = dictAdd(dict, key, value);
-
if (ret != DICT_OK) {
-
serverLogHexDump(LL_WARNING,"ziplist with dup elements dump",
-
o->ptr,ziplistBlobLen(o->ptr));
-
serverPanic("Ziplist corruption detected");
-
}
-
}
-
hashTypeReleaseIterator(hi);
-
zfree(o->ptr);
-
o->encoding = OBJ_ENCODING_HT;
-
o->ptr = dict;
-
} else {
-
serverPanic("Unknown hash encoding");
-
}
- }