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

Redis学习笔记之底层数据结构的更多相关文章

  1. Redis学习笔记一:数据结构与对象

    1. String(SDS) Redis使用自定义的一种字符串结构SDS来作为字符串的表示. 127.0.0.1:6379> set name liushijie OK 在如上操作中,name( ...

  2. redis学习笔记——内存映射数据结构

    内存映射数据结构 解决问题:当一个对象包含的元素数量并不多,或者元素本身的体积并不大时,使用代价高昂的内部数据结构并不是最好的办法. 内存映射数据结构是一系列经过特殊编码的字节序列,创建它们所消耗的内 ...

  3. Redis学习笔记~目录

    回到占占推荐博客索引 百度百科 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...

  4. Redis学习笔记(3)——Redis的命令大全

    Redis是一种nosql数据库,常被称作数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted se ...

  5. Redis学习笔记(1)——Redis简介

    一.Redis是什么? Remote Dictionary Server(Redis) 是一个开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value ...

  6. Redis学习笔记(二) Redis 数据类型

    Redis 支持五种数据类型:string(字符串).list(列表).hash(哈希).set(集合)和 zset(有序集合),接下来我们讲解分别讲解一下这五种类型的的使用. String(字符串) ...

  7. redis学习笔记(详细)——高级篇

    redis学习笔记(详细)--初级篇 redis学习笔记(详细)--高级篇 redis配置文件介绍 linux环境下配置大于编程 redis 的配置文件位于 Redis 安装目录下,文件名为 redi ...

  8. redis 学习笔记(6)-cluster集群搭建

    上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...

  9. Redis学习笔记4-Redis配置详解

    在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server   xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...

随机推荐

  1. 2018.08.31 19:41 自学go语言

    有的人是从最基础的开始学,而我却是从最简单开始学,学着调试,学着编程,其实我也是编程小白,好多的不懂,我不明白很多都可以用云完成了,为什么还要继续自己编程,不明白,但是有需求吧,有需求是件好事情,说明 ...

  2. sql注入--基础

    什么是sql注入: 利用SQL语句 在外部 对数据库进行 查询,更新等 动作 sql注入的原理: 输入值可控且带入数据库执行(前提) 接受的变量传值未进行过滤(实质) sql注入的目的: 获取数据(网 ...

  3. Beta阶段第一次冲刺

    Beta阶段第一次冲刺 以后严格按照Git标准来,组员有上传Git的才有贡献分没有的为0 代码签入图 1.part1 -站立式会议照片 2.part2 -项目燃尽图 3.part3 -项目进展 1.正 ...

  4. 【转】IE内嵌google chrome frame解决浏览器兼容问题

    参考文献: http://www.pseudowired.com/2012/12/04/tomcat-http-header-manipulation/(html中自动添加使用chrome的heade ...

  5. java读写properties配置文件不改变属性的顺序和注释

    先贴代码 import java.io.BufferedWriter; import java.io.File; import java.io.FileInputStream; import java ...

  6. OpenCV——LBP(Local Binary Patterns)特征检测

    #include <opencv2/opencv.hpp> #include <iostream> #include "math.h" using name ...

  7. js 自己项目中几种打开或弹出页面的方法

    自己项目中,几种打开或弹出页面的方法(部分需要特定环境下) var blnTop = false;//是否在顶层显示 ///动态生成模态窗体(通过字符串生成) ///strModalId:模态窗体ID ...

  8. 大数据入门第十九天——推荐系统与mahout(一)入门与概述

    一.推荐系统概述 为了解决信息过载和用户无明确需求的问题,找到用户感兴趣的物品,才有了个性化推荐系统.其实,解决信息过载的问题,代表性的解决方案是分类目录和搜索引擎,如hao123,电商首页的分类目录 ...

  9. Django Rest Framework源码剖析(一)-----认证

    一.简介 Django REST Framework(简称DRF),是一个用于构建Web API的强大且灵活的工具包. 先说说REST:REST是一种Web API设计标准,是目前比较成熟的一套互联网 ...

  10. 20155204 王昊《网络对抗技术》EXP2 后门原理与实践

    20155204 王昊<网络对抗技术>EXP2 后门原理与实践 一.实验内容 准备工作(试用ncat.socat) 1. 使用netcat获取主机操作Shell,cron启动. 明确目标: ...