同样的hash类型对象也有两种编码方式,一种是压缩列表,一种是哈希表哈希对象默认创建的是压缩列表编码方式,当达到一定条件后会转换成哈希编码方式

#define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define REDIS_ENCODING_HT 2      /* Encoded as hash table */

// 创建一个哈希对象
robj *createHashObject(void) {
    unsigned char *zl = ziplistNew();
    robj *o = createObject(REDIS_HASH, zl);
    o->encoding = REDIS_ENCODING_ZIPLIST;
    return o;
}

//常见的条件有以下这些
#define REDIS_HASH_MAX_ZIPLIST_ENTRIES 512
#define REDIS_HASH_MAX_ZIPLIST_VALUE 64

server.hash_max_ziplist_entries 保存的键值数量小于默认值512
server.hash_max_ziplist_value  键值的长度都小于默认值64字节


// 具体的转换函数为hashTypeConvert
void hashTypeConvert(robj *o, int enc) {
    if (o->encoding == REDIS_ENCODING_ZIPLIST) {
        hashTypeConvertZiplist(o, enc);
    } else if (o->encoding == REDIS_ENCODING_HT) {
        redisPanic("Not implemented");
    } else {
        redisPanic("Unknown hash encoding");
    }
}

// 将REDIS_ENCODING_ZIPLIST编码对象转成REDIS_ENCODING_HT
void hashTypeConvertZiplist(robj *o, int enc) {
    redisAssert(o->encoding == REDIS_ENCODING_ZIPLIST);
    if (enc == REDIS_ENCODING_ZIPLIST) {
    } else if (enc == REDIS_ENCODING_HT) {
        hashTypeIterator *hi;
        dict *dict;
        int ret;
        hi = hashTypeInitIterator(o);
        dict = dictCreate(&hashDictType, NULL);
        while (hashTypeNext(hi) != REDIS_ERR) {
            robj *field, *value;
            field = hashTypeCurrentObject(hi, REDIS_HASH_KEY);
            field = tryObjectEncoding(field);


            value = hashTypeCurrentObject(hi, REDIS_HASH_VALUE);
            value = tryObjectEncoding(value);


            ret = dictAdd(dict, field, value);
            if (ret != DICT_OK) {
                redisLogHexDump(REDIS_WARNING,"ziplist with dup elements dump",
                    o->ptr,ziplistBlobLen(o->ptr));
                redisAssert(ret == DICT_OK);
            }
        }

        hashTypeReleaseIterator(hi);
        zfree(o->ptr);
        // 转换编码方式和新的字典
        o->encoding = REDIS_ENCODING_HT;
        o->ptr = dict;

    } else {
        redisPanic("Unknown hash encoding");
    }
}

基于版本3.0.0版本,点击下载https://download.redis.io/releases/redis-3.0.0.tar.gz

本文地址,https://www.ccagml.com/?p=424

发表评论