文章插图
这个结构类似于JDK7以前的HashMap<String,Object>,当有两个或以上的键被分配到哈希数组的同一个索引上时,会产生哈希冲突 。Redis也使用链地址法来解决键冲突 。即每个哈希表节点都有一个next指针,多个哈希表节点用next指针构成一个单项链表,链地址法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位 。
Redis中的字典使用hashtable作为底层实现的话,每个字典会带有两个哈希表,一个平时使用,另一个仅在rehash(重新散列)时使用 。随着对哈希表的操作,键会逐渐增多或减少 。为了让哈希表的负载因子维持在一个合理范围内,Redis会对哈希表的大小进行扩展或收缩(rehash),也就是将ht【0】里面所有的键值对分多次、渐进式的rehash到ht【1】里 。
六、Set
Set集合对象的底层实现可以是intset(整数集合)或者hashtable(字典或者也叫哈希表) 。
文章插图
intset(整数集合)当一个集合只含有整数,并且元素不多时会使用intset(整数集合)作为Set集合对象的底层实现 。
???????typedefstructintset{ // 编码方式uint32_tencoding; // 集合包含的元素数量uint32_tlength; // 保存元素的数组int8_tcontents[]; } intset;sadd: intsetAdd---O(1)
smembers: intsetGetO(1)---O(N)
srem: intsetRemove---O(N)
slen: intsetlen ---O(1)
intset底层实现为有序,无重复数组保存集合元素 。intset这个结构里的整数数组的类型可以是16位的,32位的,64位的 。如果数组里所有的整数都是16位长度的,如果新加入一个32位的整数,那么整个16的数组将升级成一个32位的数组 。升级可以提升intset的灵活性,又可以节约内存,但不可逆 。
7.ZSet
ZSet有序集合对象底层实现可以是ziplist(压缩列表)或者skiplist(跳跃表) 。
文章插图
当一个有序集合的元素数量比较多或者成员是比较长的字符串时,Redis就使用skiplist(跳跃表)作为ZSet对象的底层实现 。
???????typedefstructzskiplist{ // 表头节点和表尾节点structzskiplistNode* header, * tail; // 表中节点的数量unsignedlonglength; // 表中层数最大的节点的层数intlevel; } zskiplist;typedefstructzskiplistNode{ // 成员对象robj *obj;// 分值doublescore; // 后退指针structzskiplistNode* backward; // 层structzskiplistLevel{ // 前进指针structzskiplistNode* forward; // 跨度---前进指针所指向节点与当前节点的距离unsignedintspan; } level[];} zskiplistNode;zadd---zslinsert---平均O(logN), 最坏O(N)
zrem---zsldelete---平均O(logN), 最坏O(N)
zrank--zslGetRank---平均O(logN), 最坏O(N)
文章插图
skiplist的查找时间复杂度是LogN,可以和平衡二叉树相当,但实现起来又比它简单 。 跳跃表(skiplist)是一种有序数据结构,它通过在某个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的 。
推荐阅读
- 利用openresty+lua+redis 实现封杀频繁恶意访问IP地址
- 泡茶技巧,泡茶会遇到的误区及各类泡茶技巧
- 武夷山岩茶肉桂,武夷山各岩区
- 松针茶价格,滇红茶的类型和特点
- 抖音带货卖什么类型产品热门 抖音带货做什么类型好
- 普洱茶班章,详解各种班章
- 黄山毛峰、黄山毛尖、之间的区别大吗?各地毛尖绿茶的品质特征
- Redis消息队列发展历程
- 卖家有淘宝违规行为会受到哪些处理? 淘宝卖家严重违规有哪几种类型
- PDC钻头各个部位!