Coverage Report

Created: 2025-12-14 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/freeradius-devel/util/minmax_heap.h
Line
Count
Source
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
 */
57
typedef struct fr_minmax_heap_s * fr_minmax_heap_t;
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
 */
93
static inline bool fr_minmax_heap_entry_inserted(fr_minmax_heap_index_t heap_idx)
94
0
{
95
0
  return (heap_idx > 0);
96
0
}
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);
100
void    *fr_minmax_heap_min_pop(fr_minmax_heap_t *hp) CC_HINT(nonnull);
101
void    *fr_minmax_heap_min_peek(fr_minmax_heap_t *hp) CC_HINT(nonnull);
102
void    *fr_minmax_heap_max_pop(fr_minmax_heap_t *hp) CC_HINT(nonnull);
103
void    *fr_minmax_heap_max_peek(fr_minmax_heap_t *hp) CC_HINT(nonnull);
104
105
uint32_t  fr_minmax_heap_num_elements(fr_minmax_heap_t *hp) CC_HINT(nonnull);
106
107
void    *fr_minmax_heap_iter_init(fr_minmax_heap_t *hp, fr_minmax_heap_iter_t *iter) CC_HINT(nonnull);
108
void    *fr_minmax_heap_iter_next(fr_minmax_heap_t *hp, fr_minmax_heap_iter_t *iter) CC_HINT(nonnull);
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