LCOV - code coverage report
Current view: top level - basic - hashmap.h (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 129 135 95.6 %
Date: 2019-08-23 13:36:53 Functions: 63 66 95.5 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 7 12 58.3 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : #pragma once
       3                 :            : 
       4                 :            : #include <limits.h>
       5                 :            : #include <stdbool.h>
       6                 :            : #include <stddef.h>
       7                 :            : 
       8                 :            : #include "hash-funcs.h"
       9                 :            : #include "macro.h"
      10                 :            : #include "util.h"
      11                 :            : 
      12                 :            : /*
      13                 :            :  * A hash table implementation. As a minor optimization a NULL hashmap object
      14                 :            :  * will be treated as empty hashmap for all read operations. That way it is not
      15                 :            :  * necessary to instantiate an object for each Hashmap use.
      16                 :            :  *
      17                 :            :  * If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap),
      18                 :            :  * the implementation will:
      19                 :            :  * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py)
      20                 :            :  * - perform extra checks for invalid use of iterators
      21                 :            :  */
      22                 :            : 
      23                 :            : #define HASH_KEY_SIZE 16
      24                 :            : 
      25                 :            : typedef void* (*hashmap_destroy_t)(void *p);
      26                 :            : 
      27                 :            : /* The base type for all hashmap and set types. Many functions in the
      28                 :            :  * implementation take (HashmapBase*) parameters and are run-time polymorphic,
      29                 :            :  * though the API is not meant to be polymorphic (do not call functions
      30                 :            :  * internal_*() directly). */
      31                 :            : typedef struct HashmapBase HashmapBase;
      32                 :            : 
      33                 :            : /* Specific hashmap/set types */
      34                 :            : typedef struct Hashmap Hashmap;               /* Maps keys to values */
      35                 :            : typedef struct OrderedHashmap OrderedHashmap; /* Like Hashmap, but also remembers entry insertion order */
      36                 :            : typedef struct Set Set;                       /* Stores just keys */
      37                 :            : 
      38                 :            : typedef struct IteratedCache IteratedCache;   /* Caches the iterated order of one of the above */
      39                 :            : 
      40                 :            : /* Ideally the Iterator would be an opaque struct, but it is instantiated
      41                 :            :  * by hashmap users, so the definition has to be here. Do not use its fields
      42                 :            :  * directly. */
      43                 :            : typedef struct {
      44                 :            :         unsigned idx;         /* index of an entry to be iterated next */
      45                 :            :         const void *next_key; /* expected value of that entry's key pointer */
      46                 :            : #if ENABLE_DEBUG_HASHMAP
      47                 :            :         unsigned put_count;   /* hashmap's put_count recorded at start of iteration */
      48                 :            :         unsigned rem_count;   /* hashmap's rem_count in previous iteration */
      49                 :            :         unsigned prev_idx;    /* idx in previous iteration */
      50                 :            : #endif
      51                 :            : } Iterator;
      52                 :            : 
      53                 :            : #define _IDX_ITERATOR_FIRST (UINT_MAX - 1)
      54                 :            : #define ITERATOR_FIRST ((Iterator) { .idx = _IDX_ITERATOR_FIRST, .next_key = NULL })
      55                 :            : 
      56                 :            : /* Macros for type checking */
      57                 :            : #define PTR_COMPATIBLE_WITH_HASHMAP_BASE(h) \
      58                 :            :         (__builtin_types_compatible_p(typeof(h), HashmapBase*) || \
      59                 :            :          __builtin_types_compatible_p(typeof(h), Hashmap*) || \
      60                 :            :          __builtin_types_compatible_p(typeof(h), OrderedHashmap*) || \
      61                 :            :          __builtin_types_compatible_p(typeof(h), Set*))
      62                 :            : 
      63                 :            : #define PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h) \
      64                 :            :         (__builtin_types_compatible_p(typeof(h), Hashmap*) || \
      65                 :            :          __builtin_types_compatible_p(typeof(h), OrderedHashmap*)) \
      66                 :            : 
      67                 :            : #define HASHMAP_BASE(h) \
      68                 :            :         __builtin_choose_expr(PTR_COMPATIBLE_WITH_HASHMAP_BASE(h), \
      69                 :            :                 (HashmapBase*)(h), \
      70                 :            :                 (void)0)
      71                 :            : 
      72                 :            : #define PLAIN_HASHMAP(h) \
      73                 :            :         __builtin_choose_expr(PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h), \
      74                 :            :                 (Hashmap*)(h), \
      75                 :            :                 (void)0)
      76                 :            : 
      77                 :            : #if ENABLE_DEBUG_HASHMAP
      78                 :            : # define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line
      79                 :            : # define HASHMAP_DEBUG_SRC_ARGS   , __func__, PROJECT_FILE, __LINE__
      80                 :            : # define HASHMAP_DEBUG_PASS_ARGS   , func, file, line
      81                 :            : #else
      82                 :            : # define HASHMAP_DEBUG_PARAMS
      83                 :            : # define HASHMAP_DEBUG_SRC_ARGS
      84                 :            : # define HASHMAP_DEBUG_PASS_ARGS
      85                 :            : #endif
      86                 :            : 
      87                 :            : Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
      88                 :            : OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
      89                 :            : #define hashmap_new(ops) internal_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS)
      90                 :            : #define ordered_hashmap_new(ops) internal_ordered_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS)
      91                 :            : 
      92                 :            : HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
      93                 :     218816 : static inline Hashmap *hashmap_free(Hashmap *h) {
      94                 :     218816 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL);
      95                 :            : }
      96                 :       8252 : static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) {
      97                 :       8252 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL);
      98                 :            : }
      99                 :            : 
     100                 :       1309 : static inline Hashmap *hashmap_free_free(Hashmap *h) {
     101                 :       1309 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free);
     102                 :            : }
     103                 :      39989 : static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) {
     104                 :      39989 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free);
     105                 :            : }
     106                 :            : 
     107                 :        204 : static inline Hashmap *hashmap_free_free_key(Hashmap *h) {
     108                 :        204 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL);
     109                 :            : }
     110                 :          0 : static inline OrderedHashmap *ordered_hashmap_free_free_key(OrderedHashmap *h) {
     111                 :          0 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL);
     112                 :            : }
     113                 :            : 
     114                 :      32530 : static inline Hashmap *hashmap_free_free_free(Hashmap *h) {
     115                 :      32530 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free);
     116                 :            : }
     117                 :      62662 : static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) {
     118                 :      62662 :         return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free);
     119                 :            : }
     120                 :            : 
     121                 :            : IteratedCache *iterated_cache_free(IteratedCache *cache);
     122                 :            : int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries);
     123                 :            : 
     124                 :            : HashmapBase *internal_hashmap_copy(HashmapBase *h);
     125                 :          3 : static inline Hashmap *hashmap_copy(Hashmap *h) {
     126                 :          3 :         return (Hashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
     127                 :            : }
     128                 :          3 : static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) {
     129                 :          3 :         return (OrderedHashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
     130                 :            : }
     131                 :            : 
     132                 :            : int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
     133                 :            : int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
     134                 :            : #define hashmap_ensure_allocated(h, ops) internal_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
     135                 :            : #define ordered_hashmap_ensure_allocated(h, ops) internal_ordered_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
     136                 :            : 
     137                 :            : IteratedCache *internal_hashmap_iterated_cache_new(HashmapBase *h);
     138                 :          3 : static inline IteratedCache *hashmap_iterated_cache_new(Hashmap *h) {
     139                 :          3 :         return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h));
     140                 :            : }
     141                 :        848 : static inline IteratedCache *ordered_hashmap_iterated_cache_new(OrderedHashmap *h) {
     142                 :        848 :         return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h));
     143                 :            : }
     144                 :            : 
     145                 :            : int hashmap_put(Hashmap *h, const void *key, void *value);
     146                 :    9531171 : static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *value) {
     147                 :    9531171 :         return hashmap_put(PLAIN_HASHMAP(h), key, value);
     148                 :            : }
     149                 :            : 
     150                 :            : int hashmap_put_strdup(Hashmap **h, const char *k, const char *v);
     151                 :            : 
     152                 :            : int hashmap_update(Hashmap *h, const void *key, void *value);
     153                 :          6 : static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
     154                 :          6 :         return hashmap_update(PLAIN_HASHMAP(h), key, value);
     155                 :            : }
     156                 :            : 
     157                 :            : int hashmap_replace(Hashmap *h, const void *key, void *value);
     158                 :     218474 : static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, void *value) {
     159                 :     218474 :         return hashmap_replace(PLAIN_HASHMAP(h), key, value);
     160                 :            : }
     161                 :            : 
     162                 :            : void *internal_hashmap_get(HashmapBase *h, const void *key);
     163                 :    3466810 : static inline void *hashmap_get(Hashmap *h, const void *key) {
     164                 :    3466810 :         return internal_hashmap_get(HASHMAP_BASE(h), key);
     165                 :            : }
     166                 :    3368157 : static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) {
     167                 :    3368157 :         return internal_hashmap_get(HASHMAP_BASE(h), key);
     168                 :            : }
     169                 :            : 
     170                 :            : void *hashmap_get2(Hashmap *h, const void *key, void **rkey);
     171                 :     218237 : static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) {
     172                 :     218237 :         return hashmap_get2(PLAIN_HASHMAP(h), key, rkey);
     173                 :            : }
     174                 :            : 
     175                 :            : bool internal_hashmap_contains(HashmapBase *h, const void *key);
     176                 :    9598500 : static inline bool hashmap_contains(Hashmap *h, const void *key) {
     177                 :    9598500 :         return internal_hashmap_contains(HASHMAP_BASE(h), key);
     178                 :            : }
     179                 :    9584652 : static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) {
     180                 :    9584652 :         return internal_hashmap_contains(HASHMAP_BASE(h), key);
     181                 :            : }
     182                 :            : 
     183                 :            : void *internal_hashmap_remove(HashmapBase *h, const void *key);
     184                 :    3443297 : static inline void *hashmap_remove(Hashmap *h, const void *key) {
     185                 :    3443297 :         return internal_hashmap_remove(HASHMAP_BASE(h), key);
     186                 :            : }
     187                 :    3195091 : static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) {
     188                 :    3195091 :         return internal_hashmap_remove(HASHMAP_BASE(h), key);
     189                 :            : }
     190                 :            : 
     191                 :            : void *hashmap_remove2(Hashmap *h, const void *key, void **rkey);
     192                 :       1321 : static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) {
     193                 :       1321 :         return hashmap_remove2(PLAIN_HASHMAP(h), key, rkey);
     194                 :            : }
     195                 :            : 
     196                 :            : void *internal_hashmap_remove_value(HashmapBase *h, const void *key, void *value);
     197                 :      15892 : static inline void *hashmap_remove_value(Hashmap *h, const void *key, void *value) {
     198                 :      15892 :         return internal_hashmap_remove_value(HASHMAP_BASE(h), key, value);
     199                 :            : }
     200                 :            : 
     201                 :         12 : static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) {
     202                 :         12 :         return hashmap_remove_value(PLAIN_HASHMAP(h), key, value);
     203                 :            : }
     204                 :            : 
     205                 :            : int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value);
     206                 :         12 : static inline int ordered_hashmap_remove_and_put(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
     207                 :         12 :         return hashmap_remove_and_put(PLAIN_HASHMAP(h), old_key, new_key, value);
     208                 :            : }
     209                 :            : 
     210                 :            : int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value);
     211                 :         72 : static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
     212                 :         72 :         return hashmap_remove_and_replace(PLAIN_HASHMAP(h), old_key, new_key, value);
     213                 :            : }
     214                 :            : 
     215                 :            : /* Since merging data from a OrderedHashmap into a Hashmap or vice-versa
     216                 :            :  * should just work, allow this by having looser type-checking here. */
     217                 :            : int internal_hashmap_merge(Hashmap *h, Hashmap *other);
     218                 :            : #define hashmap_merge(h, other) internal_hashmap_merge(PLAIN_HASHMAP(h), PLAIN_HASHMAP(other))
     219                 :            : #define ordered_hashmap_merge(h, other) hashmap_merge(h, other)
     220                 :            : 
     221                 :            : int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add);
     222                 :         12 : static inline int hashmap_reserve(Hashmap *h, unsigned entries_add) {
     223                 :         12 :         return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
     224                 :            : }
     225                 :         12 : static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) {
     226                 :         12 :         return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
     227                 :            : }
     228                 :            : 
     229                 :            : int internal_hashmap_move(HashmapBase *h, HashmapBase *other);
     230                 :            : /* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */
     231                 :          6 : static inline int hashmap_move(Hashmap *h, Hashmap *other) {
     232                 :          6 :         return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
     233                 :            : }
     234                 :          6 : static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) {
     235                 :          6 :         return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
     236                 :            : }
     237                 :            : 
     238                 :            : int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key);
     239                 :         15 : static inline int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) {
     240                 :         15 :         return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
     241                 :            : }
     242                 :        311 : static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) {
     243                 :        311 :         return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
     244                 :            : }
     245                 :            : 
     246                 :            : unsigned internal_hashmap_size(HashmapBase *h) _pure_;
     247                 :    3238232 : static inline unsigned hashmap_size(Hashmap *h) {
     248                 :    3238232 :         return internal_hashmap_size(HASHMAP_BASE(h));
     249                 :            : }
     250                 :    3234844 : static inline unsigned ordered_hashmap_size(OrderedHashmap *h) {
     251                 :    3234844 :         return internal_hashmap_size(HASHMAP_BASE(h));
     252                 :            : }
     253                 :            : 
     254                 :    3225229 : static inline bool hashmap_isempty(Hashmap *h) {
     255                 :    3225229 :         return hashmap_size(h) == 0;
     256                 :            : }
     257                 :    3195109 : static inline bool ordered_hashmap_isempty(OrderedHashmap *h) {
     258                 :    3195109 :         return ordered_hashmap_size(h) == 0;
     259                 :            : }
     260                 :            : 
     261                 :            : unsigned internal_hashmap_buckets(HashmapBase *h) _pure_;
     262                 :         30 : static inline unsigned hashmap_buckets(Hashmap *h) {
     263                 :         30 :         return internal_hashmap_buckets(HASHMAP_BASE(h));
     264                 :            : }
     265                 :         30 : static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) {
     266                 :         30 :         return internal_hashmap_buckets(HASHMAP_BASE(h));
     267                 :            : }
     268                 :            : 
     269                 :            : bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key);
     270                 :    1988284 : static inline bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) {
     271                 :    1988284 :         return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
     272                 :            : }
     273                 :      74128 : static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) {
     274                 :      74128 :         return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
     275                 :            : }
     276                 :            : 
     277                 :            : void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
     278                 :        107 : static inline void hashmap_clear(Hashmap *h) {
     279                 :        107 :         internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL);
     280                 :        107 : }
     281                 :         76 : static inline void ordered_hashmap_clear(OrderedHashmap *h) {
     282                 :         76 :         internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL);
     283                 :         76 : }
     284                 :            : 
     285                 :          6 : static inline void hashmap_clear_free(Hashmap *h) {
     286                 :          6 :         internal_hashmap_clear(HASHMAP_BASE(h), NULL, free);
     287                 :          6 : }
     288                 :          6 : static inline void ordered_hashmap_clear_free(OrderedHashmap *h) {
     289                 :          6 :         internal_hashmap_clear(HASHMAP_BASE(h), NULL, free);
     290                 :          6 : }
     291                 :            : 
     292                 :            : static inline void hashmap_clear_free_key(Hashmap *h) {
     293                 :            :         internal_hashmap_clear(HASHMAP_BASE(h), free, NULL);
     294                 :            : }
     295                 :          0 : static inline void ordered_hashmap_clear_free_key(OrderedHashmap *h) {
     296                 :          0 :         internal_hashmap_clear(HASHMAP_BASE(h), free, NULL);
     297                 :          0 : }
     298                 :            : 
     299                 :          6 : static inline void hashmap_clear_free_free(Hashmap *h) {
     300                 :          6 :         internal_hashmap_clear(HASHMAP_BASE(h), free, free);
     301                 :          6 : }
     302                 :          6 : static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) {
     303                 :          6 :         internal_hashmap_clear(HASHMAP_BASE(h), free, free);
     304                 :          6 : }
     305                 :            : 
     306                 :            : /*
     307                 :            :  * Note about all *_first*() functions
     308                 :            :  *
     309                 :            :  * For plain Hashmaps and Sets the order of entries is undefined.
     310                 :            :  * The functions find whatever entry is first in the implementation
     311                 :            :  * internal order.
     312                 :            :  *
     313                 :            :  * Only for OrderedHashmaps the order is well defined and finding
     314                 :            :  * the first entry is O(1).
     315                 :            :  */
     316                 :            : 
     317                 :            : void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key);
     318                 :        292 : static inline void *hashmap_steal_first_key_and_value(Hashmap *h, void **ret) {
     319                 :        292 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
     320                 :            : }
     321                 :            : static inline void *ordered_hashmap_steal_first_key_and_value(OrderedHashmap *h, void **ret) {
     322                 :            :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
     323                 :            : }
     324                 :            : static inline void *hashmap_first_key_and_value(Hashmap *h, void **ret) {
     325                 :            :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
     326                 :            : }
     327                 :            : static inline void *ordered_hashmap_first_key_and_value(OrderedHashmap *h, void **ret) {
     328                 :            :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
     329                 :            : }
     330                 :            : 
     331                 :       3612 : static inline void *hashmap_steal_first(Hashmap *h) {
     332                 :       3612 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
     333                 :            : }
     334                 :      50900 : static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) {
     335                 :      50900 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
     336                 :            : }
     337                 :      12050 : static inline void *hashmap_first(Hashmap *h) {
     338                 :      12050 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
     339                 :            : }
     340                 :        476 : static inline void *ordered_hashmap_first(OrderedHashmap *h) {
     341                 :        476 :         return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
     342                 :            : }
     343                 :            : 
     344                 :    6404614 : static inline void *internal_hashmap_first_key(HashmapBase *h, bool remove) {
     345                 :    6404614 :         void *key = NULL;
     346                 :            : 
     347                 :    6404614 :         (void) internal_hashmap_first_key_and_value(HASHMAP_BASE(h), remove, &key);
     348                 :    6404614 :         return key;
     349                 :            : }
     350                 :      14774 : static inline void *hashmap_steal_first_key(Hashmap *h) {
     351                 :      14774 :         return internal_hashmap_first_key(HASHMAP_BASE(h), true);
     352                 :            : }
     353                 :          6 : static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) {
     354                 :          6 :         return internal_hashmap_first_key(HASHMAP_BASE(h), true);
     355                 :            : }
     356                 :    3194942 : static inline void *hashmap_first_key(Hashmap *h) {
     357                 :    3194942 :         return internal_hashmap_first_key(HASHMAP_BASE(h), false);
     358                 :            : }
     359                 :    3194892 : static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
     360                 :    3194892 :         return internal_hashmap_first_key(HASHMAP_BASE(h), false);
     361                 :            : }
     362                 :            : 
     363                 :            : #define hashmap_clear_with_destructor(_s, _f)                   \
     364                 :            :         ({                                                      \
     365                 :            :                 void *_item;                                    \
     366                 :            :                 while ((_item = hashmap_steal_first(_s)))       \
     367                 :            :                         _f(_item);                              \
     368                 :            :         })
     369                 :            : #define hashmap_free_with_destructor(_s, _f)                    \
     370                 :            :         ({                                                      \
     371                 :            :                 hashmap_clear_with_destructor(_s, _f);          \
     372                 :            :                 hashmap_free(_s);                               \
     373                 :            :         })
     374                 :            : #define ordered_hashmap_clear_with_destructor(_s, _f)                   \
     375                 :            :         ({                                                              \
     376                 :            :                 void *_item;                                            \
     377                 :            :                 while ((_item = ordered_hashmap_steal_first(_s)))       \
     378                 :            :                         _f(_item);                                      \
     379                 :            :         })
     380                 :            : #define ordered_hashmap_free_with_destructor(_s, _f)                    \
     381                 :            :         ({                                                              \
     382                 :            :                 ordered_hashmap_clear_with_destructor(_s, _f);          \
     383                 :            :                 ordered_hashmap_free(_s);                               \
     384                 :            :         })
     385                 :            : 
     386                 :            : /* no hashmap_next */
     387                 :            : void *ordered_hashmap_next(OrderedHashmap *h, const void *key);
     388                 :            : 
     389                 :            : char **internal_hashmap_get_strv(HashmapBase *h);
     390                 :       3827 : static inline char **hashmap_get_strv(Hashmap *h) {
     391                 :       3827 :         return internal_hashmap_get_strv(HASHMAP_BASE(h));
     392                 :            : }
     393                 :          3 : static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
     394                 :          3 :         return internal_hashmap_get_strv(HASHMAP_BASE(h));
     395                 :            : }
     396                 :            : 
     397                 :            : /*
     398                 :            :  * Hashmaps are iterated in unpredictable order.
     399                 :            :  * OrderedHashmaps are an exception to this. They are iterated in the order
     400                 :            :  * the entries were inserted.
     401                 :            :  * It is safe to remove the current entry.
     402                 :            :  */
     403                 :            : #define HASHMAP_FOREACH(e, h, i) \
     404                 :            :         for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), NULL); )
     405                 :            : 
     406                 :            : #define ORDERED_HASHMAP_FOREACH(e, h, i) \
     407                 :            :         for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), NULL); )
     408                 :            : 
     409                 :            : #define HASHMAP_FOREACH_KEY(e, k, h, i) \
     410                 :            :         for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
     411                 :            : 
     412                 :            : #define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \
     413                 :            :         for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
     414                 :            : 
     415         [ +  + ]:      21347 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free);
     416         [ +  - ]:          4 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free);
     417         [ #  # ]:          0 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_key);
     418         [ +  - ]:         35 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free);
     419         [ +  + ]:        826 : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free);
     420                 :            : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free);
     421                 :            : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_key);
     422         [ +  - ]:          3 : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free);
     423                 :            : 
     424                 :            : #define _cleanup_hashmap_free_ _cleanup_(hashmap_freep)
     425                 :            : #define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep)
     426                 :            : #define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep)
     427                 :            : #define _cleanup_ordered_hashmap_free_ _cleanup_(ordered_hashmap_freep)
     428                 :            : #define _cleanup_ordered_hashmap_free_free_ _cleanup_(ordered_hashmap_free_freep)
     429                 :            : #define _cleanup_ordered_hashmap_free_free_free_ _cleanup_(ordered_hashmap_free_free_freep)
     430                 :            : 
     431                 :            : DEFINE_TRIVIAL_CLEANUP_FUNC(IteratedCache*, iterated_cache_free);
     432                 :            : 
     433                 :            : #define _cleanup_iterated_cache_free_ _cleanup_(iterated_cache_freep)

Generated by: LCOV version 1.14