Zephyr API Documentation 4.4.99
A Scalable Open Source RTOS
Loading...
Searching...
No Matches
min_heap_ref.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2026 Aerlync Labs Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
12
13#ifndef ZEPHYR_INCLUDE_SYS_MIN_HEAP_REF_H_
14#define ZEPHYR_INCLUDE_SYS_MIN_HEAP_REF_H_
15
16#include <zephyr/sys/util.h>
17
18#ifdef __cplusplus
19extern "C" {
20#endif
21
34
45
60typedef int (*min_heap_ref_cmp_t)(const struct min_heap_handle *a, const struct min_heap_handle *b);
61
75
83#define MIN_HEAP_REF_DEFINE(name, cap, cmp_func) \
84 static struct min_heap_handle *(name##_storage)[(cap)]; \
85 struct min_heap_ref name = { \
86 .storage = (name##_storage), \
87 .capacity = (cap), \
88 .size = 0, \
89 .cmp = (cmp_func), \
90 }
91
99#define MIN_HEAP_REF_DEFINE_STATIC(name, cap, cmp_func) \
100 static struct min_heap_handle *(name##_storage)[(cap)]; \
101 static struct min_heap_ref name = { \
102 .storage = (name##_storage), \
103 .capacity = (cap), \
104 .size = 0, \
105 .cmp = (cmp_func), \
106 }
107
123static inline void min_heap_ref_init(struct min_heap_ref *heap, struct min_heap_handle **storage,
124 size_t capacity, min_heap_ref_cmp_t cmp)
125{
126 __ASSERT_NO_MSG(heap != NULL);
127 __ASSERT_NO_MSG(storage != NULL);
128 __ASSERT_NO_MSG(cmp != NULL);
129
130 heap->storage = storage;
131 heap->capacity = capacity;
132 heap->size = 0;
133 heap->cmp = cmp;
134}
135
143static inline void min_heap_ref_swap(struct min_heap_ref *heap, size_t a, size_t b)
144{
145 struct min_heap_handle *tmp = heap->storage[a];
146
147 heap->storage[a] = heap->storage[b];
148 heap->storage[b] = tmp;
149 heap->storage[a]->idx = (uint16_t)(a + 1U);
150 heap->storage[b]->idx = (uint16_t)(b + 1U);
151}
152
161static inline void min_heap_ref_heapify_up(struct min_heap_ref *heap, size_t index)
162{
163 while (index > 0) {
164 size_t parent = (index - 1U) / 2U;
165
166 if (heap->cmp(heap->storage[index], heap->storage[parent]) >= 0) {
167 break;
168 }
169 min_heap_ref_swap(heap, index, parent);
170 index = parent;
171 }
172}
173
183static inline void min_heap_ref_heapify_down(struct min_heap_ref *heap, size_t index)
184{
185 for (size_t left = 2U * index + 1U; left < heap->size; left = 2U * index + 1U) {
186 size_t right = left + 1U;
187 size_t smallest = index;
188
189 if (heap->cmp(heap->storage[left], heap->storage[smallest]) < 0) {
190 smallest = left;
191 }
192 if (right < heap->size &&
193 heap->cmp(heap->storage[right], heap->storage[smallest]) < 0) {
194 smallest = right;
195 }
196 if (smallest == index) {
197 break;
198 }
199 min_heap_ref_swap(heap, index, smallest);
200 index = smallest;
201 }
202}
203
216static inline int min_heap_ref_push(struct min_heap_ref *heap, struct min_heap_handle *handle)
217{
218 __ASSERT_NO_MSG(heap != NULL);
219 __ASSERT_NO_MSG(handle != NULL);
220 __ASSERT_NO_MSG(handle->idx == 0U);
221 __ASSERT(heap->size < UINT16_MAX, "heap idx overflow");
222
223 if (heap->size >= heap->capacity) {
224 return -1;
225 }
226
227 heap->storage[heap->size] = handle;
228 handle->idx = (uint16_t)(heap->size + 1U);
229 heap->size++;
230 min_heap_ref_heapify_up(heap, heap->size - 1U);
231
232 return 0;
233}
234
244static inline const struct min_heap_handle *min_heap_ref_peek(const struct min_heap_ref *heap)
245{
246 __ASSERT_NO_MSG(heap != NULL);
247 return heap->size == 0U ? NULL : heap->storage[0];
248}
249
260static inline bool min_heap_ref_remove(struct min_heap_ref *heap, struct min_heap_handle *handle)
261{
262 __ASSERT_NO_MSG(heap != NULL);
263 __ASSERT_NO_MSG(handle != NULL);
264
265 if (handle->idx == 0U || (size_t)handle->idx > heap->size) {
266 return false;
267 }
268
269 size_t id = (size_t)(handle->idx - 1U);
270
271 handle->idx = 0U;
272 heap->size--;
273
274 if (id != heap->size) {
275 struct min_heap_handle *last = heap->storage[heap->size];
276
277 heap->storage[heap->size] = NULL;
278 heap->storage[id] = last;
279 last->idx = (uint16_t)(id + 1U);
281 min_heap_ref_heapify_up(heap, id);
282 } else {
283 heap->storage[heap->size] = NULL;
284 }
285
286 return true;
287}
288
298static inline bool min_heap_ref_is_empty(struct min_heap_ref *heap)
299{
300 __ASSERT_NO_MSG(heap != NULL);
301 return (heap->size == 0);
302}
303
312static inline struct min_heap_handle *min_heap_ref_pop(struct min_heap_ref *heap)
313{
314 __ASSERT_NO_MSG(heap != NULL);
315
316 if (heap->size == 0U) {
317 return NULL;
318 }
319
320 struct min_heap_handle *min = heap->storage[0];
321 bool ok = min_heap_ref_remove(heap, min);
322
323 __ASSERT_NO_MSG(ok);
324 (void)ok;
325 return min;
326}
327
345#define MIN_HEAP_REF_FOREACH(__heap, __handle) \
346 for (size_t __mh_i = 0; \
347 (__mh_i < (__heap)->size) && ((__handle) = (__heap)->storage[__mh_i], true); \
348 __mh_i++)
349
364#define MIN_HEAP_REF_FOREACH_CONTAINER(__heap, __cn, __field) \
365 for (size_t __mh_i = 0; \
366 (__mh_i < (__heap)->size) && \
367 ((__cn) = CONTAINER_OF((__heap)->storage[__mh_i], __typeof__(*(__cn)), __field), \
368 true); \
369 __mh_i++)
370
374
375#ifdef __cplusplus
376}
377#endif
378
379#endif /* ZEPHYR_INCLUDE_SYS_MIN_HEAP_REF_H_ */
static void min_heap_ref_heapify_up(struct min_heap_ref *heap, size_t index)
Restore heap order by moving a node up the tree.
Definition min_heap_ref.h:161
static void min_heap_ref_swap(struct min_heap_ref *heap, size_t a, size_t b)
Swap two elements in the heap storage, updating their idx fields.
Definition min_heap_ref.h:143
static const struct min_heap_handle * min_heap_ref_peek(const struct min_heap_ref *heap)
Peek at the top element of the min-heap.
Definition min_heap_ref.h:244
static void min_heap_ref_heapify_down(struct min_heap_ref *heap, size_t index)
Restore heap order by moving a node down the tree.
Definition min_heap_ref.h:183
static struct min_heap_handle * min_heap_ref_pop(struct min_heap_ref *heap)
Remove and return the highest priority element's handle.
Definition min_heap_ref.h:312
static bool min_heap_ref_remove(struct min_heap_ref *heap, struct min_heap_handle *handle)
Remove a specific element from the min-heap by handle.
Definition min_heap_ref.h:260
static void min_heap_ref_init(struct min_heap_ref *heap, struct min_heap_handle **storage, size_t capacity, min_heap_ref_cmp_t cmp)
Initialize a min-heap instance at runtime.
Definition min_heap_ref.h:123
static bool min_heap_ref_is_empty(struct min_heap_ref *heap)
Check if the min heap is empty.
Definition min_heap_ref.h:298
static int min_heap_ref_push(struct min_heap_ref *heap, struct min_heap_handle *handle)
Push a handle into the min-heap.
Definition min_heap_ref.h:216
int(* min_heap_ref_cmp_t)(const struct min_heap_handle *a, const struct min_heap_handle *b)
Comparator function type for min-heap ordering.
Definition min_heap_ref.h:60
#define min(a, b)
Return smaller value of two provided expressions.
Definition minmax.h:81
#define UINT16_MAX
Definition stdint.h:28
__UINT16_TYPE__ uint16_t
Definition stdint.h:89
Embeddable heap position handle.
Definition min_heap_ref.h:41
uint16_t idx
1-based storage index; 0 means not in heap
Definition min_heap_ref.h:43
min-heap data structure with user-provided comparator.
Definition min_heap_ref.h:65
min_heap_ref_cmp_t cmp
Comparator function: returns <0, 0, >0.
Definition min_heap_ref.h:73
size_t capacity
Maximum number of elements.
Definition min_heap_ref.h:69
size_t size
Current elements count.
Definition min_heap_ref.h:71
struct min_heap_handle ** storage
Array of handle pointers: one slot per element.
Definition min_heap_ref.h:67
Misc utilities.