LCOV - code coverage report
Current view: top level - basic - hashmap.h (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 104 104 100.0 %
Date: 2015-07-29 18:47:03 Functions: 53 53 100.0 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : #pragma once
       4             : 
       5             : /***
       6             :   This file is part of systemd.
       7             : 
       8             :   Copyright 2010 Lennart Poettering
       9             :   Copyright 2014 Michal Schmidt
      10             : 
      11             :   systemd is free software; you can redistribute it and/or modify it
      12             :   under the terms of the GNU Lesser General Public License as published by
      13             :   the Free Software Foundation; either version 2.1 of the License, or
      14             :   (at your option) any later version.
      15             : 
      16             :   systemd is distributed in the hope that it will be useful, but
      17             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      19             :   Lesser General Public License for more details.
      20             : 
      21             :   You should have received a copy of the GNU Lesser General Public License
      22             :   along with systemd; If not, see <http://www.gnu.org/licenses/>.
      23             : ***/
      24             : 
      25             : #include <stdbool.h>
      26             : 
      27             : #include "macro.h"
      28             : #include "util.h"
      29             : 
      30             : /*
      31             :  * A hash table implementation. As a minor optimization a NULL hashmap object
      32             :  * will be treated as empty hashmap for all read operations. That way it is not
      33             :  * necessary to instantiate an object for each Hashmap use.
      34             :  *
      35             :  * If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap),
      36             :  * the implemention will:
      37             :  * - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py)
      38             :  * - perform extra checks for invalid use of iterators
      39             :  */
      40             : 
      41             : #define HASH_KEY_SIZE 16
      42             : 
      43             : /* The base type for all hashmap and set types. Many functions in the
      44             :  * implementation take (HashmapBase*) parameters and are run-time polymorphic,
      45             :  * though the API is not meant to be polymorphic (do not call functions
      46             :  * internal_*() directly). */
      47             : typedef struct HashmapBase HashmapBase;
      48             : 
      49             : /* Specific hashmap/set types */
      50             : typedef struct Hashmap Hashmap;               /* Maps keys to values */
      51             : typedef struct OrderedHashmap OrderedHashmap; /* Like Hashmap, but also remembers entry insertion order */
      52             : typedef struct Set Set;                       /* Stores just keys */
      53             : 
      54             : /* Ideally the Iterator would be an opaque struct, but it is instantiated
      55             :  * by hashmap users, so the definition has to be here. Do not use its fields
      56             :  * directly. */
      57             : typedef struct {
      58             :         unsigned idx;         /* index of an entry to be iterated next */
      59             :         const void *next_key; /* expected value of that entry's key pointer */
      60             : #ifdef ENABLE_DEBUG_HASHMAP
      61             :         unsigned put_count;   /* hashmap's put_count recorded at start of iteration */
      62             :         unsigned rem_count;   /* hashmap's rem_count in previous iteration */
      63             :         unsigned prev_idx;    /* idx in previous iteration */
      64             : #endif
      65             : } Iterator;
      66             : 
      67             : #define _IDX_ITERATOR_FIRST (UINT_MAX - 1)
      68             : #define ITERATOR_FIRST ((Iterator) { .idx = _IDX_ITERATOR_FIRST, .next_key = NULL })
      69             : 
      70             : typedef unsigned long (*hash_func_t)(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]);
      71             : typedef int (*compare_func_t)(const void *a, const void *b);
      72             : 
      73             : struct hash_ops {
      74             :         hash_func_t hash;
      75             :         compare_func_t compare;
      76             : };
      77             : 
      78             : unsigned long string_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_;
      79             : int string_compare_func(const void *a, const void *b) _pure_;
      80             : extern const struct hash_ops string_hash_ops;
      81             : 
      82             : /* This will compare the passed pointers directly, and will not
      83             :  * dereference them. This is hence not useful for strings or
      84             :  * suchlike. */
      85             : unsigned long trivial_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_;
      86             : int trivial_compare_func(const void *a, const void *b) _const_;
      87             : extern const struct hash_ops trivial_hash_ops;
      88             : 
      89             : /* 32bit values we can always just embedd in the pointer itself, but
      90             :  * in order to support 32bit archs we need store 64bit values
      91             :  * indirectly, since they don't fit in a pointer. */
      92             : unsigned long uint64_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_;
      93             : int uint64_compare_func(const void *a, const void *b) _pure_;
      94             : extern const struct hash_ops uint64_hash_ops;
      95             : 
      96             : /* On some archs dev_t is 32bit, and on others 64bit. And sometimes
      97             :  * it's 64bit on 32bit archs, and sometimes 32bit on 64bit archs. Yuck! */
      98             : #if SIZEOF_DEV_T != 8
      99             : unsigned long devt_hash_func(const void *p, const uint8_t hash_key[HASH_KEY_SIZE]) _pure_;
     100             : int devt_compare_func(const void *a, const void *b) _pure_;
     101             : extern const struct hash_ops devt_hash_ops = {
     102             :         .hash = devt_hash_func,
     103             :         .compare = devt_compare_func
     104             : };
     105             : #else
     106             : #define devt_hash_func uint64_hash_func
     107             : #define devt_compare_func uint64_compare_func
     108             : #define devt_hash_ops uint64_hash_ops
     109             : #endif
     110             : 
     111             : /* Macros for type checking */
     112             : #define PTR_COMPATIBLE_WITH_HASHMAP_BASE(h) \
     113             :         (__builtin_types_compatible_p(typeof(h), HashmapBase*) || \
     114             :          __builtin_types_compatible_p(typeof(h), Hashmap*) || \
     115             :          __builtin_types_compatible_p(typeof(h), OrderedHashmap*) || \
     116             :          __builtin_types_compatible_p(typeof(h), Set*))
     117             : 
     118             : #define PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h) \
     119             :         (__builtin_types_compatible_p(typeof(h), Hashmap*) || \
     120             :          __builtin_types_compatible_p(typeof(h), OrderedHashmap*)) \
     121             : 
     122             : #define HASHMAP_BASE(h) \
     123             :         __builtin_choose_expr(PTR_COMPATIBLE_WITH_HASHMAP_BASE(h), \
     124             :                 (HashmapBase*)(h), \
     125             :                 (void)0)
     126             : 
     127             : #define PLAIN_HASHMAP(h) \
     128             :         __builtin_choose_expr(PTR_COMPATIBLE_WITH_PLAIN_HASHMAP(h), \
     129             :                 (Hashmap*)(h), \
     130             :                 (void)0)
     131             : 
     132             : #ifdef ENABLE_DEBUG_HASHMAP
     133             : # define HASHMAP_DEBUG_PARAMS , const char *func, const char *file, int line
     134             : # define HASHMAP_DEBUG_SRC_ARGS   , __func__, __FILE__, __LINE__
     135             : # define HASHMAP_DEBUG_PASS_ARGS   , func, file, line
     136             : #else
     137             : # define HASHMAP_DEBUG_PARAMS
     138             : # define HASHMAP_DEBUG_SRC_ARGS
     139             : # define HASHMAP_DEBUG_PASS_ARGS
     140             : #endif
     141             : 
     142             : Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
     143             : OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
     144             : #define hashmap_new(ops) internal_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS)
     145             : #define ordered_hashmap_new(ops) internal_ordered_hashmap_new(ops  HASHMAP_DEBUG_SRC_ARGS)
     146             : 
     147             : HashmapBase *internal_hashmap_free(HashmapBase *h);
     148        2045 : static inline Hashmap *hashmap_free(Hashmap *h) {
     149        2045 :         return (void*)internal_hashmap_free(HASHMAP_BASE(h));
     150             : }
     151         507 : static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) {
     152         507 :         return (void*)internal_hashmap_free(HASHMAP_BASE(h));
     153             : }
     154             : 
     155             : HashmapBase *internal_hashmap_free_free(HashmapBase *h);
     156         213 : static inline Hashmap *hashmap_free_free(Hashmap *h) {
     157         213 :         return (void*)internal_hashmap_free_free(HASHMAP_BASE(h));
     158             : }
     159        1470 : static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) {
     160        1470 :         return (void*)internal_hashmap_free_free(HASHMAP_BASE(h));
     161             : }
     162             : 
     163             : Hashmap *hashmap_free_free_free(Hashmap *h);
     164         878 : static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) {
     165         878 :         return (void*)hashmap_free_free_free(PLAIN_HASHMAP(h));
     166             : }
     167             : 
     168             : HashmapBase *internal_hashmap_copy(HashmapBase *h);
     169           1 : static inline Hashmap *hashmap_copy(Hashmap *h) {
     170           1 :         return (Hashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
     171             : }
     172           1 : static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) {
     173           1 :         return (OrderedHashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
     174             : }
     175             : 
     176             : int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
     177             : int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops  HASHMAP_DEBUG_PARAMS);
     178             : #define hashmap_ensure_allocated(h, ops) internal_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
     179             : #define ordered_hashmap_ensure_allocated(h, ops) internal_ordered_hashmap_ensure_allocated(h, ops  HASHMAP_DEBUG_SRC_ARGS)
     180             : 
     181             : int hashmap_put(Hashmap *h, const void *key, void *value);
     182     1051649 : static inline int ordered_hashmap_put(OrderedHashmap *h, const void *key, void *value) {
     183     1051649 :         return hashmap_put(PLAIN_HASHMAP(h), key, value);
     184             : }
     185             : 
     186             : int hashmap_update(Hashmap *h, const void *key, void *value);
     187           2 : static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
     188           2 :         return hashmap_update(PLAIN_HASHMAP(h), key, value);
     189             : }
     190             : 
     191             : int hashmap_replace(Hashmap *h, const void *key, void *value);
     192        5378 : static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, void *value) {
     193        5378 :         return hashmap_replace(PLAIN_HASHMAP(h), key, value);
     194             : }
     195             : 
     196             : void *internal_hashmap_get(HashmapBase *h, const void *key);
     197     1184951 : static inline void *hashmap_get(Hashmap *h, const void *key) {
     198     1184951 :         return internal_hashmap_get(HASHMAP_BASE(h), key);
     199             : }
     200     1076206 : static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) {
     201     1076206 :         return internal_hashmap_get(HASHMAP_BASE(h), key);
     202             : }
     203             : 
     204             : void *hashmap_get2(Hashmap *h, const void *key, void **rkey);
     205        5379 : static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, void **rkey) {
     206        5379 :         return hashmap_get2(PLAIN_HASHMAP(h), key, rkey);
     207             : }
     208             : 
     209             : bool internal_hashmap_contains(HashmapBase *h, const void *key);
     210     3153691 : static inline bool hashmap_contains(Hashmap *h, const void *key) {
     211     3153691 :         return internal_hashmap_contains(HASHMAP_BASE(h), key);
     212             : }
     213     3151874 : static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) {
     214     3151874 :         return internal_hashmap_contains(HASHMAP_BASE(h), key);
     215             : }
     216             : 
     217             : void *internal_hashmap_remove(HashmapBase *h, const void *key);
     218     1053844 : static inline void *hashmap_remove(Hashmap *h, const void *key) {
     219     1053844 :         return internal_hashmap_remove(HASHMAP_BASE(h), key);
     220             : }
     221     1050631 : static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) {
     222     1050631 :         return internal_hashmap_remove(HASHMAP_BASE(h), key);
     223             : }
     224             : 
     225             : void *hashmap_remove2(Hashmap *h, const void *key, void **rkey);
     226          23 : static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key, void **rkey) {
     227          23 :         return hashmap_remove2(PLAIN_HASHMAP(h), key, rkey);
     228             : }
     229             : 
     230             : void *hashmap_remove_value(Hashmap *h, const void *key, void *value);
     231           4 : static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) {
     232           4 :         return hashmap_remove_value(PLAIN_HASHMAP(h), key, value);
     233             : }
     234             : 
     235             : int hashmap_remove_and_put(Hashmap *h, const void *old_key, const void *new_key, void *value);
     236           4 : static inline int ordered_hashmap_remove_and_put(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
     237           4 :         return hashmap_remove_and_put(PLAIN_HASHMAP(h), old_key, new_key, value);
     238             : }
     239             : 
     240             : int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_key, void *value);
     241          24 : static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const void *old_key, const void *new_key, void *value) {
     242          24 :         return hashmap_remove_and_replace(PLAIN_HASHMAP(h), old_key, new_key, value);
     243             : }
     244             : 
     245             : /* Since merging data from a OrderedHashmap into a Hashmap or vice-versa
     246             :  * should just work, allow this by having looser type-checking here. */
     247             : int internal_hashmap_merge(Hashmap *h, Hashmap *other);
     248             : #define hashmap_merge(h, other) internal_hashmap_merge(PLAIN_HASHMAP(h), PLAIN_HASHMAP(other))
     249             : #define ordered_hashmap_merge(h, other) hashmap_merge(h, other)
     250             : 
     251             : int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add);
     252           4 : static inline int hashmap_reserve(Hashmap *h, unsigned entries_add) {
     253           4 :         return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
     254             : }
     255           4 : static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) {
     256           4 :         return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
     257             : }
     258             : 
     259             : int internal_hashmap_move(HashmapBase *h, HashmapBase *other);
     260             : /* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */
     261           2 : static inline int hashmap_move(Hashmap *h, Hashmap *other) {
     262           2 :         return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
     263             : }
     264           2 : static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) {
     265           2 :         return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
     266             : }
     267             : 
     268             : int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key);
     269           5 : static inline int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) {
     270           5 :         return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
     271             : }
     272           5 : static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) {
     273           5 :         return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
     274             : }
     275             : 
     276             : unsigned internal_hashmap_size(HashmapBase *h) _pure_;
     277     1067472 : static inline unsigned hashmap_size(Hashmap *h) {
     278     1067472 :         return internal_hashmap_size(HASHMAP_BASE(h));
     279             : }
     280     1051995 : static inline unsigned ordered_hashmap_size(OrderedHashmap *h) {
     281     1051995 :         return internal_hashmap_size(HASHMAP_BASE(h));
     282             : }
     283             : 
     284     1066656 : static inline bool hashmap_isempty(Hashmap *h) {
     285     1066656 :         return hashmap_size(h) == 0;
     286             : }
     287     1050632 : static inline bool ordered_hashmap_isempty(OrderedHashmap *h) {
     288     1050632 :         return ordered_hashmap_size(h) == 0;
     289             : }
     290             : 
     291             : unsigned internal_hashmap_buckets(HashmapBase *h) _pure_;
     292          10 : static inline unsigned hashmap_buckets(Hashmap *h) {
     293          10 :         return internal_hashmap_buckets(HASHMAP_BASE(h));
     294             : }
     295          10 : static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) {
     296          10 :         return internal_hashmap_buckets(HASHMAP_BASE(h));
     297             : }
     298             : 
     299             : bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key);
     300        7599 : static inline bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) {
     301        7599 :         return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
     302             : }
     303       63074 : static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) {
     304       63074 :         return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
     305             : }
     306             : 
     307             : void internal_hashmap_clear(HashmapBase *h);
     308          20 : static inline void hashmap_clear(Hashmap *h) {
     309          20 :         internal_hashmap_clear(HASHMAP_BASE(h));
     310          20 : }
     311          20 : static inline void ordered_hashmap_clear(OrderedHashmap *h) {
     312          20 :         internal_hashmap_clear(HASHMAP_BASE(h));
     313          20 : }
     314             : 
     315             : void internal_hashmap_clear_free(HashmapBase *h);
     316             : static inline void hashmap_clear_free(Hashmap *h) {
     317             :         internal_hashmap_clear_free(HASHMAP_BASE(h));
     318             : }
     319             : static inline void ordered_hashmap_clear_free(OrderedHashmap *h) {
     320             :         internal_hashmap_clear_free(HASHMAP_BASE(h));
     321             : }
     322             : 
     323             : void hashmap_clear_free_free(Hashmap *h);
     324           1 : static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) {
     325           1 :         hashmap_clear_free_free(PLAIN_HASHMAP(h));
     326           1 : }
     327             : 
     328             : /*
     329             :  * Note about all *_first*() functions
     330             :  *
     331             :  * For plain Hashmaps and Sets the order of entries is undefined.
     332             :  * The functions find whatever entry is first in the implementation
     333             :  * internal order.
     334             :  *
     335             :  * Only for OrderedHashmaps the order is well defined and finding
     336             :  * the first entry is O(1).
     337             :  */
     338             : 
     339             : void *internal_hashmap_steal_first(HashmapBase *h);
     340         472 : static inline void *hashmap_steal_first(Hashmap *h) {
     341         472 :         return internal_hashmap_steal_first(HASHMAP_BASE(h));
     342             : }
     343        1310 : static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) {
     344        1310 :         return internal_hashmap_steal_first(HASHMAP_BASE(h));
     345             : }
     346             : 
     347             : void *internal_hashmap_steal_first_key(HashmapBase *h);
     348           2 : static inline void *hashmap_steal_first_key(Hashmap *h) {
     349           2 :         return internal_hashmap_steal_first_key(HASHMAP_BASE(h));
     350             : }
     351           2 : static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) {
     352           2 :         return internal_hashmap_steal_first_key(HASHMAP_BASE(h));
     353             : }
     354             : 
     355             : void *internal_hashmap_first_key(HashmapBase *h) _pure_;
     356     1050626 : static inline void *hashmap_first_key(Hashmap *h) {
     357     1050626 :         return internal_hashmap_first_key(HASHMAP_BASE(h));
     358             : }
     359     1050628 : static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
     360     1050628 :         return internal_hashmap_first_key(HASHMAP_BASE(h));
     361             : }
     362             : 
     363             : void *internal_hashmap_first(HashmapBase *h) _pure_;
     364        1807 : static inline void *hashmap_first(Hashmap *h) {
     365        1807 :         return internal_hashmap_first(HASHMAP_BASE(h));
     366             : }
     367         281 : static inline void *ordered_hashmap_first(OrderedHashmap *h) {
     368         281 :         return internal_hashmap_first(HASHMAP_BASE(h));
     369             : }
     370             : 
     371             : /* no hashmap_next */
     372             : void *ordered_hashmap_next(OrderedHashmap *h, const void *key);
     373             : 
     374             : char **internal_hashmap_get_strv(HashmapBase *h);
     375          11 : static inline char **hashmap_get_strv(Hashmap *h) {
     376          11 :         return internal_hashmap_get_strv(HASHMAP_BASE(h));
     377             : }
     378           1 : static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
     379           1 :         return internal_hashmap_get_strv(HASHMAP_BASE(h));
     380             : }
     381             : 
     382             : /*
     383             :  * Hashmaps are iterated in unpredictable order.
     384             :  * OrderedHashmaps are an exception to this. They are iterated in the order
     385             :  * the entries were inserted.
     386             :  * It is safe to remove the current entry.
     387             :  */
     388             : #define HASHMAP_FOREACH(e, h, i) \
     389             :         for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), NULL); )
     390             : 
     391             : #define ORDERED_HASHMAP_FOREACH(e, h, i) \
     392             :         for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), NULL); )
     393             : 
     394             : #define HASHMAP_FOREACH_KEY(e, k, h, i) \
     395             :         for ((i) = ITERATOR_FIRST; hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
     396             : 
     397             : #define ORDERED_HASHMAP_FOREACH_KEY(e, k, h, i) \
     398             :         for ((i) = ITERATOR_FIRST; ordered_hashmap_iterate((h), &(i), (void**)&(e), (const void**) &(k)); )
     399             : 
     400          20 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free);
     401           3 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free);
     402           1 : DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free);
     403          11 : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free);
     404             : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free);
     405           1 : DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedHashmap*, ordered_hashmap_free_free_free);
     406             : 
     407             : #define _cleanup_hashmap_free_ _cleanup_(hashmap_freep)
     408             : #define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep)
     409             : #define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep)
     410             : #define _cleanup_ordered_hashmap_free_ _cleanup_(ordered_hashmap_freep)
     411             : #define _cleanup_ordered_hashmap_free_free_ _cleanup_(ordered_hashmap_free_freep)
     412             : #define _cleanup_ordered_hashmap_free_free_free_ _cleanup_(ordered_hashmap_free_free_freep)

Generated by: LCOV version 1.11