xref: /unit/src/nxt_list.c (revision 108:f87c1c4e22be)
1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_main.h>
8 
9 
10 nxt_list_t *
nxt_list_create(nxt_mp_t * mp,nxt_uint_t n,size_t size)11 nxt_list_create(nxt_mp_t *mp, nxt_uint_t n, size_t size)
12 {
13     nxt_list_t  *list;
14 
15     list = nxt_mp_get(mp, sizeof(nxt_list_t) + n * size);
16 
17     if (nxt_fast_path(list != NULL)) {
18         list->last = &list->part;
19         list->size = size;
20         list->nalloc = n;
21         list->mem_pool = mp;
22         list->part.next = NULL;
23         list->part.nelts = 0;
24     }
25 
26     return list;
27 }
28 
29 
30 void *
nxt_list_add(nxt_list_t * list)31 nxt_list_add(nxt_list_t *list)
32 {
33     void             *elt;
34     nxt_list_part_t  *last;
35 
36     last = list->last;
37 
38     if (last->nelts == list->nalloc) {
39 
40         /* The last list part is filled up, allocating a new list part. */
41 
42         last = nxt_mp_get(list->mem_pool,
43                           sizeof(nxt_list_part_t) + list->nalloc * list->size);
44 
45         if (nxt_slow_path(last == NULL)) {
46             return NULL;
47         }
48 
49         last->next = NULL;
50         last->nelts = 0;
51 
52         list->last->next = last;
53         list->last = last;
54     }
55 
56     elt = nxt_pointer_to(nxt_list_data(last), last->nelts * list->size);
57     last->nelts++;
58 
59     return elt;
60 }
61 
62 
63 void *
nxt_list_zero_add(nxt_list_t * list)64 nxt_list_zero_add(nxt_list_t *list)
65 {
66     void  *p;
67 
68     p = nxt_list_add(list);
69 
70     if (nxt_fast_path(p != NULL)) {
71         nxt_memzero(p, list->size);
72     }
73 
74     return p;
75 }
76 
77 
78 void *
nxt_list_next(nxt_list_t * list,nxt_list_next_t * next)79 nxt_list_next(nxt_list_t *list, nxt_list_next_t *next)
80 {
81     if (next->part != NULL) {
82         next->elt++;
83 
84         if (next->elt < next->part->nelts) {
85             return nxt_list_next_value(list, next);
86         }
87 
88         next->part = next->part->next;
89 
90         if (next->part != NULL) {
91             next->elt = 0;
92             return nxt_list_data(next->part);
93         }
94 
95     } else {
96         next->part = nxt_list_part(list);
97         /*
98          * The first list part is allocated together with
99          * a nxt_list_t itself and it may never be NULL.
100          */
101         if (next->part->nelts != 0) {
102             return nxt_list_data(next->part);
103         }
104 
105     }
106 
107     return NULL;
108 }
109