File Coverage

pollfd_rbhash.h
Criterion Covered Total %
statement 0 8 0.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 0 8 0.0


line stmt bran cond sub pod time code
1             #ifndef POLLFD_RBHASH_H
2             #define POLLFD_RBHASH_H
3             /*
4             Generated by rbhash.cpppp using command
5              
6             cpppp -p 'max_bits=16' \
7             -p 'namespace=pollfd_rbhash' \
8             -p '@default_search_args=('\''int search_fd'\'')' \
9             -p 'default_search_cmp=search_fd - ((struct pollfd*)rbhash)[(int)node_id-1-(int)capacity].fd' \
10             rbhash.cpppp \
11             -o 'public=pollfd_rbhash.h' \
12             -o pollfd_rbhash.c
13              
14             */
15              
16             #include
17             #include
18             #include
19             #include
20             #include
21             #include
22              
23             /* MAX_TREE_HEIGHT is the maximum number of nodes from root to leaf in any
24             * correctly balanced tree. The exact formula for the maximum height (including
25             * root node) is floor(2*log2(N/2+1)) for a tree of N nodes.
26             */
27             #define POLLFD_RBHASH_MAX_ELEMENTS_8 0x7F
28             #define POLLFD_RBHASH_MAX_TREE_HEIGHT_8 12
29             #define POLLFD_RBHASH_MAX_ELEMENTS_16 0x7FFF
30             #define POLLFD_RBHASH_MAX_TREE_HEIGHT_16 28
31              
32             /* This macro tells you the word offset (treating rbhash as an array of words)
33             * of the first hash bucket.
34             */
35             #define POLLFD_RBHASH_TABLE_WORD_OFS(capacity) ( (capacity)*2 + 2 )
36              
37             /* This macro selects the word size needed to index 'capacity' number of
38             * user elements.
39             */
40             #define POLLFD_RBHASH_SIZEOF_WORD(capacity) ( \
41             (capacity) <= POLLFD_RBHASH_MAX_ELEMENTS_8? 1 : \
42             2 \
43             )
44              
45             /* This macro defines the total size (in bytes) of the rbhash storage
46             * for a given number of elements and buckets. This does not include
47             * the user's elements themselves, since those are whatever size the
48             * user wants them to be, and rbhash doesn't need to know.
49             */
50             #define POLLFD_RBHASH_SIZEOF(capacity, buckets) ( \
51             POLLFD_RBHASH_SIZEOF_WORD(capacity) \
52             * ( POLLFD_RBHASH_TABLE_WORD_OFS(capacity) + buckets ) \
53             )
54              
55             /* Several functions can operate on a "path", which is a list of
56             * references starting at the bucket and ending at a tree node.
57             * The path is allocated to the maximum depth that a tree of that
58             * word-bits-size could reach. Since this drastically affects the
59             * amount of stack used, a struct is declared for each word-bit size.
60             *
61             * The structs each record their length so that they can be passed
62             * interchangably to the functions. You could even allocate custom
63             * lengths with alloca, but that seems overcomplicated.
64             */
65             struct pollfd_rbhash_path_8 {
66             uint8_t len, lim;
67             size_t refs[POLLFD_RBHASH_MAX_TREE_HEIGHT_8];
68             };
69              
70 0           inline void pollfd_rbhash_path_8_init(struct pollfd_rbhash_path_8 *p) {
71 0           p->len= 0;
72 0           p->lim= POLLFD_RBHASH_MAX_TREE_HEIGHT_8;
73 0           }
74              
75             struct pollfd_rbhash_path_16 {
76             uint8_t len, lim;
77             size_t refs[POLLFD_RBHASH_MAX_TREE_HEIGHT_16];
78             };
79              
80 0           inline void pollfd_rbhash_path_16_init(struct pollfd_rbhash_path_16 *p) {
81 0           p->len= 0;
82 0           p->lim= POLLFD_RBHASH_MAX_TREE_HEIGHT_16;
83 0           }
84              
85              
86             // Different template output may end up with different structs claiming
87             // the name of pollfd_rbhash_path, but that should be OK.
88             typedef struct pollfd_rbhash_path_16 pollfd_rbhash_path;
89             #define pollfd_rbhash_path_init(p) pollfd_rbhash_path_16_init(p)
90              
91             // Iterate one or more places through the R/B tree of a bucket, updating 'path'
92             extern size_t pollfd_rbhash_path_step(void *rbhash, size_t capacity, pollfd_rbhash_path *path, int ofs);
93              
94             // Exchange the tree node of one node_id (at the end of 'path') for another node_id
95             extern size_t pollfd_rbhash_path_swap(void *rbhash, size_t capacity, pollfd_rbhash_path *path, size_t new_node_id);
96              
97             // implementation detail used to reduce size of inline functions
98             extern size_t pollfd_rbhash_capacity_bounds_assertion(size_t capacity);
99              
100             // Add a node_id at the end of 'path', and balance the tree if needed
101             extern size_t pollfd_rbhash_path_insert_8(uint8_t *rbhash, pollfd_rbhash_path *path, size_t node_id);
102             extern size_t pollfd_rbhash_path_insert_16(uint16_t *rbhash, pollfd_rbhash_path *path, size_t node_id);
103             inline size_t pollfd_rbhash_path_insert(void *rbhash, size_t capacity, pollfd_rbhash_path *path, size_t node) {
104             return
105             (capacity <= POLLFD_RBHASH_MAX_ELEMENTS_8)? pollfd_rbhash_path_insert_8((uint8_t*) rbhash, path, node) :
106             (capacity <= POLLFD_RBHASH_MAX_ELEMENTS_16)? pollfd_rbhash_path_insert_16((uint16_t*) rbhash, path, node) :
107             pollfd_rbhash_capacity_bounds_assertion(capacity);
108             }
109              
110             // Remove the node_id from the end of 'path', and balance the tree if needed
111             extern size_t pollfd_rbhash_path_delete_8(uint8_t *rbhash, pollfd_rbhash_path *path);
112             extern size_t pollfd_rbhash_path_delete_16(uint16_t *rbhash, pollfd_rbhash_path *path);
113             inline size_t pollfd_rbhash_path_delete(void *rbhash, size_t capacity, pollfd_rbhash_path *path) {
114             return
115             (capacity <= POLLFD_RBHASH_MAX_ELEMENTS_8)? pollfd_rbhash_path_delete_8((uint8_t*) rbhash, path) :
116             (capacity <= POLLFD_RBHASH_MAX_ELEMENTS_16)? pollfd_rbhash_path_delete_16((uint16_t*) rbhash, path) :
117             pollfd_rbhash_capacity_bounds_assertion(capacity);
118             }
119              
120             // Find a node_id matching the search criteria and fill in the 'path' to it, else return 0
121             extern size_t pollfd_rbhash_find_path(void *rbhash, size_t capacity, pollfd_rbhash_path *path, size_t bucket_idx, int search_fd);
122              
123             // Simplified search for node_id, without building a path
124             extern size_t pollfd_rbhash_find(void *rbhash, size_t capacity, size_t bucket_idx, int search_fd);
125              
126             // Insert a node_id, unless one already matches the search criteria
127             extern size_t pollfd_rbhash_insert(void *rbhash, size_t capacity, size_t node_id, size_t bucket_idx, int search_fd);
128              
129             // Delete a node matching the search criteria
130             extern size_t pollfd_rbhash_delete(void *rbhash, size_t capacity, size_t bucket_idx, int search_fd);
131              
132              
133             // Handy for gdb:
134             // p pollfd_rbhash_print(rbhash, capacity, buckets, NULL, NULL, stdout)
135             extern void pollfd_rbhash_print(void *rbhash, size_t capacity, size_t n_buckets,
136             void (*print_node)(void*,size_t,FILE*), void* userdata, FILE *out);
137              
138             #endif