Redis源代码-数据结构Adlist双端列表

Redis的Adlist实现了数据结构中的双端链表,整个结构例如以下:

链表节点定义:

typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

链表定义:

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;

当中的三个函数指针先不用管,后面遇到了再看详细是干什么的,另外还实现了一个迭代器,有点c++的味道在里面

typedef struct listIter {
    listNode *next;
    int direction;
} listIter;

链表三要素。创建,插入,和删除

list *listCreate(void)
{
    struct list *list;

    if ((list = malloc(sizeof(*list))) == NULL)
        return NULL;
    list->head = list->tail = NULL;
    list->len = 0;
    list->dup = NULL;
    list->free = NULL;
    list->match = NULL;
    return list;
}

插入分为从头部插入和尾部插入,源码实现头部都有非常清晰的凝视,告诉这个函数的一些细节,作者非常是用心:

list *listAddNodeHead(list *list, void *value)
{
    listNode *node;

    if ((node = malloc(sizeof(*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;
}

释放内存

void listRelease(list *list)
{
    unsigned long len;
    listNode *current, *next;

    current = list->head;
    len = list->len;
    while(len--) {
        next = current->next;
        if (list->free) list->free(current->value);
        free(current);
        current = next;
    }
    free(list);
}

迭代器的创建,以后能够效仿这样的做法,迭代器分方向:

/* Returns a list iterator 'iter'. After the initialization every
 * call to listNext() will return the next element of the list.
 *
 * This function can't fail. */
listIter *listGetIterator(list *list, int direction)
{
    listIter *iter;

    if ((iter = malloc(sizeof(*iter))) == NULL) return NULL;
    if (direction == AL_START_HEAD)
        iter->next = list->head;
    else
        iter->next = list->tail;
    iter->direction = direction;
    return iter;
}

版权声明:本文博客原创文章。博客,未经同意,不得转载。

时间: 2024-10-14 11:53:43

Redis源代码-数据结构Adlist双端列表的相关文章

Redis源码-数据结构之Adlist双端链表

Redis的Adlist实现了数据结构中的双端链表,整个结构如下: 链表节点定义: typedef struct listNode { struct listNode *prev; struct listNode *next; void *value; } listNode; 链表定义: typedef struct list { listNode *head; listNode *tail; void *(*dup)(void *ptr); void (*free)(void *ptr); i

Java数据结构——用双端链表实现队列

//================================================= // File Name : LinkQueue_demo //------------------------------------------------------------------------------ // Author : Common //类名:FirstLastList //属性: //方法: class FirstLastList_long{ private Lin

数据结构与算法分析 3.26 — 双端队列的实现

一.题目 编写支持双端队列的例程,插入与弹出操作均花费 O(1)时间 二.解答 双端队列(deque,全名double-ended queue)是一种具有队列和栈性质的数据结构. 双端队列中的元素可以从两端弹出,插入和删除操作限定在队列的两边进行. 基本操作:在双端队列两端插入与删除. ADT术语: Capacity:数组容量 Left:队列左端,指向队列左边第一个元素 Right:队列右端,指向队列右边最后一个元素的下一个位置 初始化:Left = Right = 0: 判空:   Left

Redis 基础数据结构与对象

Redis用到的底层数据结构有:简单动态字符串.双端链表.字典.压缩列表.整数集合.跳跃表等,Redis并没有直接使用这些数据结构来实现键值对数据库,而是基于这些数据结构创建了一个对象系统,这个系统包括字符串对象.列表对象.哈希对象.集合对象和有序结合对象共5种类型的对象. 1 简单动态字符串 redis自定义了简单动态字符串数据结构(sds),并将其作为默认字符串表示. struct sdshdr { unsigned int len; unsigned int free; char buf[

C++ STL 双端队列deque详解

一.解释 Deque(双端队列)是一种具有队列和栈的性质的数据结构.双端队列的元素可以从两端弹出,其限定插入和删除操作在表的两端进行. 二.常用操作: 1.头文件 #include <deque> 2.定义 a) deque<int>s1; b) deque<string>s2; c) deque<node>s3; /*node为结构体,可自行定义.*/ 3.常用操作 //a) 构造函数 deque<int> ideq //b)增加函数 ideq

PHP双向队列,双端队列代码

<?php /**  * User: jifei  * Date: 2013-07-30  * Time: 23:12 */ /**  * PHP实现双向队列,双端队列  * 双端队列(deque,全名double-ended queue)是一种具有队列和栈性质的数据结构.  * 双端队列中的元素可以从两端弹出,插入和删除操作限定在队列的两边进行.  */ class Deque {     public $queue=array();     /**      * 构造函数初始化队列     

第十一节 双端队列的概念和python代码实现

deque 即双端队列. (deque,全名double-ended queue)是一种具有队列和栈的性质的数据结构.双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行. 双端队列是限定插入和删除操作在表的两端进行的线性表.这两端分别称做端点1和端点2.也可像栈一样,可以用一个铁道转轨网络来比喻双端队列.在实际使用中,还可以有输出受限的双端队列(即一个端点允许插入和删除,另一个端点只允许插入的双端队列)和输入受限的双端队列(即一个端点允许插入和删除,另一个端点只允许删除的双端队列

redis底层数据结构之adlist

最近,我想通过redis的源码来学习redis.虽然平时工作中用得不多,不过对redis还是比较感兴趣的,毕竟它的性能是不错的.redis是一个开源的项目,我们可以通过源代码去了解redis.我后面会通过自己的学习,写一些关于redis源码的帖子.帖子的主要内容是分析代码设计,而并不会对源码进行详细解说.如果有不对的地方,请指正.源码是reids 3.0.3版本. adlist 一.adlist,双链列表 数据结构定义如下: //节点 typedef struct listNode {     

数据结构 --- 01. 时间复杂度,timeit模块,栈,队列,双端队列

一.时间复杂度 1.基本概念 评判程序优劣的方法: 消耗计算机资源和执行效率(无法直观) 计算算法执行的耗时(适当推荐,因为会受机器和执行环境的影响) 时间复杂度(推荐) 时间复杂度 评判规则:量化算法执行的操作/执行步骤的数量 最重要的项:时间复杂度表达式中最有意义的项 大O记法:O(时间复杂度表达式中最有意义的项) 常见的时间复杂度: O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O