/* * Copyright (C) Igor Sysoev * Copyright (C) NGINX, Inc. */ #ifndef _NXT_LIST_H_INCLUDED_ #define _NXT_LIST_H_INCLUDED_ typedef struct nxt_list_part_s nxt_list_part_t; struct nxt_list_part_s { nxt_list_part_t *next; uintptr_t nelts; char data[]; }; typedef struct { nxt_list_part_t *last; #if (NXT_64BIT) uint32_t size; uint32_t nalloc; #else uint16_t size; uint16_t nalloc; #endif nxt_mp_t *mem_pool; nxt_list_part_t part; } nxt_list_t; typedef struct { nxt_list_part_t *part; uintptr_t elt; } nxt_list_next_t; #define nxt_list_part(list) \ (&(list)->part) #define nxt_list_data(part) \ ((void *) part->data) #define nxt_list_first(list) \ nxt_list_data(nxt_list_part(list)) nxt_inline void * nxt_list_elt(nxt_list_t *list, nxt_uint_t n) { nxt_list_part_t *part; if (nxt_fast_path((list) != NULL)) { part = nxt_list_part(list); while (part != NULL) { if (n < (nxt_uint_t) part->nelts) { return nxt_pointer_to(nxt_list_data(part), n * (list)->size); } n -= (nxt_uint_t) part->nelts; part = part->next; } } return NULL; } #define nxt_list_each(elt, list) \ do { \ if (nxt_fast_path((list) != NULL)) { \ void *_end; \ nxt_list_part_t *_part = nxt_list_part(list); \ \ do { \ elt = nxt_list_data(_part); \ \ for (_end = (elt + _part->nelts); elt != _end; elt++) { \ #define nxt_list_loop \ } \ \ _part = _part->next; \ \ } while (_part != NULL); \ } \ } while (0) NXT_EXPORT nxt_list_t *nxt_list_create(nxt_mp_t *mp, nxt_uint_t n, size_t size); NXT_EXPORT void *nxt_list_add(nxt_list_t *list); NXT_EXPORT void *nxt_list_zero_add(nxt_list_t *list); NXT_EXPORT void *nxt_list_next(nxt_list_t *list, nxt_list_next_t *next); #define nxt_list_next_value(list, next) \ (nxt_pointer_to(nxt_list_data((next)->part), (next)->elt * (list)->size)) nxt_inline nxt_uint_t nxt_list_nelts(nxt_list_t *list) { nxt_uint_t n; nxt_list_part_t *part; n = 0; if (nxt_fast_path((list) != NULL)) { part = nxt_list_part(list); do { n += (nxt_uint_t) part->nelts; part = part->next; } while (part != NULL); } return n; } #endif /* _NXT_LIST_H_INCLUDED_ */