diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:57:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 02:57:58 +0000 |
commit | be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97 (patch) | |
tree | 9754ff1ca740f6346cf8483ec915d4054bc5da2d /fluent-bit/lib/librdkafka-2.1.0/src/rdmap.h | |
parent | Initial commit. (diff) | |
download | netdata-upstream.tar.xz netdata-upstream.zip |
Adding upstream version 1.44.3.upstream/1.44.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/lib/librdkafka-2.1.0/src/rdmap.h')
-rw-r--r-- | fluent-bit/lib/librdkafka-2.1.0/src/rdmap.h | 487 |
1 files changed, 487 insertions, 0 deletions
diff --git a/fluent-bit/lib/librdkafka-2.1.0/src/rdmap.h b/fluent-bit/lib/librdkafka-2.1.0/src/rdmap.h new file mode 100644 index 00000000..a79dcda0 --- /dev/null +++ b/fluent-bit/lib/librdkafka-2.1.0/src/rdmap.h @@ -0,0 +1,487 @@ +/* + * librdkafka - The Apache Kafka C/C++ library + * + * Copyright (c) 2020 Magnus Edenhill + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _RDMAP_H_ +#define _RDMAP_H_ + +/** + * @name Hash maps. + * + * Memory of key and value are allocated by the user but owned by the hash map + * until elements are deleted or overwritten. + * + * The lower-case API provides a generic typeless (void *) hash map while + * the upper-case API provides a strictly typed hash map implemented as macros + * on top of the generic API. + * + * See rd_map_init(), et.al, for the generic API and RD_MAP_INITIALIZER() + * for the typed API. + * + * @remark Not thread safe. + */ + + +/** + * @struct Map element. This is the internal representation + * of the element and exposed to the user for iterating over the hash. + */ +typedef struct rd_map_elem_s { + LIST_ENTRY(rd_map_elem_s) hlink; /**< Hash bucket link */ + LIST_ENTRY(rd_map_elem_s) link; /**< Iterator link */ + unsigned int hash; /**< Key hash value */ + const void *key; /**< Key (memory owned by map) */ + const void *value; /**< Value (memory owned by map) */ +} rd_map_elem_t; + + +/** + * @struct Hash buckets (internal use). + */ +struct rd_map_buckets { + LIST_HEAD(, rd_map_elem_s) * p; /**< Hash buckets array */ + int cnt; /**< Bucket count */ +}; + + +/** + * @struct Hash map. + */ +typedef struct rd_map_s { + struct rd_map_buckets rmap_buckets; /**< Hash buckets */ + int rmap_cnt; /**< Element count */ + + LIST_HEAD(, rd_map_elem_s) + rmap_iter; /**< Element list for iterating + * over all elements. */ + + int (*rmap_cmp)(const void *a, const void *b); /**< Key comparator */ + unsigned int (*rmap_hash)(const void *key); /**< Key hash function */ + void (*rmap_destroy_key)(void *key); /**< Optional key free */ + void (*rmap_destroy_value)(void *value); /**< Optional value free */ + + void *rmap_opaque; +} rd_map_t; + + + +/** + * @brief Set/overwrite value in map. + * + * If an existing entry with the same key already exists its key and value + * will be freed with the destroy_key and destroy_value functions + * passed to rd_map_init(). + * + * The map assumes memory ownership of both the \p key and \p value and will + * use the destroy_key and destroy_value functions (if set) to free + * the key and value memory when the map is destroyed or element removed. + * + * @returns the map element. + */ +rd_map_elem_t *rd_map_set(rd_map_t *rmap, void *key, void *value); + + +/** + * @brief Look up \p key in the map and return its value, or NULL + * if \p key was not found. + * + * The returned memory is still owned by the map. + */ +void *rd_map_get(const rd_map_t *rmap, const void *key); + + +/** + * @brief Delete \p key from the map, if it exists. + * + * The destroy_key and destroy_value functions (if set) will be used + * to free the key and value memory. + */ +void rd_map_delete(rd_map_t *rmap, const void *key); + + +/** Key or Value Copy function signature. */ +typedef void *(rd_map_copy_t)(const void *key_or_value); + + +/** + * @brief Copy all elements from \p src to \p dst. + * \p dst must be initialized and compatible with \p src. + * + * @param dst Destination map to copy to. + * @param src Source map to copy from. + * @param key_copy Key copy callback. If NULL the \p dst key will just + * reference the \p src key. + * @param value_copy Value copy callback. If NULL the \p dst value will just + * reference the \p src value. + */ +void rd_map_copy(rd_map_t *dst, + const rd_map_t *src, + rd_map_copy_t *key_copy, + rd_map_copy_t *value_copy); + + +/** + * @returns the current number of elements in the map. + */ +size_t rd_map_cnt(const rd_map_t *rmap); + +/** + * @returns true if map is empty, else false. + */ +rd_bool_t rd_map_is_empty(const rd_map_t *rmap); + + +/** + * @brief Iterate over all elements in the map. + * + * @warning The map MUST NOT be modified during the loop. + * + * @remark This is part of the untyped generic API. + */ +#define RD_MAP_FOREACH_ELEM(ELEM, RMAP) \ + for (rd_map_iter_begin((RMAP), &(ELEM)); rd_map_iter(&(ELEM)); \ + rd_map_iter_next(&(ELEM))) + + +/** + * @brief Begin iterating \p rmap, first element is set in \p *elem. + */ +void rd_map_iter_begin(const rd_map_t *rmap, const rd_map_elem_t **elem); + +/** + * @returns 1 if \p *elem is a valid iteration element, else 0. + */ +static RD_INLINE RD_UNUSED int rd_map_iter(const rd_map_elem_t **elem) { + return *elem != NULL; +} + +/** + * @brief Advances the iteration to the next element. + */ +static RD_INLINE RD_UNUSED void rd_map_iter_next(const rd_map_elem_t **elem) { + *elem = LIST_NEXT(*elem, link); +} + + +/** + * @brief Initialize a map that is expected to hold \p expected_cnt elements. + * + * @param expected_cnt Expected number of elements in the map, + * this is used to select a suitable bucket count. + * Passing a value of 0 will set the bucket count + * to a reasonable default. + * @param cmp Key comparator that must return 0 if the two keys match. + * @param hash Key hashing function that is used to map a key to a bucket. + * It must return an integer hash >= 0 of the key. + * @param destroy_key (Optional) When an element is deleted or overwritten + * this function will be used to free the key memory. + * @param destroy_value (Optional) When an element is deleted or overwritten + * this function will be used to free the value memory. + * + * Destroy the map with rd_map_destroy() + * + * @remarks The map is not thread-safe. + */ +void rd_map_init(rd_map_t *rmap, + size_t expected_cnt, + int (*cmp)(const void *a, const void *b), + unsigned int (*hash)(const void *key), + void (*destroy_key)(void *key), + void (*destroy_value)(void *value)); + + +/** + * @brief Internal use + */ +struct rd_map_buckets rd_map_alloc_buckets(size_t expected_cnt); + + +/** + * @brief Empty the map and free all elements. + */ +void rd_map_clear(rd_map_t *rmap); + + +/** + * @brief Free all elements in the map and free all memory associated + * with the map, but not the rd_map_t itself. + * + * The map is unusable after this call but can be re-initialized using + * rd_map_init(). + * + * @sa rd_map_clear() + */ +void rd_map_destroy(rd_map_t *rmap); + + +/** + * @brief String comparator for (const char *) keys. + */ +int rd_map_str_cmp(const void *a, const void *b); + + +/** + * @brief String hash function (djb2) for (const char *) keys. + */ +unsigned int rd_map_str_hash(const void *a); + + + +/** + * @name Typed hash maps. + * + * Typed hash maps provides a type-safe layer on top of the standard hash maps. + */ + +/** + * @brief Define a typed map type which can later be used with + * RD_MAP_INITIALIZER() and typed RD_MAP_*() API. + */ +#define RD_MAP_TYPE(KEY_TYPE, VALUE_TYPE) \ + struct { \ + rd_map_t rmap; \ + KEY_TYPE key; \ + VALUE_TYPE value; \ + const rd_map_elem_t *elem; \ + } + +/** + * @brief Initialize a typed hash map. The left hand side variable must be + * a typed hash map defined by RD_MAP_TYPE(). + * + * The typed hash map is a macro layer on top of the rd_map_t implementation + * that provides type safety. + * The methods are the same as the underlying implementation but in all caps + * (to indicate their macro use), e.g., RD_MAP_SET() is the typed version + * of rd_map_set(). + * + * @param EXPECTED_CNT Expected number of elements in hash. + * @param KEY_TYPE The type of the hash key. + * @param VALUE_TYPE The type of the hash value. + * @param CMP Comparator function for the key. + * @param HASH Hash function for the key. + * @param DESTROY_KEY Destructor for the key type. + * @param DESTROY_VALUE Destructor for the value type. + * + * @sa rd_map_init() + */ +#define RD_MAP_INITIALIZER(EXPECTED_CNT, CMP, HASH, DESTROY_KEY, \ + DESTROY_VALUE) \ + { \ + .rmap = { \ + .rmap_buckets = rd_map_alloc_buckets(EXPECTED_CNT), \ + .rmap_cmp = CMP, \ + .rmap_hash = HASH, \ + .rmap_destroy_key = DESTROY_KEY, \ + .rmap_destroy_value = DESTROY_VALUE \ + } \ + } + + +/** + * @brief Initialize a locally-defined typed hash map. + * This hash map can only be used in the current scope/function + * as its type is private to this initializement. + * + * @param RMAP Hash map variable name. + * + * For the other parameters, see RD_MAP_INITIALIZER(). + * + * @sa RD_MAP_INITIALIZER() + */ +#define RD_MAP_LOCAL_INITIALIZER(RMAP, EXPECTED_CNT, KEY_TYPE, VALUE_TYPE, \ + CMP, HASH, DESTROY_KEY, DESTROY_VALUE) \ + struct { \ + rd_map_t rmap; \ + KEY_TYPE key; \ + VALUE_TYPE value; \ + const rd_map_elem_t *elem; \ + } RMAP = RD_MAP_INITIALIZER(EXPECTED_CNT, CMP, HASH, DESTROY_KEY, \ + DESTROY_VALUE) + + +/** + * @brief Initialize typed map \p RMAP. + * + * @sa rd_map_init() + */ +#define RD_MAP_INIT(RMAP, EXPECTED_CNT, CMP, HASH, DESTROY_KEY, DESTROY_VALUE) \ + rd_map_init(&(RMAP)->rmap, EXPECTED_CNT, CMP, HASH, DESTROY_KEY, \ + DESTROY_VALUE) + + +/** + * @brief Allocate and initialize a typed map. + */ + + +/** + * @brief Typed hash map: Set key/value in map. + * + * @sa rd_map_set() + */ +#define RD_MAP_SET(RMAP, KEY, VALUE) \ + ((RMAP)->key = KEY, (RMAP)->value = VALUE, \ + rd_map_set(&(RMAP)->rmap, (void *)(RMAP)->key, \ + (void *)(RMAP)->value)) + +/** + * @brief Typed hash map: Get value for key. + * + * @sa rd_map_get() + */ +#define RD_MAP_GET(RMAP, KEY) \ + ((RMAP)->key = (KEY), \ + (RMAP)->value = rd_map_get(&(RMAP)->rmap, (RMAP)->key), \ + (RMAP)->value) + + + +/** + * @brief Get value for key. If key does not exist in map a new + * entry is added using the DEFAULT_CODE. + */ +#define RD_MAP_GET_OR_SET(RMAP, KEY, DEFAULT_CODE) \ + (RD_MAP_GET(RMAP, KEY) \ + ? (RMAP)->value \ + : (RD_MAP_SET(RMAP, (RMAP)->key, DEFAULT_CODE), (RMAP)->value)) + + +/** + * @brief Typed hash map: Delete element by key. + * + * The destroy_key and destroy_value functions (if set) will be used + * to free the key and value memory. + * + * @sa rd_map_delete() + */ +#define RD_MAP_DELETE(RMAP, KEY) \ + ((RMAP)->key = (KEY), rd_map_delete(&(RMAP)->rmap, (RMAP)->key)) + + +/** + * @brief Copy all elements from \p SRC to \p DST. + * \p DST must be initialized and compatible with \p SRC. + * + * @param DST Destination map to copy to. + * @param SRC Source map to copy from. + * @param KEY_COPY Key copy callback. If NULL the \p DST key will just + * reference the \p SRC key. + * @param VALUE_COPY Value copy callback. If NULL the \p DST value will just + * reference the \p SRC value. + */ +#define RD_MAP_COPY(DST, SRC, KEY_COPY, VALUE_COPY) \ + do { \ + if ((DST) != (SRC)) /*implicit type-check*/ \ + rd_map_copy(&(DST)->rmap, &(SRC)->rmap, KEY_COPY, \ + VALUE_COPY); \ + } while (0) + + +/** + * @brief Empty the map and free all elements. + * + * @sa rd_map_clear() + */ +#define RD_MAP_CLEAR(RMAP) rd_map_clear(&(RMAP)->rmap) + + +/** + * @brief Typed hash map: Destroy hash map. + * + * @sa rd_map_destroy() + */ +#define RD_MAP_DESTROY(RMAP) rd_map_destroy(&(RMAP)->rmap) + + +/** + * @brief Typed hash map: Destroy and free the hash map. + * + * @sa rd_map_destroy() + */ +#define RD_MAP_DESTROY_AND_FREE(RMAP) \ + do { \ + rd_map_destroy(&(RMAP)->rmap); \ + rd_free(RMAP); \ + } while (0) + + +/** + * @brief Typed hash map: Iterate over all elements in the map. + * + * @warning The current or previous elements may be removed, but the next + * element after the current one MUST NOT be modified during the loop. + * + * @warning RD_MAP_FOREACH() only supports one simultaneous invocation, + * that is, special care must be taken not to call FOREACH() from + * within a FOREACH() or FOREACH_KEY() loop on the same map. + * This is due to how RMAP->elem is used as the iterator. + * This restriction is unfortunately not enforced at build or run time. + * + * @remark The \p RMAP may not be const. + */ +#define RD_MAP_FOREACH(K, V, RMAP) \ + for (rd_map_iter_begin(&(RMAP)->rmap, &(RMAP)->elem), (K) = NULL, \ + (V) = NULL; \ + rd_map_iter(&(RMAP)->elem) && \ + ((RMAP)->key = (void *)(RMAP)->elem->key, (K) = (RMAP)->key, \ + (RMAP)->value = (void *)(RMAP)->elem->value, (V) = (RMAP)->value, \ + rd_map_iter_next(&(RMAP)->elem), rd_true);) + + +/** + * @brief Typed hash map: Iterate over all keys in the map. + * + * @warning The current or previous elements may be removed, but the next + * element after the current one MUST NOT be modified during the loop. + * + * @warning RD_MAP_FOREACH_KEY() only supports one simultaneous invocation, + * that is, special care must be taken not to call FOREACH_KEY() from + * within a FOREACH() or FOREACH_KEY() loop on the same map. + * This is due to how RMAP->elem is used as the iterator. + * This restriction is unfortunately not enforced at build or run time. + * + * @remark The \p RMAP may not be const. + */ +#define RD_MAP_FOREACH_KEY(K, RMAP) \ + for (rd_map_iter_begin(&(RMAP)->rmap, &(RMAP)->elem), (K) = NULL; \ + rd_map_iter(&(RMAP)->elem) && \ + ((RMAP)->key = (void *)(RMAP)->elem->key, (K) = (RMAP)->key, \ + rd_map_iter_next(&(RMAP)->elem), rd_true);) + + +/** + * @returns the number of elements in the map. + */ +#define RD_MAP_CNT(RMAP) rd_map_cnt(&(RMAP)->rmap) + +/** + * @returns true if map is empty, else false. + */ +#define RD_MAP_IS_EMPTY(RMAP) rd_map_is_empty(&(RMAP)->rmap) + +#endif /* _RDMAP_H_ */ |