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