The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
heap.h
Go to the documentation of this file.
1#pragma once
2/*
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16 */
17
18/** Structures and prototypes for binary heaps
19 *
20 * @file src/lib/util/heap.h
21 *
22 * @copyright 2007 Alan DeKok
23 */
24RCSIDH(heap_h, "$Id: 83d2e03cfe3b19fb85f38547def39ae7d4ed7652 $")
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30#include <freeradius-devel/build.h>
31#include <freeradius-devel/missing.h>
32#include <freeradius-devel/util/misc.h>
33#include <freeradius-devel/util/talloc.h>
34
35#include <stdint.h>
36#include <sys/types.h>
37
38/*
39 * Allow public and private versions of the same structures
40 */
41#ifdef _CONST
42# error _CONST can only be defined in the local header
43#endif
44#ifndef _HEAP_PRIVATE
45# define _CONST const
46#else
47# define _CONST
48#endif
49
50/** Comparator to order heap elements
51 *
52 * Return CMP_LT to put 'a' at the top of the heap.
53 * Return CMP_GT to put 'b' at the top of the heap.
54 * Return CMP_ERR when the comparison itself failed.
55 */
56typedef fr_cmp_ret_t (*fr_heap_cmp_t)(void const *a, void const *b);
57
58/** The main heap structure
59 *
60 * A heap entry is made of a pointer to the object, which
61 * contains the key. The heap itself is an array of pointers.
62 *
63 * Heaps normally support only ordered insert, and extraction
64 * of the minimum element. The heap entry can contain an "int"
65 * field that holds the entries position in the heap. The offset
66 * of the field is held inside of the heap structure.
67 */
68typedef struct {
69 unsigned int _CONST size; //!< Number of nodes allocated.
70 unsigned int _CONST min; //!< Minimum number of elements we allow
71 ///< the heap to reduce down to.
72 size_t _CONST offset; //!< Offset of heap index in element structure.
73
74 unsigned int _CONST num_elements; //!< Number of nodes used.
75
76 char const * _CONST type; //!< Talloc type of elements.
77 fr_heap_cmp_t _CONST cmp; //!< Comparator function.
78
79 void * _CONST p[]; //!< Array of nodes.
80} fr_heap_t;
81
82typedef unsigned int fr_heap_index_t;
83typedef unsigned int fr_heap_iter_t;
84
85#define FR_HEAP_INDEX_INVALID (0)
86
87/** How many talloc headers need to be pre-allocated for a heap
88 */
89#define FR_HEAP_TALLOC_HEADERS 2
90
91size_t fr_heap_pre_alloc_size(unsigned int count);
92
93/** Creates a heap that can be used with non-talloced elements
94 *
95 * @param[in] _ctx Talloc ctx to allocate heap in.
96 * @param[in] _cmp Comparator used to compare elements.
97 * @param[in] _type Of elements.
98 * @param[in] _field to store heap indexes in.
99 * @param[in] _init the initial number of elements to allocate.
100 * Pass 0 to use the default.
101 */
102#define fr_heap_alloc(_ctx, _cmp, _type, _field, _init) \
103 _fr_heap_alloc(_ctx, _cmp, NULL, (size_t)offsetof(_type, _field), _init)
104
105/** Creates a heap that verifies elements are of a specific talloc type
106 *
107 * @param[in] _ctx Talloc ctx to allocate heap in.
108 * @param[in] _cmp Comparator used to compare elements.
109 * @param[in] _talloc_type of elements.
110 * @param[in] _field to store heap indexes in.
111 * @param[in] _init the initial number of elements to allocate.
112 * Pass 0 to use the default.
113 * @return
114 * - A new heap.
115 * - NULL on error.
116 */
117#define fr_heap_talloc_alloc(_ctx, _cmp, _talloc_type, _field, _init) \
118 _fr_heap_alloc(_ctx, _cmp, #_talloc_type, (size_t)offsetof(_talloc_type, _field), _init)
119fr_heap_t *_fr_heap_alloc(TALLOC_CTX *ctx, fr_heap_cmp_t cmp, char const *talloc_type,
120 size_t offset, unsigned int init) CC_HINT(nonnull(2));
121
122/** Check if an entry is inserted into a heap
123 *
124 * @param[in] heap_idx from object to check.
125 */
126static inline bool fr_heap_entry_inserted(fr_heap_index_t heap_idx)
127{
128 return (heap_idx != FR_HEAP_INDEX_INVALID);
129}
130
131/** Return the item from the top of the heap but don't pop it
132 *
133 * @param[in] h to return element from.
134 * @return
135 * - Element at the top of the heap.
136 * - NULL if no elements remain in the heap.
137 */
138static inline void *fr_heap_peek(fr_heap_t *h)
139{
140 if (h->num_elements == 0) return NULL;
141
142 return h->p[1];
143}
144
145/** Peek at a specific index in the heap
146 *
147 * @param[in] h to return element from.
148 * @param[in] idx to lookup
149 * @return
150 * - Element at the top of the heap.
151 * - NULL if index outside of the range of the heap.
152 */
153static inline void *fr_heap_peek_at(fr_heap_t *h, fr_heap_index_t idx)
154{
155 if (unlikely(idx > h->num_elements)) return NULL;
156
157 return h->p[idx];
158}
159
160/** Peek at the last element in the heap (not necessarily the bottom)
161 *
162 * @param[in] h to return element from.
163 * @return
164 * - Last element in the heap.
165 * - NULL if no elements remain in the heap.
166 */
167static inline void *fr_heap_peek_tail(fr_heap_t *h)
168{
169 if (h->num_elements == 0) return NULL;
170
171 /*
172 * If this is NULL, we have a problem.
173 */
174 return h->p[h->num_elements];
175}
176
177/** Return the number of elements in the heap
178 *
179 * @param[in] h to return the number of elements from.
180 */
181static inline unsigned int fr_heap_num_elements(fr_heap_t *h)
182{
183 return h->num_elements;
184}
185
186int fr_heap_insert(fr_heap_t **hp, void *data) CC_HINT(nonnull);
187int fr_heap_extract(fr_heap_t **hp, void *data) CC_HINT(nonnull);
188int fr_heap_pop(void **out, fr_heap_t **hp) CC_HINT(nonnull);
189
190void *fr_heap_iter_init(fr_heap_t *hp, fr_heap_iter_t *iter) CC_HINT(nonnull);
191void *fr_heap_iter_next(fr_heap_t *hp, fr_heap_iter_t *iter) CC_HINT(nonnull);
192
193/** Iterate over the contents of a heap
194 *
195 * @note The initializer section of a for loop can't declare variables with distinct
196 * base types, so we require a containing block, and can't follow the standard
197 * do {...} while(0) dodge. The code to be run for each item in the heap should
198 * thus start with one open brace and end with two close braces, and shouldn't
199 * be followed with a semicolon.
200 * This may fake out code formatting programs and code-aware editors.
201 *
202 * @param[in] _heap to iterate over.
203 * @param[in] _type of item the heap contains.
204 * @param[in] _data Name of variable holding a pointer to the heap element.
205 * Will be declared in the scope of the loop.
206 */
207#define fr_heap_foreach(_heap, _type, _data) \
208{ \
209 fr_heap_iter_t _iter; \
210 for (_type *_data = fr_heap_iter_init(_heap, &_iter); _data; _data = fr_heap_iter_next(_heap, &_iter))
211
212#ifndef TALLOC_GET_TYPE_ABORT_NOOP
213void fr_heap_verify(char const *file, int line, fr_heap_t *hp);
214# define FR_HEAP_VERIFY(_heap) fr_heap_verify(__FILE__, __LINE__, _heap)
215#elif !defined(NDEBUG)
216# define FR_HEAP_VERIFY(_heap) fr_assert(_heap)
217#else
218# define FR_HEAP_VERIFY(_heap)
219#endif
220
221#undef _CONST
222#ifdef __cplusplus
223}
224#endif
int const char int line
Definition acutest.h:702
#define RCSIDH(h, id)
Definition build.h:561
#define unlikely(_x)
Definition build.h:455
unsigned int fr_heap_index_t
Definition heap.h:82
char const *_CONST type
Talloc type of elements.
Definition heap.h:76
static void * fr_heap_peek(fr_heap_t *h)
Return the item from the top of the heap but don't pop it.
Definition heap.h:138
void fr_heap_verify(char const *file, int line, fr_heap_t *hp)
Definition heap.c:420
unsigned int _CONST min
Minimum number of elements we allow the heap to reduce down to.
Definition heap.h:70
static void * fr_heap_peek_tail(fr_heap_t *h)
Peek at the last element in the heap (not necessarily the bottom)
Definition heap.h:167
void * fr_heap_iter_init(fr_heap_t *hp, fr_heap_iter_t *iter)
Iterate over entries in heap.
Definition heap.c:391
unsigned int fr_heap_iter_t
Definition heap.h:83
unsigned int _CONST size
Number of nodes allocated.
Definition heap.h:69
size_t fr_heap_pre_alloc_size(unsigned int count)
Return how many bytes need to be allocated to hold a heap of a given size.
Definition heap.c:52
int fr_heap_insert(fr_heap_t **hp, void *data)
Insert a new element into the heap.
Definition heap.c:149
#define _CONST
Definition heap.h:45
int fr_heap_pop(void **out, fr_heap_t **hp)
Remove a node from the heap.
Definition heap.c:359
fr_heap_t * _fr_heap_alloc(TALLOC_CTX *ctx, fr_heap_cmp_t cmp, char const *talloc_type, size_t offset, unsigned int init))
Definition heap.c:57
void * fr_heap_iter_next(fr_heap_t *hp, fr_heap_iter_t *iter)
Get the next entry in a heap.
Definition heap.c:411
unsigned int _CONST num_elements
Number of nodes used.
Definition heap.h:74
static bool fr_heap_entry_inserted(fr_heap_index_t heap_idx)
Check if an entry is inserted into a heap.
Definition heap.h:126
static void * fr_heap_peek_at(fr_heap_t *h, fr_heap_index_t idx)
Peek at a specific index in the heap.
Definition heap.h:153
int fr_heap_extract(fr_heap_t **hp, void *data)
Remove a node from the heap.
Definition heap.c:259
static unsigned int fr_heap_num_elements(fr_heap_t *h)
Return the number of elements in the heap.
Definition heap.h:181
void *_CONST p[]
Array of nodes.
Definition heap.h:79
fr_heap_cmp_t _CONST cmp
Comparator function.
Definition heap.h:77
fr_cmp_ret_t(* fr_heap_cmp_t)(void const *a, void const *b)
Comparator to order heap elements.
Definition heap.h:56
#define FR_HEAP_INDEX_INVALID
Definition heap.h:85
size_t _CONST offset
Offset of heap index in element structure.
Definition heap.h:72
The main heap structure.
Definition heap.h:68
fr_cmp_ret_t
Result of an ordering comparison.
Definition misc.h:50
return count
Definition module.c:155
init
Enter the EAP-IDENTITY state.
static fr_slen_t data
Definition value.h:1340
int nonnull(2, 5))
static size_t char ** out
Definition value.h:1030