1.简单动态字符串(simple dynamic string, SDS)

  定义:

  struct sdshdr {

         int len;//记录buf中使用的字节数量

         int free;//记录buf中未使用的字节数量

         char buf[];//字节数组,用于保存字符串

         //buf字节数组以’\0’结束,但是’\0’不计算在len之中,对于用户来说是透明的

  }

  SDS与C中的字符串相比,优势在于:

   O(1)时间复杂度获取字符串长度;杜绝缓冲区溢出(每次修改buf时会检查空间是否充足);提高修改字符串的效率(空间预分配和惰性释放空间,客观的说会浪费一定的空间,空间换时间);二进制安全(支持字符串中有空字符串);

2.链表和链表节点

  定义:双向链表的节点

  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;

  优点:很多值或者节点都存储起来了,访问节点长度、尾节点等时间复杂度降低,多态(value的类型是void*)

3.字典——哈希键的底层实现之一

  哈希表结构:

  typedef struct dictht {

           dictEntry **table;//哈希表数组

           unsigned long size;//哈希表大小

           unsigned long sizemask;//哈希表大小掩码

           unsigned long used;//哈希表已有节点数量

  } dictht;

  哈希表节点结构:

  type struct dictEntry {

           void *key;//

           union {//

                  void *val;

                  unit64_tu64;

                  int64_ts64;

           } v;

           struct dictEntry *next;//指向下个哈希表节点,形成链表

  } dictEntry;

  字典结构:

  typedef struct dict {

                dictType *type;//字典类型,为创建多态字典

                void *privdata;//保存需要传给类型特性函数的参数

                dictht ht[2];//字典只使用ht[0],rehash时才使用ht[1]

                int rehashidx;//记录了rehash的进度,默认是-1

  } dict;

  Redis的哈希表使用链地址法,rehash时将ht[0]上的值rehash到ht[1]上(涉及ht[1]的空间分配大小问题),然后把ht[1]作为ht[0],把ht[1]设置为空白哈希表

  渐进式rehash:在每一次增删改操作的时候,将ht[0]上对应的键值对写到ht[1]上,在某个时间点时,ht[0]上的值全部写到ht[1]上

4.跳跃表

  实现:主要由两个结构组成,zskiplist用于保存跳跃表信息,zskiplistNode用于表示跳跃表节点;每一个zskiplistNode有若干(1~32随机)层(每一层都有前进指针和跨度),还有后退指针、分值、成员对象obj;成员对象唯一,分值可相同;节点按照分值的大小进行排序,分值相同时按照成员对象的大小排序。

  用处:有序集合、集群节点中用作内部数据结构

5.整数集合

  定义:

  typedef struct intset {

                uint32_t encoding;

                uint32_t length;

                int8_t contents[];

  } intset;

  重点:整数集合升级,contents中保存的数据可能是16位、32位、64位的,会根据存入数据的位数对集合进行升级;不支持降级

  用处:集合元素全是整数的情况

6.压缩列表——列表键和哈希键的底层实现之一

  结构:zlbytes zltail zllen entry1 entry2…entryN zlend

  zlbytes:uint32_t,记录整个压缩列表的字节数

  zltail:uint32_t,记录压缩列表尾节点距离列表首地址有多少个字节

  zllen:uint16_t,记录压缩列表包含的节点数量

  entryN:压缩列表包含的节点

       previous_entry_length   前一节点的大小

          encoding   记录了节点content所保存的数据的类型和值

        content   节点的值

  zlend:uint8_t,特殊值0XFF,用于标记压缩列表的末端

  连锁更新:节点中previous_entry_length的长度是根据值的大小确定的,所以当更新前一节点的长度时,这个值所占的字节数可能会引起改变,因此需要更新更新节点的后续节点。如果更新节点的后续节点全部都需要更新,那么效率会很低,但是需要全部节点更新的概率极低,因此不需要考虑对效率的影响。

最新文章

  1. python csv用法
  2. webstorm node 3000端口被占用
  3. python第二天基础1-1
  4. nios II--实验7——数码管IP软件部分
  5. 第16章 Windows线程栈
  6. 使用ansible批量管理远程服务器
  7. Android+Eclipse+Java:在“正在启动 CrazySnake”期间发生了内部错误, java.lang.NullPointerException
  8. MFC编辑框换行实现
  9. MFC应用程序的开发流程
  10. javascript基础学习(十)
  11. SpringMVC接收复杂集合参数
  12. 读书笔记:《重来REWORK》
  13. 微信小程序生成带参数的二维码 小程序二维码
  14. javascript引擎执行的过程的理解--执行阶段
  15. JS对象2
  16. localforage调用setItem时出现DOMException错误的解决方法
  17. [转]angular2中ng alerts的使用教程
  18. Jmeter(十八)_Ubuntu部署jmeter与ant
  19. 通过IP获取所在城市
  20. canvas下载图片

热门文章

  1. 转 10 个 Nginx 的安全提示
  2. Volley源码分析(二)CacheDispatcher分析
  3. css里颜色的那些事儿(合法颜色值)
  4. docker swarm英文文档学习-5-在swarm模式中运行Docker引擎
  5. scrapy shell
  6. jq中each的中断
  7. 解决Android中,禁止ScrollView内的控件改变之后自动滚动 - 转
  8. 大数据入门第十九天——推荐系统与mahout(一)入门与概述
  9. 20155320 Exp3 免杀原理与实践
  10. STM32一键下载电路设计原理