1 2 /* 3 * Copyright (C) Igor Sysoev 4 * Copyright (C) NGINX, Inc. 5 */ 6 7 #ifndef _NXT_LIST_H_INCLUDED_ 8 #define _NXT_LIST_H_INCLUDED_ 9 10 11 typedef struct nxt_list_part_s nxt_list_part_t; 12 13 struct nxt_list_part_s { 14 nxt_list_part_t *next; 15 uintptr_t nelts; 16 }; 17 18 19 typedef struct { 20 nxt_list_part_t *last; 21 #if (NXT_64BIT) 22 uint32_t size; 23 uint32_t nalloc; 24 #else 25 uint16_t size; 26 uint16_t nalloc; 27 #endif 28 nxt_mem_pool_t *mem_pool; 29 nxt_list_part_t part; 30 } nxt_list_t; 31 32 33 typedef struct { 34 nxt_list_part_t *part; 35 uintptr_t elt; 36 } nxt_list_next_t; 37 38 39 #define \ 40 nxt_list_part(list) \ 41 (&(list)->part) 42 43 44 #define \ 45 nxt_list_data(part) \ 46 ((char *) (part) + sizeof(nxt_list_part_t)) 47 48 49 #define \ 50 nxt_list_first(list) \ 51 (void *) nxt_list_data(nxt_list_part(list)) 52 53 54 nxt_inline void * 55 nxt_list_elt(nxt_list_t *list, nxt_uint_t n) 56 { 57 nxt_list_part_t *part; 58 59 if (nxt_fast_path((list) != NULL)) { 60 part = nxt_list_part(list); 61 62 while (part != NULL) { 63 if (n < (nxt_uint_t) part->nelts) { 64 return ((void *) (nxt_list_data(part) + n * (list)->size)); 65 } 66 67 n -= (nxt_uint_t) part->nelts; 68 part = part->next; 69 } 70 } 71 72 return NULL; 73 } 74 75 76 #define nxt_list_each(elt, list) \ 77 do { \ 78 if (nxt_fast_path((list) != NULL)) { \ 79 void *_end; \ 80 nxt_list_part_t *_part = nxt_list_part(list); \ 81 \ 82 do { \ 83 elt = (void *) nxt_list_data(_part); \ 84 \ 85 for (_end = (elt + _part->nelts); elt != _end; elt++) { \ 86 87 #define nxt_list_loop \ 88 } \ 89 \ 90 _part = _part->next; \ 91 \ 92 } while (_part != NULL); \ 93 } \ 94 } while (0) 95 96 97 NXT_EXPORT nxt_list_t *nxt_list_create(nxt_mem_pool_t *mp, nxt_uint_t n, 98 size_t size); 99 NXT_EXPORT void *nxt_list_add(nxt_list_t *list); 100 NXT_EXPORT void *nxt_list_zero_add(nxt_list_t *list); 101 102 NXT_EXPORT void *nxt_list_next(nxt_list_t *list, nxt_list_next_t *next); 103 104 105 #define \ 106 nxt_list_next_value(list, next) \ 107 ((void *) (nxt_list_data((next)->part) + (next)->elt * (list)->size)) 108 109 110 nxt_inline nxt_uint_t 111 nxt_list_nelts(nxt_list_t *list) 112 { 113 nxt_uint_t n; 114 nxt_list_part_t *part; 115 116 n = 0; 117 118 if (nxt_fast_path((list) != NULL)) { 119 part = nxt_list_part(list); 120 121 do { 122 n += (nxt_uint_t) part->nelts; 123 part = part->next; 124 } while (part != NULL); 125 } 126 127 return n; 128 } 129 130 131 #endif /* _NXT_LIST_H_INCLUDED_ */ 132