The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
minmax_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 min-max heaps
19  *
20  * @file src/lib/util/minmax_heap.h
21  *
22  * @copyright 2021 Network RADIUS SAS (legal@networkradius.com)
23  */
24 RCSIDH(minmax_heap_h, "$Id: 4f0fcd55c6a25890c9b7e24c67eea81d19c3f611 $")
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include <freeradius-devel/build.h>
31 #include <freeradius-devel/missing.h>
32 #include <freeradius-devel/util/talloc.h>
33 
34 #include <stdint.h>
35 #include <sys/types.h>
36 
37 typedef unsigned int fr_minmax_heap_index_t;
38 typedef unsigned int fr_minmax_heap_iter_t;
39 
40 /** How many talloc headers need to be pre-allocated for a minmax heap
41  */
42 #define FR_MINMAX_HEAP_TALLOC_HEADERS 2
43 
44 /** Comparator to order elements
45  *
46  * Return a negative number if 'a' precedes 'b'.
47  * Return zero if the ordering of 'a' and 'b' doesn't matter.
48  * Return a positive number if 'b' precedes 'a'.
49  */
50 typedef int8_t (*fr_minmax_heap_cmp_t)(void const *a, void const *b);
51 
52 /** The main minmax heap structure
53  * Note that fr_minmax_heap_t is a pointer to fr_minmax_heap_s. This added level of indirection
54  * lets one allocate/reallocate the heap structure and the array of pointers to items in the
55  * minmax heap as a unit without affecting the caller.
56  */
58 
59 size_t fr_minmax_heap_pre_alloc_size(unsigned int count);
60 
61 /** Creates a minmax heap that can be used with non-talloced elements
62  *
63  * @param[in] _ctx Talloc ctx to allocate heap in.
64  * @param[in] _cmp Comparator used to compare elements.
65  * @param[in] _type Of elements.
66  * @param[in] _field to store heap indexes in.
67  * @param[in] _init the initial number of elements to allocate.
68  * Pass 0 to use the default.
69  */
70 #define fr_minmax_heap_alloc(_ctx, _cmp, _type, _field, _init) \
71  _fr_minmax_heap_alloc(_ctx, _cmp, NULL, (size_t)offsetof(_type, _field), _init)
72 
73 /** Creates a minmax heap that verifies elements are of a specific talloc type
74  *
75  * @param[in] _ctx Talloc ctx to allocate heap in.
76  * @param[in] _cmp Comparator used to compare elements.
77  * @param[in] _talloc_type of elements.
78  * @param[in] _field to store heap indexes in.
79  * @param[in] _init the initial number of elements to allocate.
80  * Pass 0 to use the default.
81  * @return
82  * - A new minmax heap.
83  * - NULL on error.
84  */
85 #define fr_minmax_heap_talloc_alloc(_ctx, _cmp, _talloc_type, _field, _init) \
86  _fr_minmax_heap_alloc(_ctx, _cmp, #_talloc_type, (size_t)offsetof(_talloc_type, _field), _init)
87 
88 fr_minmax_heap_t *_fr_minmax_heap_alloc(TALLOC_CTX *ctx, fr_minmax_heap_cmp_t cmp, char const *talloc_type, size_t offset, unsigned int init) CC_HINT(nonnull(2));
89 
90 /** Check if an entry is inserted into a heap
91  *
92  */
94 {
95  return (heap_idx > 0);
96 }
97 
98 int fr_minmax_heap_insert(fr_minmax_heap_t *hp, void *data) CC_HINT(nonnull);
99 int fr_minmax_heap_extract(fr_minmax_heap_t *hp, void *data) CC_HINT(nonnull);
104 
106 
109 
110 /** Iterate over the contents of a minmax_heap
111  *
112  * @note The initializer section of a for loop can't declare variables with distinct
113  * base types, so we require a containing block, and can't follow the standard
114  * do {...} while(0) dodge. The code to be run for each item in the heap should
115  * therefore start with 1 open braces and end with 2 close braces, and shouldn't
116  * be followed with a semicolon.
117  * This may fake out code formatting programs, including editors.
118  *
119  * @param[in] _hp to iterate over.
120  * @param[in] _type of item the heap contains.
121  * @param[in] _data Name of variable holding a pointer to the heap element.
122  * Will be declared in the scope of the loop.
123  */
124 #define fr_minmax_heap_foreach(_hp, _type, _data) \
125 { \
126  fr_minmax_heap_iter_t _iter; \
127  for (_type *_data = fr_minmax_heap_iter_init(_hp, &_iter); _data; _data = fr_minmax_heap_iter_next(_hp, &_iter))
128 
129 #ifndef TALLOC_GET_TYPE_ABORT_NOOP
130 CC_HINT(nonnull(1)) void fr_minmax_heap_verify(char const *file, int line, fr_minmax_heap_t const *hp);
131 # define FR_MINMAX_HEAP_VERIFY(_hp) fr_minmax_heap_verify(__FILE__, __LINE__, _hp)
132 #elif !defined(NDEBUG)
133 # define FR_MINMAX_HEAP_VERIFY(_hp) fr_assert(_hp)
134 #else
135 # define FR_MINMAX_HEAP_VERIFY(_hp)
136 #endif
137 
138 
139 #ifdef __cplusplus
140 }
141 #endif
142 
int const char * file
Definition: acutest.h:702
int const char int line
Definition: acutest.h:702
#define RCSIDH(h, id)
Definition: build.h:482
fr_dcursor_iter_t iter
Definition: dcursor.h:147
unsigned int uint32_t
Definition: merged_model.c:33
fr_minmax_heap_cmp_t cmp
Comparator function.
Definition: minmax_heap.c:60
size_t offset
Offset of heap index in element structure.
Definition: minmax_heap.c:55
int fr_minmax_heap_insert(fr_minmax_heap_t *hp, void *data)
Definition: minmax_heap.c:424
size_t fr_minmax_heap_pre_alloc_size(unsigned int count)
struct fr_minmax_heap_s * fr_minmax_heap_t
The main minmax heap structure Note that fr_minmax_heap_t is a pointer to fr_minmax_heap_s.
Definition: minmax_heap.h:57
void * fr_minmax_heap_iter_next(fr_minmax_heap_t *hp, fr_minmax_heap_iter_t *iter)
Get the next entry in a minmax heap.
Definition: minmax_heap.c:573
void * fr_minmax_heap_min_peek(fr_minmax_heap_t *hp)
Definition: minmax_heap.c:449
int8_t(* fr_minmax_heap_cmp_t)(void const *a, void const *b)
Comparator to order elements.
Definition: minmax_heap.h:50
uint32_t fr_minmax_heap_num_elements(fr_minmax_heap_t *hp)
Return the number of elements in the minmax heap.
Definition: minmax_heap.c:533
static bool fr_minmax_heap_entry_inserted(fr_minmax_heap_index_t heap_idx)
Check if an entry is inserted into a heap.
Definition: minmax_heap.h:93
void * fr_minmax_heap_max_pop(fr_minmax_heap_t *hp)
Definition: minmax_heap.c:477
void * fr_minmax_heap_min_pop(fr_minmax_heap_t *hp)
Definition: minmax_heap.c:457
unsigned int fr_minmax_heap_iter_t
Definition: minmax_heap.h:38
void * fr_minmax_heap_max_peek(fr_minmax_heap_t *hp)
Definition: minmax_heap.c:466
fr_minmax_heap_t * _fr_minmax_heap_alloc(TALLOC_CTX *ctx, fr_minmax_heap_cmp_t cmp, char const *talloc_type, size_t offset, unsigned int init))
Definition: minmax_heap.c:111
unsigned int fr_minmax_heap_index_t
Definition: minmax_heap.h:37
int fr_minmax_heap_extract(fr_minmax_heap_t *hp, void *data)
Definition: minmax_heap.c:486
void * fr_minmax_heap_iter_init(fr_minmax_heap_t *hp, fr_minmax_heap_iter_t *iter)
Iterate over entries in a minmax heap.
Definition: minmax_heap.c:551
void fr_minmax_heap_verify(char const *file, int line, fr_minmax_heap_t const *hp)
Definition: minmax_heap.c:584
return count
Definition: module.c:163
init
Enter the EAP-IDENTITY state.
Definition: state_machine.c:90
static fr_slen_t data
Definition: value.h:1265
int nonnull(2, 5))