redis当中哈希对象的底层存储使用的是ziplist和hashtable,其中个人觉得比较有意思的就是类型转换这一块了
首先,在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");
-
}
-
}
其次,发生转换的条件是:1)当前编码为ziplist;2)当前ziplist当中的entry个数大于512,或者ziplist当中最长的key/value占用字节大于64字节时。具体代码如下:
-
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;
-
}
-
}
-
}
其中的512和64是可以通过redis.conf中的两个配置项更改的,具体如下:
-
# 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
转化的流程就是遍历ziplist当中的key/value对,逐个插入到新建的hashtable当中,最后释放原有数据,将object当中的ptr指向新的hashtable,具体代码如下:
-
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");
-
}
-
}
其余的命令实现,底层都是基于ziplist和hashtable的操作,参数解析什么的也都同字符串模型和list模型,这里就不再赘述了。还请大家多提宝贵意见~~~
阅读(2238) | 评论(0) | 转发(0) |