zephyr/include/zephyr/sys/min_heap.h
Sayooj K Karun e719ba239f include: zephyr: sys: simplify MIN_HEAP_FOREACH macro
Refactor the `MIN_HEAP_FOREACH` macro to use a cleaner
for-loop style removing the need for a third `body` argument.
Update the sample application with the new macro changes.

Signed-off-by: Sayooj K Karun <sayooj@aerlync.com>
2025-06-26 11:58:05 -04:00

245 lines
7.1 KiB
C

/*
* Copyright (c) 2025 Aerlync Labs Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_SYS_MIN_HEAP_H_
#define ZEPHYR_INCLUDE_SYS_MIN_HEAP_H_
#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief min_heap
* @defgroup min_heap_apis Min-Heap service
* @ingroup datastructure_apis
* @{
*/
/**
* @brief Comparator function type for min-heap ordering.
*
* This function compares two heap nodes to establish their relative order.
* It must be implemented by the user and provided at min-heap
* initialization.
*
* @param a First user defined data pointer for comparison.
* @param b Second user defined data pointer for comparison.
*
* @return Negative value if @p a is less than @p b,
* positive value if @p a is greater than @p b,
* zero if they are equal.
*/
typedef int (*min_heap_cmp_t)(const void *a,
const void *b);
/**
* @brief Equality function for finding a node in the heap.
*
* @param node Pointer to a user defined data.
* @param other Pointer to a user-defined key or structure to compare with.
*
* @return true if the node matches the search criteria, false otherwise.
*/
typedef bool (*min_heap_eq_t)(const void *node,
const void *other);
/**
* @brief min-heap data structure with user-provided comparator.
*/
struct min_heap {
/** Raw pointer to contiguous memory for elements */
void *storage;
/** Maximum number of elements */
size_t capacity;
/** Size of each element*/
size_t elem_size;
/** Current elements count */
size_t size;
/** Comparator function */
min_heap_cmp_t cmp;
};
/**
* @brief Define and initialize a heap instance at runtime.
*
* @param name Name of the heap variable.
* @param storage Pointer to the preallocated storage.
* @param cap Capacity (number of elements).
* @param size Size of each element.
* @param cmp_func Comparator function for the heap.
*/
#define MIN_HEAP_DEFINE(name, storage, cap, size, cmp_func) \
struct min_heap name; \
min_heap_init(&name, storage, cap, size, cmp_func)
/**
* @brief Define a statically allocated and aligned min-heap instance.
*
* @param name Base name for the heap instance.
* @param cap Capacity (number of elements).
* @param elem_sz Size in bytes of each element.
* @param align Required alignment of each element.
* @param cmp_func Comparator function used by the heap
*/
#define MIN_HEAP_DEFINE_STATIC(name, cap, elem_sz, align, cmp_func) \
static uint8_t name##_storage[(cap) * (elem_sz)] __aligned(align); \
static struct min_heap name = { \
.storage = name##_storage, \
.capacity = (cap), \
.elem_size = (elem_sz), \
.size = 0, \
.cmp = (cmp_func) \
}
/**
* @brief Initialize a min-heap instance at runtime.
*
* Sets up the internal structure of a min heap using a user-provided
* memory block, capacity, and comparator function. This function must
* be called before using the heap if not statically defined.
*
* @param heap Pointer to the min-heap structure.
* @param storage Pointer to memory block for storing elements.
* @param cap Maximum number of elements the heap can store.
* @param elem_size Size in bytes of each element.
* @param cmp Comparator function used to order the heap elements.
*
* @note All arguments must be valid. This function does not allocate memory.
*
*/
void min_heap_init(struct min_heap *heap, void *storage, size_t cap,
size_t elem_size, min_heap_cmp_t cmp);
/**
* @brief Push an element into the min-heap.
*
* Adds a new element to the min-heap and restores the heap order by moving it
* upward as necessary. Insert operation will fail if the min-heap
* has reached full capacity.
*
* @param heap Pointer to the min-heap.
* @param item Pointer to the item to insert.
*
* @return 0 on Success, -ENOMEM if the heap is full.
*/
int min_heap_push(struct min_heap *heap, const void *item);
/**
* @brief Peek at the top element of the min-heap.
*
* The function will not remove the element from the min-heap.
*
* @param heap Pointer to the min-heap.
*
* @return Pointer to the top priority element, or NULL if the heap is empty.
*/
void *min_heap_peek(const struct min_heap *heap);
/**
* @brief Remove a specific element from the min-heap.
*
* Removes the specified node from the min-heap based on the ID it stores
* internally. The min-heap is rebalanced after removal to ensure
* proper ordering.
* The caller gains ownership of the returned element and is responsible for
* any further management of its memory or reuse.
*
* @param heap Pointer to the min-heap.
* @param id element ID to be removed.
* @param out_buf User-provided buffer where the removed element will be copied.
*
* @return true in success, false otherwise.
*/
bool min_heap_remove(struct min_heap *heap, size_t id, void *out_buf);
/**
* @brief Check if the min heap is empty.
*
* This function checks whether the heap contains any elements.
*
* @param heap Pointer to the min heap.
*
* @return true if heap is empty, false otherwise.
*/
static inline bool min_heap_is_empty(struct min_heap *heap)
{
__ASSERT_NO_MSG(heap != NULL);
return (heap->size == 0);
}
/**
* @brief Remove and return the highest priority element in the heap.
*
* The caller gains ownership of the returned element and is responsible for
* any further management of its memory or reuse. The min-heap is rebalanced
* after removal to ensure proper ordering.
*
* @param heap Pointer to heap.
* @param out_buf User-provided buffer where the removed element will be copied.
*
* @return true in success, false otherwise.
*/
bool min_heap_pop(struct min_heap *heap, void *out_buf);
/**
* @brief Search for a node in the heap matching a condition.
*
* @param heap Pointer to the heap structure.
* @param eq Function used to compare each node with the search target.
* @param other Pointer to the data used for comparison in the eq function.
* @param out_id Optional output parameter to store the index of the found node.
*
* @return Pointer to the first matching element, or NULL if not found.
*/
void *min_heap_find(struct min_heap *heap, min_heap_eq_t eq,
const void *other, size_t *out_id);
/**
* @brief Get a pointer to the element at the specified index.
*
* @param heap Pointer to the min-heap.
* @param index Index of the element to retrieve.
*
* @return Pointer to the element at the given index.
*/
static inline void *min_heap_get_element(const struct min_heap *heap,
size_t index)
{
return (void *)((uintptr_t)heap->storage + index * heap->elem_size);
}
/**
* @brief Iterate over each node in the heap.
*
* @param heap Pointer to the heap.
* @param node_var The loop variable used to reference each node.
*
* Example:
* ```
* void *node;
* MIN_HEAP_FOREACH(&heap, node) {
* printk("Value: %d\n", node->value);
* }
* ```
*/
#define MIN_HEAP_FOREACH(heap, node_var) \
for (size_t _i = 0; \
_i < (heap)->size && (((node_var) = min_heap_get_element((heap), _i)) || true); ++_i)
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_SYS_MIN_HEAP_H_ */