LCOV - code coverage report
Current view: top level - zephyr/sys - hash_map_api.h Hit Total Coverage
Test: new.info Lines: 31 32 96.9 %
Date: 2024-12-22 00:14:23

          Line data    Source code
       1           0 : /*
       2             :  * Copyright (c) 2022 Meta
       3             :  *
       4             :  * SPDX-License-Identifier: Apache-2.0
       5             :  */
       6             : 
       7             : #ifndef ZEPHYR_INCLUDE_SYS_HASHMAP_API_H_
       8             : #define ZEPHYR_INCLUDE_SYS_HASHMAP_API_H_
       9             : 
      10             : #include <stdbool.h>
      11             : #include <stddef.h>
      12             : #include <stdint.h>
      13             : 
      14             : #include <zephyr/sys/hash_function.h>
      15             : #include <zephyr/sys/util.h>
      16             : 
      17             : #ifdef __cplusplus
      18             : extern "C" {
      19             : #endif
      20             : 
      21             : /**
      22             :  * @file
      23             :  * @defgroup hashmap_apis Hashmap
      24             :  * @ingroup datastructure_apis
      25             :  *
      26             :  * @brief Hashmap (Hash Table) API
      27             :  *
      28             :  * Hashmaps (a.k.a Hash Tables) sacrifice space for speed. All operations
      29             :  * on a Hashmap (insert, delete, search) are O(1) complexity (on average).
      30             :  *
      31             :  * @defgroup hashmap_implementations Hashmap Implementations
      32             :  * @ingroup hashmap_apis
      33             :  *
      34             :  * @addtogroup hashmap_apis
      35             :  * @{
      36             :  */
      37             : 
      38             : /**
      39             :  * @brief Generic Hashmap iterator interface
      40             :  *
      41             :  * @note @a next should not be used without first checking
      42             :  * @ref sys_hashmap_iterator_has_next
      43             :  */
      44           1 : struct sys_hashmap_iterator {
      45             :         /** Pointer to the associated Hashmap */
      46           1 :         const struct sys_hashmap *map;
      47             :         /** Modify the iterator in-place to point to the next Hashmap entry */
      48           1 :         void (*next)(struct sys_hashmap_iterator *it);
      49             :         /** Implementation-specific iterator state */
      50           1 :         void *state;
      51             :         /** Key associated with the current entry */
      52           1 :         uint64_t key;
      53             :         /** Value associated with the current entry */
      54           1 :         uint64_t value;
      55             :         /** Number of entries in the map */
      56           1 :         const size_t size;
      57             :         /** Number of entries already iterated */
      58           1 :         size_t pos;
      59             : };
      60             : 
      61             : /**
      62             :  * @brief Check if a Hashmap iterator has a next entry
      63             :  *
      64             :  * @param it Hashmap iterator
      65             :  * @return true if there is a next entry
      66             :  * @return false if there is no next entry
      67             :  */
      68           1 : static inline bool sys_hashmap_iterator_has_next(const struct sys_hashmap_iterator *it)
      69             : {
      70             :         return it->pos < it->size;
      71             : }
      72             : 
      73             : /**
      74             :  * @brief Allocator interface for @ref sys_hashmap
      75             :  *
      76             :  * The Hashmap allocator can be any allocator that behaves similarly to `realloc()` with the
      77             :  * additional specification that the allocator behaves like `free()` when @p new_size is zero.
      78             :  *
      79             :  * @param ptr Previously allocated memory region or `NULL` to make a new vallocation.
      80             :  * @param new_size the new size of the allocation, in bytes.
      81             :  *
      82             :  * @see <a href="https://en.cppreference.com/w/c/memory/realloc">realloc</a>
      83             :  */
      84           1 : typedef void *(*sys_hashmap_allocator_t)(void *ptr, size_t new_size);
      85             : 
      86             : /**
      87             :  * @brief In-place iterator constructor for @ref sys_hashmap
      88             :  *
      89             :  * Construct an iterator, @p it, for @p map.
      90             :  *
      91             :  * @param map Hashmap to iterate over.
      92             :  * @param it Iterator to initialize.
      93             :  */
      94           1 : typedef void (*sys_hashmap_iterator_t)(const struct sys_hashmap *map,
      95             :                                        struct sys_hashmap_iterator *it);
      96             : 
      97             : /**
      98             :  * @brief Callback interface for @ref sys_hashmap
      99             :  *
     100             :  * This callback is used by some Hashmap methods.
     101             :  *
     102             :  * @param key Key corresponding to @p value
     103             :  * @param value Value corresponding to @p key
     104             :  * @param cookie User-specified variable
     105             :  */
     106           1 : typedef void (*sys_hashmap_callback_t)(uint64_t key, uint64_t value, void *cookie);
     107             : 
     108             : /**
     109             :  * @brief Clear all entries contained in a @ref sys_hashmap
     110             :  *
     111             :  * @note If the values in a particular Hashmap are
     112             :  *
     113             :  * @param map Hashmap to clear
     114             :  * @param cb Callback to call for each entry
     115             :  * @param cookie User-specified variable
     116             :  */
     117           1 : typedef void (*sys_hashmap_clear_t)(struct sys_hashmap *map, sys_hashmap_callback_t cb,
     118             :                                     void *cookie);
     119             : 
     120             : /**
     121             :  * @brief Insert a new entry into a @ref sys_hashmap
     122             :  *
     123             :  * Insert a new @p key - @p value pair into @p map.
     124             :  *
     125             :  * @param map Hashmap to insert into
     126             :  * @param key Key to associate with @p value
     127             :  * @param value Value to associate with @p key
     128             :  * @param old_value Location to store the value previously associated with @p key or `NULL`
     129             :  * @retval 0 if @p value was inserted for an existing key, in which case @p old_value will contain
     130             :  * the previous value
     131             :  * @retval 1 if a new entry was inserted for the @p key - @p value pair
     132             :  * @retval -ENOMEM if memory allocation failed
     133             :  */
     134           1 : typedef int (*sys_hashmap_insert_t)(struct sys_hashmap *map, uint64_t key, uint64_t value,
     135             :                                     uint64_t *old_value);
     136             : 
     137             : /**
     138             :  * @brief Remove an entry from a @ref sys_hashmap
     139             :  *
     140             :  * Erase the entry associated with key @p key, if one exists.
     141             :  *
     142             :  * @param map Hashmap to remove from
     143             :  * @param key Key to remove from @p map
     144             :  * @param value Location to store a potential value associated with @p key or `NULL`
     145             :  *
     146             :  * @retval true if @p map was modified as a result of this operation.
     147             :  * @retval false if @p map does not contain a value associated with @p key.
     148             :  */
     149           1 : typedef bool (*sys_hashmap_remove_t)(struct sys_hashmap *map, uint64_t key, uint64_t *value);
     150             : 
     151             : /**
     152             :  * @brief Get a value from a @ref sys_hashmap
     153             :  *
     154             :  * Look-up the @ref uint64_t associated with @p key, if one exists.
     155             :  *
     156             :  * @param map Hashmap to search through
     157             :  * @param key Key with which to search @p map
     158             :  * @param value Location to store a potential value associated with @p key or `NULL`
     159             :  *
     160             :  * @retval true if @p map contains a value associated with @p key.
     161             :  * @retval false if @p map does not contain a value associated with @p key.
     162             :  */
     163           1 : typedef bool (*sys_hashmap_get_t)(const struct sys_hashmap *map, uint64_t key, uint64_t *value);
     164             : 
     165             : /**
     166             :  * @brief Generic Hashmap API
     167             :  */
     168           1 : struct sys_hashmap_api {
     169             :         /** Iterator constructor (in-place) */
     170           1 :         sys_hashmap_iterator_t iter;
     171             :         /** Clear the hash table, freeing all resources */
     172           1 :         sys_hashmap_clear_t clear;
     173             :         /** Insert a key-value pair into the Hashmap */
     174           1 :         sys_hashmap_insert_t insert;
     175             :         /** Remove a key-value pair from the Hashmap */
     176           1 :         sys_hashmap_remove_t remove;
     177             :         /** Retrieve the value associated with a given key from the Hashmap */
     178           1 :         sys_hashmap_get_t get;
     179             : };
     180             : 
     181             : /**
     182             :  * @brief Generic Hashmap configuration
     183             :  *
     184             :  * When there is a known limit imposed on the number of entries in the Hashmap,
     185             :  * users should specify that via @a max_size. When the Hashmap should have
     186             :  * no artificial limitation in size (and be bounded only by the provided
     187             :  * allocator), users should specify `SIZE_MAX` here.
     188             :  *
     189             :  * The @a load_factor is defined as the size of the Hashmap divided by the
     190             :  * number of buckets. In this case, the size of the Hashmap is defined as
     191             :  * the number of valid entries plus the number of invalidated entries.
     192             :  *
     193             :  * The @a initial_n_buckets is defined as the number of buckets to allocate
     194             :  * when moving from size 0 to size 1 such that the maximum @a load_factor
     195             :  * property is preserved.
     196             :  */
     197           1 : struct sys_hashmap_config {
     198             :         /** Maximum number of entries */
     199           1 :         size_t max_size;
     200             :         /** Maximum load factor expressed in hundredths */
     201           1 :         uint8_t load_factor;
     202             :         /** Initial number of buckets to allocate */
     203           1 :         uint8_t initial_n_buckets;
     204             : };
     205             : 
     206             : /**
     207             :  * @brief Initializer for @p sys_hashmap_config
     208             :  *
     209             :  * This macro helps to initialize a structure of type @p sys_hashmap_config.
     210             :  *
     211             :  * @param _max_size Maximum number of entries
     212             :  * @param _load_factor Maximum load factor of expressed in hundredths
     213             :  */
     214           1 : #define SYS_HASHMAP_CONFIG(_max_size, _load_factor)                                                \
     215             :         {                                                                                          \
     216             :                 .max_size = (size_t)_max_size, .load_factor = (uint8_t)_load_factor,               \
     217             :                 .initial_n_buckets = NHPOT(DIV_ROUND_UP(100, _load_factor)),                   \
     218             :         }
     219             : 
     220             : /**
     221             :  * @brief Generic Hashmap data
     222             :  *
     223             :  * @note When @a size is zero, @a buckets should be `NULL`.
     224             :  */
     225           1 : struct sys_hashmap_data {
     226             :         /** Pointer for implementation-specific Hashmap storage */
     227           1 :         void *buckets;
     228             :         /** The number of buckets currently allocated */
     229           1 :         size_t n_buckets;
     230             :         /** The number of entries currently in the Hashmap */
     231           1 :         size_t size;
     232             : };
     233             : 
     234             : /** @} */
     235             : 
     236             : #ifdef __cplusplus
     237             : }
     238             : #endif
     239             : 
     240             : #endif /* ZEPHYR_INCLUDE_SYS_HASHMAP_API_H_ */

Generated by: LCOV version 1.14