summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_list.h
blob: ecbb67a943b944485fb41bbcb5f6da91ce39abb9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

/*
 * 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_ */