• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Redis > 详解Redis中的双链表结构

详解Redis中的双链表结构

作者:zinss26914 字体:[增加 减小] 来源:互联网 时间:2017-05-11

zinss26914通过本文主要向大家介绍了redis内部结构详解,redis配置文件详解,redis详解,redis info详解,redis命令详解等相关知识,希望本文的分享对您有所帮助

Redis中双链表实现的基本结构:
1.节点结构

typedef struct listNode {
  struct listNode *prev; //前向节点
  struct listNode *next; //后向节点
  void *value;       //该节点的值
} listNode;

</div> </div>

2.双向链表结构

typedef struct list {
  listNode *head;       //头节点
  listNode *tail;        //尾节点
  void *(*dup)(void *ptr); //复制函数
  void (*free)(void *ptr);  //释放函数
  int (*match)(void *ptr, void *key); //匹配函数,查找节点使用
  unsigned long len;     //双向链表的长度即节点的个数
} list;

</div>

3.双向链表遍历器

typedef struct listIter {
  listNode *next;  //下一个节点
  int direction;
} listIter;

 方向定义

  #define AL_START_HEAD 0 //向前查找
  #define AL_START_TAIL 1  //向后查找

</div>

4.宏定义函数

#define listLength(l) ((l)->len)
#define listFirst(l) ((l)->head)
#define listLast(l) ((l)->tail)
#define listPrevNode(n) ((n)->prev)
#define listNextNode(n) ((n)->next)
#define listNodeValue(n) ((n)->value)

#define listSetDupMethod(l,m) ((l)->dup = (m))
#define listSetFreeMethod(l,m) ((l)->free = (m))
#define listSetMatchMethod(l,m) ((l)->match = (m))

#define listGetDupMethod(l) ((l)->dup)
#define listGetFree(l) ((l)->free)
#define listGetMatchMethod(l) ((l)->match)
</div> </div>

5.定义函数

list *listCreate(void); //创建一个新的链表。该链表可以使用AlFree()方法释放。

               //但使用AlFree()方法前需要释放用户释放私有节点的值。

               //如果没有创建成功,返回null;创建成功则返回指向新链表的指针。


void listRelease(list *list); //释放整个链表,此函数不会执行失败。调用zfree(list *list)方法,定义在Zmalloc.c中。


list *listAddNodeHead(list *list, void *value); //向链表头部中增加一个节点


list *listAddNodeTail(list *list, void *value);  //向链表尾部增加一个节点


list *listInsertNode(list *list, listNode *old_node, void *value, int after);//向某个节点位置插入节点 after为方向


void listDelNode(list *list, listNode *node);//从链表上删除特定节点,调用者释放特定私用节点的值。

                              //该函数不会执行失败
listIter *listGetIterator(list *list, int direction);//返回某个链表的迭代器。

                                 //迭代器的listNext()方法会返回链表的下个节点。direction是方向

                                //该函数不会执行失败。


listNode *listNext(listIter *iter);        


void listReleaseIterator(listIter *iter);      //释放迭代器的内存。


list *listDup(list *orig);                //复制整个链表。当内存溢出时返回null,成功时返回原链表的一个备份

                                //不管该方法是否执行成功,原链表不会改变。


listNode *listSearchKey(list *list, void *key); //从特定的链表查找key。成功则返回第一个匹配节点的指针

                                //如果没有匹配,则返回null。


listNode *listIndex(list *list, long index);   //序号从0开始,链表的头的索引为0.1为头节点的下个节点。一次类推。

                            //负整数用来表示从尾部开始计数。-1表示最后一个节点,-2倒数第二个节点

                             //如果超过链表的索引,则返回null


void listRewind(list *list, listIter *li) {
  li->next = list->head;
  li->direction = AL_START_HEAD;
}

void listRewindTail(list *list, listIter *li) {
  li->next = list->tail;
  li->direction = AL_START_TAIL;
}


void listRotate(list *list);         //旋转链表,移除尾节点并插入头部。

</div>

list结构和listNode结构的API
list和listNode都有它们自己的一族API,这里贴出来学习一下redis的源码(ps:下面的代码都是我仿照redis改写能直接编译运行的代码)

list *listCreate(void)

  /** 
   * 创建一个新列表 
   * 
   * T = O(1)                                                               
   */ 
  list *listCreate(void) 
  { 
    struct list *list; 
   
    // 为列表结构分配内存 
    list = (struct list *)malloc(sizeof(struct list)); 
    if (list == NULL) 
      return NULL; 
   
    // 初始化属性 
    list->head = list->tail = NULL; 
    list->len = 0; 
    list->dup = NULL; 
    list->free = NULL; 
    list->match = NULL; 
   
    return list; 
  } 

</div>


void listRelease(list *list)

 

  /** 
   * 释放整个列表 
   * 
   * T = O(N), N为列表长度 
   */ 
  void listRelease(list *list) 
  { 
    unsigned long len; 
    listNode *current, *next; 
   
    current = list->head; 
    len = list->len; 
   
    while (len --) { 
      next = current->next; 
      // 如果列表有自带的free方法,那么先对节点值调用它 
      if (list->free) list->free(current->value); 
      // 之后释放节点 
      free(current); 
      current = next; 
    } 
    free(list); 
  }  
</div> list *listAddNodeHead(list *list, void *value)</div>
  /** 
   * 新建一个包含给定value的节点,并将它加入到列表的表头 
   * 
   * T = O(1)                                                               
   */ 
  list *listAddNodeHead(list *list, void *value) 
  { 
    listNode *node; 
   
    node = (listNode *)malloc(sizeof(listNode)); 
    if (node == NULL) 
      return NULL; 
   
    node->value = value; 
   
    if (list->len == 0) { 
      // 第一个节点 
      list->head = list->tail = node; 
      node->prev = node->next = NULL; 
    } else { 
      // 不是第一个节点 
      node->prev = NULL; 
      node->next = list->head; 
      list->head->prev = node; 
      list->head = node; 
    } 
   
    list->len ++; 
   
    return list; 
  } 

</div>


list *listAddNodeTail(list *list, void *value)

  /** 
   * 新建一个包含给定value的节点,并把它加入到列表的表尾 
   * 
   * T = O(1) 
   */ 
  list *listAddNodeTail(list *list, void *value) 
  { 
    listNode *node; 
     
    node = (listNode *)malloc(sizeof(listNode)); 
    if (node == NULL) 
      return NULL; 
   
    if (list->len == 0) { 
      // 第一个节点 
      list->head = list->tail = node; 
      node->prev = node->next = NULL; 
    } else { 
      // 不是第一节点 
      node->prev = list->tail; 
      node->next = NULL; 
      list->tail->next = node; 
      list->tail = node; 
    } 
   
    list->len ++; 
   
    return list; 
  } 

</div>


list *listInsertNode(list *list, listNode *old_node, void *value, int after)

 

  /** 
   * 创建一个包含值value的节点 
   * 并根据after参数的指示,将新节点插入到old_node的之前或者之后 
   * 
   * T = O(1) 
   */ 
  list *listInsertNode(list *list, listNode *old_node, void *value, int after) 
  { 
    listNode *node; 
   
    node = (listNode *)malloc(sizeof(listNode)); 
    if (node == NULL) 
      return NULL; 
   
    if (after) { 
      // 插入到old_node之后 
      node->prev = old_node; 
      node->next = old_node->next; 
      // 处
  


 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 详解Redis中的双链表结构
  • Redis教程(十三):管线详解
  • Redis教程(八):事务详解

相关文章

  • 2017-05-11Redis Sentinel服务配置流程(详解)
  • 2017-05-11Windows下Redis安装配置教程
  • 2017-05-11Redis的使用模式之计数器模式实例
  • 2017-05-11Redis教程之代理ip池设计方法详解
  • 2017-08-22关于redis启动时报错:Could not get a resource from the pool。
  • 2017-05-11Redis02 使用Redis数据库(String类型)全面解析
  • 2017-05-11windows环境下Redis+Spring缓存实例讲解
  • 2017-05-11详解SSH框架和Redis的整合
  • 2017-05-11浅谈Redis在分布式系统中的协调性运用
  • 2017-05-11利用yum安装Redis的方法详解

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • redis配置文件redis.conf中文版(基于2.4)
    • Redis的使用模式之计数器模式实例
    • centos安装redis
    • Redis教程(十五):C语言连接操作代码实例
    • Windows下Redis安装配置教程
    • Redis教程之代理ip池设计方法详解
    • Redis列表类型的常用命令小结
    • 让Redis在你的系统中发挥更大作用的几点建议
    • Redis Stat的安装指南
    • Redis上实现分布式锁以提高性能的方案研究

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有