Preliminary data structure of the source code Nginx - linked list data structure

Introduction ngx_list_t
        ngx_list_t Nginx is more frequently used data structures, based on the content data pointer acquisition, memory-based memory allocation pool. Since the content data is stored in the pointer, so theoretically ngx_list_t be used to build a multi-dimensional network structure is even linked list, only the function package Nginx original code is not involved in the operation of these data structures (in fact not necessary).

1. Data Structure

        Nginx linked list data structure consists of two parts and ngx_list_part_s ngx_list_t. ngx_list_part_s data nodes, each node contains the data and data pointer linked list data has been stored in the position data and the number of the next node.

struct ngx_list_part_s {
    void             *elts;
    ngx_uint_t        nelts;/*已存储元素个数*/
    ngx_list_part_t  *next;
};

ngx_list_t responsible for management and operation of the linked list, the header structure is as follows.

typedef struct {
    ngx_list_part_t  *last;/*链表最后一个节点的位置*/
    ngx_list_part_t   part;/*链表第一个节点*/
    size_t            size;/*链表中每个元素的大小,内存分配同样是等尺寸内存卡分配,便于管理*/
    ngx_uint_t        nalloc;/*链表已分配的元素个数*/
    ngx_pool_t       *pool;/*链表分配内存所在内存池*/
} ngx_list_t;

2. Basic Operations
2.1 initialization list

         Initialization logic is very simple, first assign the first node in the memory pool, then the last node points to the first node, the last update of the list management information on it.

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;
}

2.2 Creating list

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;
}

2.3 Adding elements

          Return fight last element of the elements are added, and then add element content in an external logic.

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 chain structure may be dynamically allocated memory, thereby effectively avoiding excessive allocate memory, which is very good for save memory, it is noted that in a large number of push data memory allocation operation will bring increasing frequency problem.

Released eight original articles · won praise 0 · Views 112

Guess you like

Origin blog.csdn.net/mlydaemon/article/details/103945001