Redis---hash

概况:

不仅是提供出的数据结构(与字符串,列表。。。并列)(内层),也是redis存储的数据结构(外层)。

内部编码:

a) 使用压缩列表 (ziplist):

  1. 元素数量小于512
  2. 所有key, value长度小于64字节

b) 使用哈希表 (hashtable):

 

由1个dict,2个dictht,1个dictEntry指针数组(bucket),多个dictEntry组成。

 

dict, 最上层结构,为了便于rehash设计了冗余结构:

一般来说,dictht和dictEntry就可实现普通哈希的功能。

typedef struct dict{
    dictType *type;
    void *privdata;
    dictht ht[2];
    int trehashidx;
} dict;

dictht, 未扩容前,只有1个dictht有值:

typedef struct dictht{
    dictEntry **table;   --- 指向bucket的指针
    unsigned long size;  --- 记录bucket的大小
    unsigned long sizemask;  --- 值总是为size-1,这个属性和哈希值一起决定一个键在table中存储的位置
    unsigned long used;  --- 已使用的dictEntry的数量
}dictht;

bucket,指针数组:

大小为大于数组容量的,最大的2^n次方。
例如,如果有1000个dictEntry,那么bucket大小为1024;如果有1500个dictEntry,则bucket大小为2048

dictEntry,保存键值对:

typedef struct dictEntry{
    void *key;    --- 键值对的key
    union{        --- 键值对的value,共同体(指针、整型)
        void *val;
        uint64_tu64;
        int64_ts64;
    }v;
    struct dictEntry *next;  ---指向下一个dictEntry,解决哈希冲突
}dictEntry;

 

 

Rehash: 

  1.   (load factor) = ht[0].used / ht[0].size
  2.  扩容 ====> 第一个大于等于ht[0].used*2的2^n:
    • 没有执行BGSAVE和BGREWRITEAOF情况下,加载因子>=1
    • 正在执行BGSAVE和BGREWRITEAOF指令的情况下,加载因子>=5
  3. 收缩 =====> 第一个大于等于ht[0].used的2^n:
    • 没有执行BGSAVE和BGREWRITEAOF情况下,加载因子>=1

 

posted @ 2020-05-20 21:55  crossdunk  阅读(117)  评论(0)    收藏  举报