summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_list.h
blob: dc948e0385e442113f15df0988bc1c595a3827cf (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

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