zoukankan      html  css  js  c++  java
  • redis源码分析(3)-- 基本数据结构双链表list

    一、双链表结构

    redis中实现的双链表结构体如下:

    1 typedef struct list {
    2     listNode *head; # 链表头
    3     listNode *tail; # 链表尾
    4     void *(*dup)(void *ptr); # 复制链表函数
    5     void (*free)(void *ptr); # 释放节点函数
    6     int (*match)(void *ptr, void *key); # 匹配函数
    7     unsigned long len; # 链表节点个数
    8 } list;

    包含三个节点的list组成如图:

    每个listNode的结构:

    1 typedef struct listNode {
    2     struct listNode *prev;
    3     struct listNode *next;
    4     void *value;
    5 } listNode;

    Redis链表list特点:

    1、双端:每个节点包括前向指针prev和后级指针next,获取节点前后节点都是O(1)

    2、无环:首节点prev=NULL,尾节点next=NULL

    3、list结构包含表头指针和表尾指针,获取头尾节点时间复杂度O(1)

    4、list包含节点计数器len,获取节点长度只需要O(1)

    5、多态; 节点value为void*, 并且可以通过函数指针dup、free、match为节点设置属性。

    二、list迭代器

    链表其他操作比较简单,这里主要介绍list中的迭代器使用。先看下迭代器在遍历链表中的应用

     1 listNode *listSearchKey(list *list, void *key)
     2 {
     3     listIter *iter;
     4     listNode *node;
     5 
     6     iter = listGetIterator(list, AL_START_HEAD); # 获取从头开始的迭代器
     7     while((node = listNext(iter)) != NULL) { # 从迭代器依次获取下个节点,并开始遍历
     8         if (list->match) {
     9             if (list->match(node->value, key)) {
    10                 listReleaseIterator(iter);
    11                 return node;
    12             }
    13         } else {
    14             if (key == node->value) {
    15                 listReleaseIterator(iter);
    16                 return node;
    17             }
    18         }
    19     }
    20     listReleaseIterator(iter); # 释放迭代器
    21     return NULL;
    22 }

     获取迭代器源码:

     1 listIter *listGetIterator(list *list, int direction)
     2 {
     3     listIter *iter;
     4 
     5     if ((iter = zmalloc(sizeof(*iter))) == NULL) return NULL;
     6     if (direction == AL_START_HEAD) # 根据direction,得到链表头或者链表尾节点
     7         iter->next = list->head;
     8     else
     9         iter->next = list->tail;
    10     iter->direction = direction;
    11     return iter;
    12 }

    迭代器结构:

    1 typedef struct listIter {
    2     listNode *next;
    3     int direction;
    4 } listIter;

    三、链表操作

  • 相关阅读:
    Access使用记录
    html js 表单提交前检测数据
    asp.net mvc5 action多个参数
    asp.net mvc Areas 母版页动态获取数据进行渲染
    asp.net mvc 自定义全局过滤器 验证用户是否登录
    .net 报错汇总——持续更新
    数据库基础
    Python协程
    Python 线程
    Python 队列
  • 原文地址:https://www.cnblogs.com/ym65536/p/7220413.html
Copyright © 2011-2022 走看看