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_mp_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_mp_t *mp, nxt_uint_t n, size_t size); 98 NXT_EXPORT void *nxt_list_add(nxt_list_t *list); 99 NXT_EXPORT void *nxt_list_zero_add(nxt_list_t *list); 100 101 NXT_EXPORT void *nxt_list_next(nxt_list_t *list, nxt_list_next_t *next); 102 103 104 #define \ 105 nxt_list_next_value(list, next) \ 106 ((void *) (nxt_list_data((next)->part) + (next)->elt * (list)->size)) 107 108 109 nxt_inline nxt_uint_t 110 nxt_list_nelts(nxt_list_t *list) 111 { 112 nxt_uint_t n; 113 nxt_list_part_t *part; 114 115 n = 0; 116 117 if (nxt_fast_path((list) != NULL)) { 118 part = nxt_list_part(list); 119 120 do { 121 n += (nxt_uint_t) part->nelts; 122 part = part->next; 123 } while (part != NULL); 124 } 125 126 return n; 127 } 128 129 130 #endif /* _NXT_LIST_H_INCLUDED_ */ 131