首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Nginx(11):存储数组的链表

Nginx(11):存储数组的链表

作者头像
看、未来
发布于 2021-10-09 11:54:47
发布于 2021-10-09 11:54:47
8630
举报

今天把昨天没铺开的几个数据结构全部铺开,明天上手高级数据结构。

文章目录

我的困惑

这个链表我很喜欢,且这个构想在我的脑子里面存在很久了,但是一直没去实现。

它,是deque吗?deque,刚开始接触的时候有那么一丝欣喜,但是再进一步了解之后,嗯,大家不喜欢用是有原因的。

我一直没有去实现它,我不是一个喜欢一直拖着的人,没有去实现,肯定是有原因的。 这么一种数据结构,它存在的意义是什么呢?对于每一块内存,都要专门开辟一个位置来记录它的空间,说是插入效率会比较高,但是真的能比普通数组高到哪里去呢?说是查询效率比较高,又能比链表高到哪里去?

这些问题我一直没有想明白,所以就不冒冒失失去实现了。

今天我就来为这些问题,找到一个出路!


存储数组的链表

代码语言:javascript
复制
typedef struct ngx_list_part_s  ngx_list_part_t;

//节点
/*
每个链表元素ngx_list_part_t又是一个数组,拥有连续的内存,
它既依赖于ngx_list_t里的size和nalloc来表示数组的容量,
同时又依靠每个ngx_list_part_t成员中的nelts来表示数组当前已使用了多少容量。
*/
struct ngx_list_part_s {
    void             *elts;		//指向数组的起始地址
    ngx_uint_t        nelts;	//表示数组中已经使用元素数量
    ngx_list_part_t  *next;		//下一个链表元素的地址
};

//链表
typedef struct {
    ngx_list_part_t  *last;		//指向最后一个数组元素
    ngx_list_part_t   part;		//首元素
    size_t            size;		//限制每个数组元素占用空间大小,也就是用户要存储的一个数据所 占用的字节数必须小于或等于size。
    ngx_uint_t        nalloc;	//最多可存储数据数
    ngx_pool_t       *pool;		//管理内存分配的内存池对象
} ngx_list_t;

这个跟deque有点像的东西我想实现它很久了,没想到在这里看到了。

设计优点

1、通用链表 2、小块的内存使用链表访问效率是低下的,使用数组通过偏移量来直接访问内存则要高 效得多。


配备方法

在 ngx_list 类里面就给了这几个方法,也没有什么删查改,呃呃呃。真就给了这几个而已。

代码语言:javascript
复制
//用于创建新的链表
ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size);	

//用于初始化一个已有的元素
static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size);

//添加元素
void *ngx_list_push(ngx_list_t *list);

ngx_list_create
代码语言:javascript
复制
ngx_list_t *ngx_list_create(ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
    ngx_list_t  *list;

    list = ngx_palloc(pool, sizeof(ngx_list_t));
    if (list == NULL) {
        return NULL;
    }

    if (ngx_list_init(list, pool, n, size) != NGX_OK) {
        return NULL;
    }

    return list;
}

ngx_list_create返回新创建的链表地址,如果创建失败,则返回NULL空指针。ngx_list_create 被调用后至少会创建一个数组(不会创建空链表),其中包含n个大小为size字节的连续内存 块,也就是ngx_list_t结构中的part成员。


ngx_list_init
代码语言:javascript
复制
static ngx_inline ngx_int_t
ngx_list_init(ngx_list_t *list, ngx_pool_t *pool, ngx_uint_t n, size_t size)
{
    list->part.elts = ngx_palloc(pool, n * size);
    if (list->part.elts == NULL) {
        return NGX_ERROR;
    }

    list->part.nelts = 0;
    list->part.next = NULL;
    list->last = &list->part;
    list->size = size;
    list->nalloc = n;
    list->pool = pool;

    return NGX_OK;
}

代码语言:javascript
复制
void *ngx_list_push(ngx_list_t *l)
{
    void             *elt;
    ngx_list_part_t  *last;

    last = l->last;

    if (last->nelts == l->nalloc) {

        /* the last part is full, allocate a new list part */

        last = ngx_palloc(l->pool, sizeof(ngx_list_part_t));
        if (last == NULL) {
            return NULL;
        }

        last->elts = ngx_palloc(l->pool, l->nalloc * l->size);
        if (last->elts == NULL) {
            return NULL;
        }

        last->nelts = 0;
        last->next = NULL;

        l->last->next = last;
        l->last = last;
    }

    elt = (char *) last->elts + l->size * last->nelts;
    last->nelts++;

    return elt;
}

哎,权当记录吧,希望读到后面,能慢慢清晰这个链表在nginx中的应用吧,这篇,终究缺了个点睛之笔。 我全局搜索了源码,其实用到的地方也不多。。。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/09/28 ,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 文章目录
  • 我的困惑
  • 存储数组的链表
    • 设计优点
    • 配备方法
      • ngx_list_create
      • ngx_list_init
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档