摘要:注明设计与实现的个人学习总结,这本书对的讲解清晰易懂,如果深入学习可以看看这本书。字典的实现字典使用哈希表作为底层实现,每个哈希节点就是对应一个键值对。
注明:《Redis设计与实现》的个人学习总结,这本书对redis的讲解清晰易懂,如果深入学习可以看看这本书。
几个问题。
SET msg "hello world"
RPUSH fruits "apple" "banana" "cherry"
那么为什么会使用SDS而不是直接使用c语言的字符?
struct sdshdr {//记录buf数组中已使用字节的数量//等于SDS所保存字符串的长度int len;//记录buf数组中未使用字节的数量int free;//字节数组,用于保存字符串char buf[];};
free是0说明SDS已经没有任何分配空间了
len说明SDS保存一个5个字节长的字符串。
buf就是一个char数组,保存前5个字节的字符,最后一个字符串是’/0’
sds的/0结尾是通过sds函数处理,方便调用c语言的函数。比如printf("%s", s->buf);
也就是说c语言的字符串获取长度时间复杂度高,但是sds结构可以解决这个问题
对于c语言的字符串来说不记录长度如果字符串太长就会导致溢出。
string.h/strcat函数可以帮助把旧的字符串迁移到新的长度的字符串完成长度上的更新。
下面这个案例的意思就是s1和s2内存上紧挨在一起,这个时候需要把 Cluster合并到s1,但是由于s1没有分配足够空间,导致cluster覆盖了s2的字符串。
strcat(s1, " Cluster");
strcat(s, " Cluster");//s=Redis
strcat(s, " Tutorial");//s=Redis Cluster
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UukUwins-1637070235390)(C:/Users/11914/AppData/Roaming/Typora/typora-user-images/image-20211116123133740.png)]
sdstrim(s, "XY"); //移除SDS字符串中的所有"X"和"Y"
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J1rXMBxY-1637070235391)(C:/Users/11914/AppData/Roaming/Typora/typora-user-images/image-20211116123145031.png)]
strcasecmp(sds->buf, "hello world");
sds优点
redis> LLEN integers(integer) 1024redis> LRANGE integers 0 101)"1"2)"2"3)"3"4)"4"5)"5"6)"6"7)"7"8)"8"9)"9"10)"10"11)"11"
typedef struct listNode {//前置节点struct listNode * prev;//后置节点struct listNode * next;//节点的值void * value;}listNode;
typedef struct list {//表头节点listNode * head;//表尾节点listNode * tail;//链表所包含的节点数量unsigned long len;//节点值复制函数void *(*dup)(void *ptr);//节点值释放函数void (*free)(void *ptr);//节点值对比函数int (*match)(void *ptr,void *key);} list;
redis链表的特性
SET msg "hello world"
redis> HLEN website(integer) 10086redis> HGETALL website1)"Redis"2)"Redis.io"3)"MariaDB"4)"MariaDB.org"5)"MongoDB"6)"MongoDB.org"# ...
typedef struct dictht {//哈希表数组dictEntry **table;//哈希表大小unsigned long size;//哈希表大小掩码,用于计算索引值//总是等于size-1unsigned long sizemask;//该哈希表已有节点的数量unsigned long used;} dictht;
typedef struct dictEntry {//键void *key;//值union{void *val;uint64_tu64;int64_ts64;} v;//指向下个哈希表节点,形成链表struct dictEntry *next;} dictEntry;
typedef struct dict {//类型特定函数dictType *type;//私有数据void *privdata;//哈希表dictht ht[2];// rehash索引//当rehash不在进行时,值为-1in trehashidx; /* rehashing not in progress if rehashidx == -1 */} dict;
typedef struct dictType {//计算哈希值的函数unsigned int (*hashFunction)(const void *key);//复制键的函数void *(*keyDup)(void *privdata, const void *key);//复制值的函数void *(*valDup)(void *privdata, const void *obj);//对比键的函数int (*keyCompare)(void *privdata, const void *key1, const void *key2);//销毁键的函数void (*keyDestructor)(void *privdata, void *key);//销毁值的函数void (*valDestructor)(void *privdata, void *obj);} dictType;
ht两个项都是dictht哈希表,通常只会是调用ht[0],ht[1]用于对ht[0]rehash使用的。
rehashidx记录rehash进度。如果没有rehash那么就是-1。
下面这个就是普通状态下的字典。
#使用字典设置的哈希函数,计算键key的哈希值hash = dict->type->hashFunction(key);#使用哈希表的sizemask属性和哈希值,计算出索引值#根据情况不同,ht[x]可以是ht[0]或者ht[1]index = hash & dict->ht[x].sizemask;
键值对增加,导致哈希因子也在上升,也就是哈希表的已用大小和哈希表大小的比值,这个时候就需要进行扩容。
可以通过rehash重新散列进行扩容。
把ht[0]的键值对rehash到ht[1]中。
转移之后释放ht[0]将ht[1]设置为ht[0],为下一次rehash做准备
可以看看下面的扩容used原本是4,现在扩容到used*2的第一个2^n也就是8。
满足一下条件就要执行拓展
负载因子的计算公式。
负载因子=哈希表已保存节点数量/哈希表大小load_factor = ht[0].used / ht[0].size
redis> ZRANGE fruit-price 0 2 WITHSCORES1)"banana"2)"5"3)"cherry"4)"6.5"5)"apple"6)"8"redis> ZCARD fruit-price(integer)130
typedef struct zskiplistNode {//层struct zskiplistLevel {//前进指针struct zskiplistNode *forward;//跨度unsigned int span;} level[];//后退指针struct zskiplistNode *backward;//分值double score;//成员对象robj *obj;} zskiplistNode;
记录两个节点的距离。
指向null那么就是0
跨度用于计算排位的。查找某个节点走过的所有层跨度就是目标节点在跳跃表的排位。
比如找o3,这个时候只是通过第一个节点L5到最后一个节点的L5而且跨度是3。所以目标节点排位也是3。
typedef struct zskiplist {//表头节点和表尾节点structz skiplistNode *header, *tail;//表中节点的数量unsigned long length;//表中层数最大的节点的层数int level;} zskiplist;
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/123732.html
摘要:三年百度,五年阿里,阿里架构师浅谈我是如何顺利进入前些天在我群里认识了以为挺有意思的老哥,他也是工作年多技术和面试都不差,最近也是在找工作,是从京城来魔都的,也和他捞了不少。 说来惭愧,也不怕你们笑话。做开发8年多,到目前还是一名不折不扣的扫地僧。年前的辞职,到现在还在家静养中。其实也没什么,就是回家总结一下自己这些年来在外工作与面试等做一个简单的总结与反思。做一下自己后面一个人生规划...
摘要:三年百度,五年阿里,阿里架构师浅谈我是如何顺利进入前些天在我群里认识了以为挺有意思的老哥,他也是工作年多技术和面试都不差,最近也是在找工作,是从京城来魔都的,也和他捞了不少。 说来惭愧,也不怕你们笑话。做开发8年多,到目前还是一名不折不扣的扫地僧。年前的辞职,到现在还在家静养中。其实也没什么,就是回家总结一下自己这些年来在外工作与面试等做一个简单的总结与反思。做一下自己后面一个人生规划...
摘要:总体来说,玄武科技的真的很热情,为他们点个赞,虽然自己最后没能去玄武科技,然后就是技术面非常简单,面和高管面也都还好,不会有压抑的感觉,总体聊得很愉快。 该文已加入开源文档:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识)。地址:https://github.com/Snailclimb... 秋招历程流水账总结 笔主大四准毕业生,在秋招末流比较幸运地进入了一家...
摘要:腾讯云目前分别提供主从版集群版新一代三个版本。目前腾讯云作业平台已建成数百种场景化的工作流程,日调用次数达上千次,覆盖大部分的运维场景,变更导致的事故减少,服务更为稳定可靠,场景化运维工作效率提升。 本文由云+社区发表作者:冯伟源 作者:冯伟源,高级工程师,腾讯云Redis系统运维负责人。6年DBA经验,一直从事SQL优化、实例调优、数据库架构、海量数据库集群运维、运营平台建设和管理...
摘要:编程书籍的整理和收集最近一直在学习深度学习和机器学习的东西,发现深入地去学习就需要不断的去提高自己算法和高数的能力然后也找了很多的书和文章,随着不断的学习,也整理了下自己的学习笔记准备分享出来给大家后续的文章和总结会继续分享,先分享一部分的 编程书籍的整理和收集 最近一直在学习deep learning深度学习和机器学习的东西,发现深入地去学习就需要不断的去提高自己算法和高数的能力然后...
阅读 1860·2021-11-24 09:39
阅读 1192·2021-11-23 09:51
阅读 2969·2021-11-18 10:02
阅读 3187·2021-09-22 16:00
阅读 3204·2021-09-07 10:26
阅读 2665·2019-08-30 15:55
阅读 2670·2019-08-30 13:48
阅读 1207·2019-08-30 12:58