• 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;
    }
  • 相关阅读:
    MySQL数据库封装和分页查询
    程序员的价值在哪里?
    奇葩的程序员
    京东咚咚架构演进
    程序员必看的《黑客帝国》,你看懂了吗?
    微信后台技术“干货们”带来的启发
    drf框架 2 drf框架的请求生命周期(as_view和dispatch方法), 请求、解析、渲染、响应、异常, 序列化组件 ,ORM配置回顾(media文件配置),应用在settings.py中INSTALLED_APPS注册意义 ,数据库配置
    drf框架, 接口(api) Django FBV => CBV drf框架的基础试图类 drf核心组件 群查与单查 python换源
    前端Vue框架 05 第三方插件(vuex: 组件间交互的(移动端), axios
    前端Vue框架 04 路由:逻辑跳转、路由传参 项目组件的数据局部化处理data(){ return{} } 组件的生命周期钩子 组件间通信 全局配置css, js
  • 原文地址:https://www.cnblogs.com/hvicen/p/8450280.html
Copyright © 2020-2023  润新知