blob: a536d87b5614780d6cedd329dd266c925fc1d531 [file] [log] [blame]
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00001
Igor Sysoevd90282d2004-09-28 08:34:51 +00002/*
Igor Sysoevff8da912004-09-29 16:00:49 +00003 * Copyright (C) Igor Sysoev
Igor Sysoevd90282d2004-09-28 08:34:51 +00004 */
5
6
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00007#include <ngx_config.h>
Igor Sysoev1c104622003-06-03 15:42:58 +00008#include <ngx_core.h>
Igor Sysoev6de5c2c2002-08-06 16:39:45 +00009
Igor Sysoev4e9393a2003-01-09 05:36:00 +000010
Igor Sysoev9e580192006-02-01 18:22:15 +000011ngx_array_t *
12ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000013{
14 ngx_array_t *a;
15
Igor Sysoevc1571722005-03-19 12:38:37 +000016 a = ngx_palloc(p, sizeof(ngx_array_t));
17 if (a == NULL) {
Igor Sysoev805d9db2005-02-03 19:33:37 +000018 return NULL;
19 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000020
Igor Sysoevc1571722005-03-19 12:38:37 +000021 a->elts = ngx_palloc(p, n * size);
22 if (a->elts == NULL) {
Igor Sysoev805d9db2005-02-03 19:33:37 +000023 return NULL;
24 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000025
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000026 a->nelts = 0;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000027 a->size = size;
Igor Sysoev805d9db2005-02-03 19:33:37 +000028 a->nalloc = n;
29 a->pool = p;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000030
31 return a;
32}
33
Igor Sysoev4e9393a2003-01-09 05:36:00 +000034
Igor Sysoev9e580192006-02-01 18:22:15 +000035void
36ngx_array_destroy(ngx_array_t *a)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000037{
Igor Sysoev4e9393a2003-01-09 05:36:00 +000038 ngx_pool_t *p;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000039
Igor Sysoev4e9393a2003-01-09 05:36:00 +000040 p = a->pool;
41
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000042 if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
43 p->d.last -= a->size * a->nalloc;
Igor Sysoev4e9393a2003-01-09 05:36:00 +000044 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000045
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000046 if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
47 p->d.last = (u_char *) a;
Igor Sysoev4e9393a2003-01-09 05:36:00 +000048 }
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000049}
50
Igor Sysoev4e9393a2003-01-09 05:36:00 +000051
Igor Sysoev9e580192006-02-01 18:22:15 +000052void *
53ngx_array_push(ngx_array_t *a)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000054{
Igor Sysoev4e9393a2003-01-09 05:36:00 +000055 void *elt, *new;
Igor Sysoev805d9db2005-02-03 19:33:37 +000056 size_t size;
Igor Sysoev4e9393a2003-01-09 05:36:00 +000057 ngx_pool_t *p;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000058
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000059 if (a->nelts == a->nalloc) {
Igor Sysoev805d9db2005-02-03 19:33:37 +000060
61 /* the array is full */
62
63 size = a->size * a->nalloc;
64
Igor Sysoev4e9393a2003-01-09 05:36:00 +000065 p = a->pool;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000066
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000067 if ((u_char *) a->elts + size == p->d.last
68 && p->d.last + a->size <= p->d.end)
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000069 {
Igor Sysoev805d9db2005-02-03 19:33:37 +000070 /*
71 * the array allocation is the last in the pool
72 * and there is space for new allocation
73 */
74
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +000075 p->d.last += a->size;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000076 a->nalloc++;
77
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000078 } else {
Igor Sysoev805d9db2005-02-03 19:33:37 +000079 /* allocate a new array */
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000080
Igor Sysoevc1571722005-03-19 12:38:37 +000081 new = ngx_palloc(p, 2 * size);
82 if (new == NULL) {
Igor Sysoev805d9db2005-02-03 19:33:37 +000083 return NULL;
84 }
85
86 ngx_memcpy(new, a->elts, size);
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000087 a->elts = new;
88 a->nalloc *= 2;
89 }
90 }
91
Igor Sysoev805d9db2005-02-03 19:33:37 +000092 elt = (u_char *) a->elts + a->size * a->nelts;
Igor Sysoev6de5c2c2002-08-06 16:39:45 +000093 a->nelts++;
94
95 return elt;
96}
Igor Sysoev805d9db2005-02-03 19:33:37 +000097
98
Igor Sysoev9e580192006-02-01 18:22:15 +000099void *
100ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
Igor Sysoev805d9db2005-02-03 19:33:37 +0000101{
102 void *elt, *new;
103 size_t size;
104 ngx_uint_t nalloc;
105 ngx_pool_t *p;
106
107 size = n * a->size;
108
109 if (a->nelts + n > a->nalloc) {
110
111 /* the array is full */
112
113 p = a->pool;
114
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000115 if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
116 && p->d.last + size <= p->d.end)
Igor Sysoev805d9db2005-02-03 19:33:37 +0000117 {
118 /*
119 * the array allocation is the last in the pool
120 * and there is space for new allocation
121 */
122
Igor Sysoev7f6b2ff2008-06-17 15:00:30 +0000123 p->d.last += size;
Igor Sysoev805d9db2005-02-03 19:33:37 +0000124 a->nalloc += n;
125
126 } else {
127 /* allocate a new array */
128
129 nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
130
Igor Sysoevc1571722005-03-19 12:38:37 +0000131 new = ngx_palloc(p, nalloc * a->size);
132 if (new == NULL) {
Igor Sysoev805d9db2005-02-03 19:33:37 +0000133 return NULL;
134 }
135
136 ngx_memcpy(new, a->elts, a->nelts * a->size);
137 a->elts = new;
138 a->nalloc = nalloc;
139 }
140 }
141
142 elt = (u_char *) a->elts + a->size * a->nelts;
143 a->nelts += n;
144
145 return elt;
146}