标签:分配 inf vda oid 类型 特定 键值 表示 技术分享
Redis Map 存储K-V键值对。(跟Java的Map类比)
哈希表结构:
typedef struct dictht {
dictEntry **table; //哈希表数组
unsigned long size; //哈希表大小
unsigned long sizemask; //哈希表掩码,用于计算索引值。总是等于 size - 1
unsigned long used; //该哈希表已有节点的数量
} dictht;
哈希表节点结构:
typedef struct dictEntry {
void *key; //键
union{ //值
void *val;
uint64_t u64;
int64_t s64;
} v;
struct dictEntry *next; //指向下一个哈希表节点,形成链表。
}
字典结构:
typedef struct dict {
dictType *type; //类型特定函数
void *privdata; //私有数据
dictht ht[2]; //哈希表数组,长度为2。一般情况下使用h[0],在rehash时,使用h[1]进行过渡。
int trehashidx; // rehash 索引,当rehash不在进行时,值为 -1。配合ht[2]进行rehash。
}
结构图如下:
哈希算法,如何添加一个新值:
1、计算k的hash值。
2、由是否进行rehash决定使用h[0],还是h[1](rehash时,用h[1])。
3、根据k的hash值和sizeMask计算(hash(K) & sizeMash), 得到 table中的 dictEntry[?] 的位置。
4、用链表法,解决hash冲突。
rehash : 重新哈希
1、为ht[1]分配空间。扩展的大小为 ht[0].used 的第一个大于 2n的数。修改trehashidx标识0。
2、将ht[0]的数据,重新计算得到dictEntry的位置,存入ht[1]。
3、数据完成迁移后,将ht[0],ht[1]的指针对调。修改trehashidx表示为-1。
4、哈希方式为渐进式哈希。哈希期间,会操作两个ht。(在ht[1]进行添加操作;先在ht[0]进行删除操作,再到ht[1])
标签:分配 inf vda oid 类型 特定 键值 表示 技术分享
原文地址:https://www.cnblogs.com/chen--biao/p/9813874.html