zoukankan      html  css  js  c++  java
  • nginx源码分析——数组

    ngx_array.h

    /*
     * Copyright (C) Igor Sysoev
     * Copyright (C) Nginx, Inc.
     */
    
    
    #ifndef _NGX_ARRAY_H_INCLUDED_
    #define _NGX_ARRAY_H_INCLUDED_
    
    
    #include <ngx_config.h>
    #include <ngx_core.h>
    
    typedef struct {
        // elts指针,指向内存块
        void        *elts;
        // nelts,当前元素数量
        ngx_uint_t   nelts;
        // size,元素大小
        size_t       size;
        // nalloc,当前容量
        ngx_uint_t   nalloc;
        // pool指针,指向内存池
        ngx_pool_t  *pool;
    } ngx_array_t;
    
    
    // 创建数组(内存池,初始容量,元素大小)
    ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);
    
    // 销毁数组(目标数组)
    void ngx_array_destroy(ngx_array_t *a);
    
    // 添加元素(目标数组)
    void *ngx_array_push(ngx_array_t *a);
    
    // 添加n个元素(目标数组,元素数量)
    void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);
    
    // 初始化数组(目标数组,内存池,初始容量,元素大小)
    static ngx_inline ngx_int_t
    ngx_array_init(ngx_array_t *array, ngx_pool_t *pool, ngx_uint_t n, size_t size)
    {
        // nelts,当前元素数量
        array->nelts = 0;
        // size,元素大小
        array->size = size;
        // nalloc,当前容量
        array->nalloc = n;
        // pool指针,指向内存池
        array->pool = pool;
        // elts指针,指向内存块
        array->elts = ngx_palloc(pool, n * size);
        if (array->elts == NULL) {
            return NGX_ERROR;
        }
    
        return NGX_OK;
    }
    
    
    #endif /* _NGX_ARRAY_H_INCLUDED_ */

    ngx_array.c

    /*
     * Copyright (C) Igor Sysoev
     * Copyright (C) Nginx, Inc.
     */
    
    
    #include <ngx_config.h>
    #include <ngx_core.h>
    
    
    // 创建数组(内存池,初始容量,元素大小)
    ngx_array_t *
    ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
    {
        ngx_array_t *a;
    
        // 创建数组
        a = ngx_palloc(p, sizeof(ngx_array_t));
        if (a == NULL) {
            return NULL;
        }
    
        // 初始化数组(目标数组,内存池,初始容量,元素大小)
        if (ngx_array_init(a, p, n, size) != NGX_OK) {
            return NULL;
        }
    
        return a;
    }
    
    
    // 销毁数组(目标数组)
    void
    ngx_array_destroy(ngx_array_t *a)
    {
        ngx_pool_t  *p;
    
        // pool指针,指向内存池
        p = a->pool;
    
        // 判断数组元素是否位于内存块的最后位置,如果是直接调整内存块的参数进行删除
        if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
            p->d.last -= a->size * a->nalloc;
        }
    
        // 判断数组是否位于内存块的最后位置,如果是直接调整内存的参数进行删除
        if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
            p->d.last = (u_char *) a;
        }
    
        // 如果不是,则由内存池自行回收
    }
    
    
    // 添加元素(目标数组)
    void *
    ngx_array_push(ngx_array_t *a)
    {
        void        *elt, *new;
        size_t       size;
        ngx_pool_t  *p;
    
        // 判断元素数量是否达到最大值
        if (a->nelts == a->nalloc) {
    
            /* the array is full(满了) */
        
            size = a->size * a->nalloc;
    
            p = a->pool;
    
            // 判断数组是否位于内存块最后位置,且内存池还有足够的内存空间
            if ((u_char *) a->elts + size == p->d.last
                && p->d.last + a->size <= p->d.end)
            {
                // 如果是,则调整内存池参数,增加数组元素的内存空间
                p->d.last += a->size;
                a->nalloc++;
    
            } else {
                // 创建于原数组两倍大的数组元素空间
                new = ngx_palloc(p, 2 * size);
                if (new == NULL) {
                    return NULL;
                }
                ngx_memcpy(new, a->elts, size);
                a->elts = new;
                a->nalloc *= 2;
            }
        }
    
        // elts指针,指向内存块
        elt = (u_char *) a->elts + a->size * a->nelts;
    
        // 累加元素数量
        a->nelts++;
    
        // 返回新元素
        return elt;
    }
    
    
    // 添加n个元素(目标数组,元素数量)
    void *
    ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
    {
        void        *elt, *new;
        size_t       size;
        ngx_uint_t   nalloc;
        ngx_pool_t  *p;
    
        size = n * a->size;
    
        // 判断元素数量是否达到最大值
        if (a->nelts + n > a->nalloc) {
    
            /* the array is full (满了)*/
        
            p = a->pool;
    
            // 判断数组是否位于内存块最后位置,且内存池还有足够的内存空间
            if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
                && p->d.last + size <= p->d.end)
            {
                // 调整内存块参数
                p->d.last += size;
                a->nalloc += n;
    
            } else {
                // 创建于原数组两倍大的数组元素空间
                nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
    
                new = ngx_palloc(p, nalloc * a->size);
                if (new == NULL) {
                    return NULL;
                }
    
                ngx_memcpy(new, a->elts, a->nelts * a->size);
                a->elts = new;
                a->nalloc = nalloc;
            }
        }
    
        // elt指针,指向第一个新元素的内存地址
        elt = (u_char *) a->elts + a->size * a->nelts;
        
        // 累加元素数量
        a->nelts += n;
    
        // 返回第一个新元素
        return elt;
    }
  • 相关阅读:
    实战-百度云[大文件/文件夹]下载限制破解
    IOCP之客户端及消息传递
    IOCP简单实现
    Charles V4系列更新 | 绿色特别版 | 视频教程
    Charles 3.11.5 绿色特别版
    VC运行库合集2005/2008/2010/2012/2013/2015
    手游测试之《弱网测试》
    后端性能测试不可不知的二三事
    linux性能指标及分析工具
    Shell笔记-04
  • 原文地址:https://www.cnblogs.com/hvicen/p/8450280.html
Copyright © 2011-2022 走看看