#189 declare basic map functions

Wed, 18 May 2022 16:26:32 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 18 May 2022 16:26:32 +0200
changeset 549
d7f0b5a9a985
parent 548
459bca1cdf8d
child 550
89b2a83728b1

#189 declare basic map functions

src/CMakeLists.txt file | annotate | diff | comparison | revisions
src/cx/common.h file | annotate | diff | comparison | revisions
src/cx/hash_map.h file | annotate | diff | comparison | revisions
src/cx/map.h file | annotate | diff | comparison | revisions
src/hash_map.c file | annotate | diff | comparison | revisions
     1.1 --- a/src/CMakeLists.txt	Mon May 16 19:25:19 2022 +0200
     1.2 +++ b/src/CMakeLists.txt	Wed May 18 16:26:32 2022 +0200
     1.3 @@ -5,8 +5,10 @@
     1.4          linked_list.c
     1.5          tree.c
     1.6          buffer.c
     1.7 +        hash_map.c
     1.8  )
     1.9  set(headers
    1.10 +        cx/common.h
    1.11          cx/utils.h
    1.12          cx/allocator.h
    1.13          cx/iterator.h
    1.14 @@ -14,7 +16,9 @@
    1.15          cx/linked_list.h
    1.16          cx/tree.h
    1.17          cx/buffer.h
    1.18 -)
    1.19 +        cx/map.h
    1.20 +        cx/hash_map.h
    1.21 +        )
    1.22  
    1.23  add_library(ucx SHARED ${sources})
    1.24  add_library(ucx_static STATIC ${sources})
     2.1 --- a/src/cx/common.h	Mon May 16 19:25:19 2022 +0200
     2.2 +++ b/src/cx/common.h	Wed May 18 16:26:32 2022 +0200
     2.3 @@ -94,6 +94,25 @@
     2.4  #include <stdbool.h>
     2.5  
     2.6  /**
     2.7 + * Structure that contains a pointer to arbitrary data.
     2.8 + */
     2.9 +struct cx_data_ptr_s {
    2.10 +    /**
    2.11 +     * A pointer to the data.
    2.12 +     */
    2.13 +    unsigned const char *data;
    2.14 +    /**
    2.15 +     * The length of the data.
    2.16 +     */
    2.17 +    size_t len;
    2.18 +};
    2.19 +
    2.20 +/**
    2.21 + * Type for a data pointer with length information.
    2.22 + */
    2.23 +typedef struct cx_data_ptr_s CxDataPtr;
    2.24 +
    2.25 +/**
    2.26   * Function pointer compatible with fwrite-like functions.
    2.27   */
    2.28  typedef size_t (*cx_write_func)(
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/cx/hash_map.h	Wed May 18 16:26:32 2022 +0200
     3.3 @@ -0,0 +1,123 @@
     3.4 +/*
     3.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3.6 + *
     3.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     3.8 + *
     3.9 + * Redistribution and use in source and binary forms, with or without
    3.10 + * modification, are permitted provided that the following conditions are met:
    3.11 + *
    3.12 + *   1. Redistributions of source code must retain the above copyright
    3.13 + *      notice, this list of conditions and the following disclaimer.
    3.14 + *
    3.15 + *   2. Redistributions in binary form must reproduce the above copyright
    3.16 + *      notice, this list of conditions and the following disclaimer in the
    3.17 + *      documentation and/or other materials provided with the distribution.
    3.18 + *
    3.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    3.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    3.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    3.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    3.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    3.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    3.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    3.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    3.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    3.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    3.29 + * POSSIBILITY OF SUCH DAMAGE.
    3.30 + */
    3.31 +/**
    3.32 + * \file map.h
    3.33 + * \brief Interface for map implementations.
    3.34 + * \author Mike Becker
    3.35 + * \author Olaf Wintermann
    3.36 + * \version 3.0
    3.37 + * \copyright 2-Clause BSD License
    3.38 + */
    3.39 +
    3.40 +#ifndef UCX_HASH_MAP_H
    3.41 +#define UCX_HASH_MAP_H
    3.42 +
    3.43 +#include "map.h"
    3.44 +
    3.45 +#ifdef __cplusplus
    3.46 +extern "C" {
    3.47 +#endif
    3.48 +
    3.49 +/** Internal structure for a key within a hash map. */
    3.50 +struct cx_hash_map_key_s {
    3.51 +    /** The key data. */
    3.52 +    CxDataPtr data;
    3.53 +    /** The hash value of the key data. */
    3.54 +    unsigned hash;
    3.55 +};
    3.56 +
    3.57 +/** Internal structure for an element of a hash map. */
    3.58 +struct cx_hash_map_element_s {
    3.59 +    /** The value data. */
    3.60 +    void *data;
    3.61 +
    3.62 +    /** A pointer to the next element in the current bucket. */
    3.63 +    struct cx_hash_map_element_s *next;
    3.64 +
    3.65 +    /** The corresponding key. */
    3.66 +    struct cx_hash_map_key_s key;
    3.67 +};
    3.68 +
    3.69 +
    3.70 +/**
    3.71 + * Creates a new hash map with the specified size using a UcxAllocator.
    3.72 + *
    3.73 + * @param allocator the allocator to use
    3.74 + * @param buckets the initial number of buckets in this hash map
    3.75 + * @return a pointer to the new hash map
    3.76 + */
    3.77 +CxMap *cxHashMapCreate(
    3.78 +        CxAllocator *allocator,
    3.79 +        size_t buckets
    3.80 +);
    3.81 +
    3.82 +/**
    3.83 + * Increases the number of buckets, if necessary.
    3.84 + *
    3.85 + * The load value is \c loadFactor*buckets. If the element count exceeds the load
    3.86 + * value, the map needs to be rehashed. Otherwise, no action is performed and
    3.87 + * this function simply returns 0.
    3.88 + *
    3.89 + * The rehashing process ensures, that the number of buckets is at least
    3.90 + * \p bucketFactor times the number of stored items. So there is enough room for additional
    3.91 + * elements without the need of another soon rehashing.
    3.92 + *
    3.93 + * You can use this function after filling a map to dramatically increase access performance.
    3.94 + *
    3.95 + * @note If the specified map is not a hash map, the behavior is undefined.
    3.96 + *
    3.97 + * @param map the map to rehash
    3.98 + * @param loadFactor a percentage threshold for the load of the map
    3.99 + * @param bucketFactor a factor for the number of buckets that shall be available after rehashing
   3.100 + * @return zero on success, non-zero if a memory allocation error occurred
   3.101 + */
   3.102 +__attribute__((__nonnull__))
   3.103 +int cxMapRehash2(
   3.104 +        CxMap *map,
   3.105 +        float loadFactor,
   3.106 +        float bucketFactor
   3.107 +);
   3.108 +
   3.109 +/**
   3.110 + * Rehashes the map with load factor 0.75 and bucket factor 2.5.
   3.111 + *
   3.112 + * @param map the map to rehash
   3.113 + * @return zero on success, non-zero if a memory allocation error occurred
   3.114 + * @see cxMapRehash2()
   3.115 + */
   3.116 +__attribute__((__nonnull__))
   3.117 +static inline int cxMapRehash(CxMap *map) {
   3.118 +    return cxMapRehash2(map, 0.75f, 2.5f);
   3.119 +}
   3.120 +
   3.121 +
   3.122 +#ifdef __cplusplus
   3.123 +} // extern "C"
   3.124 +#endif
   3.125 +
   3.126 +#endif // UCX_HASH_MAP_H
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/cx/map.h	Wed May 18 16:26:32 2022 +0200
     4.3 @@ -0,0 +1,268 @@
     4.4 +/*
     4.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     4.6 + *
     4.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     4.8 + *
     4.9 + * Redistribution and use in source and binary forms, with or without
    4.10 + * modification, are permitted provided that the following conditions are met:
    4.11 + *
    4.12 + *   1. Redistributions of source code must retain the above copyright
    4.13 + *      notice, this list of conditions and the following disclaimer.
    4.14 + *
    4.15 + *   2. Redistributions in binary form must reproduce the above copyright
    4.16 + *      notice, this list of conditions and the following disclaimer in the
    4.17 + *      documentation and/or other materials provided with the distribution.
    4.18 + *
    4.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    4.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    4.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    4.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    4.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    4.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    4.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    4.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    4.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    4.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    4.29 + * POSSIBILITY OF SUCH DAMAGE.
    4.30 + */
    4.31 +/**
    4.32 + * \file map.h
    4.33 + * \brief Interface for map implementations.
    4.34 + * \author Mike Becker
    4.35 + * \author Olaf Wintermann
    4.36 + * \version 3.0
    4.37 + * \copyright 2-Clause BSD License
    4.38 + */
    4.39 +
    4.40 +#ifndef UCX_MAP_H
    4.41 +#define UCX_MAP_H
    4.42 +
    4.43 +#include "common.h"
    4.44 +#include "allocator.h"
    4.45 +#include "iterator.h"
    4.46 +
    4.47 +#ifdef    __cplusplus
    4.48 +extern "C" {
    4.49 +#endif
    4.50 +
    4.51 +/** Type for the UCX map. */
    4.52 +typedef struct cx_map_s CxMap;
    4.53 +
    4.54 +/** Type for a map entry. */
    4.55 +typedef struct cx_map_entry_s CxMapEntry;
    4.56 +
    4.57 +/** Type for map class definitions. */
    4.58 +typedef struct cx_map_class_s cx_map_class;
    4.59 +
    4.60 +/** Structure for the UCX map. */
    4.61 +struct cx_map_s {
    4.62 +    /** The map class definition. */
    4.63 +    cx_map_class *cl;
    4.64 +    /** An allocator that is used for the map elements. */
    4.65 +    CxAllocator *allocator;
    4.66 +    /** The number of elements currently stored. */
    4.67 +    size_t size;
    4.68 +    // TODO: elemsize + a flag if values shall be copied to the map
    4.69 +};
    4.70 +
    4.71 +/**
    4.72 + * The class definition for arbitrary maps.
    4.73 + */
    4.74 +struct cx_map_class_s {
    4.75 +    /**
    4.76 +     * Deallocates the entire memory.
    4.77 +     */
    4.78 +    __attribute__((__nonnull__))
    4.79 +    void (*destructor)(struct cx_map_s *map);
    4.80 +
    4.81 +    /**
    4.82 +     * Removes all elements.
    4.83 +     */
    4.84 +    __attribute__((__nonnull__))
    4.85 +    void (*clear)(struct cx_map_s *map);
    4.86 +
    4.87 +    /**
    4.88 +     * Add or overwrite an element.
    4.89 +     */
    4.90 +    __attribute__((__nonnull__))
    4.91 +    int (*put)(
    4.92 +            CxMap *map,
    4.93 +            CxDataPtr key,
    4.94 +            void const *value
    4.95 +    );
    4.96 +
    4.97 +    /**
    4.98 +     * Returns an element.
    4.99 +     */
   4.100 +    __attribute__((__nonnull__, __warn_unused_result__))
   4.101 +    void *(*get)(
   4.102 +            CxMap const *map,
   4.103 +            CxDataPtr key
   4.104 +    );
   4.105 +
   4.106 +    /**
   4.107 +     * Removes an element.
   4.108 +     */
   4.109 +    __attribute__((__nonnull__, __warn_unused_result__))
   4.110 +    void *(*remove)(
   4.111 +            CxMap const *map,
   4.112 +            CxDataPtr key
   4.113 +    );
   4.114 +
   4.115 +    /**
   4.116 +     * Iterator over the key/value pairs.
   4.117 +     */
   4.118 +    __attribute__((__nonnull__, __warn_unused_result__))
   4.119 +    CxIterator (*iterator)(CxMap const *map);
   4.120 +
   4.121 +    /**
   4.122 +     * Iterator over the keys.
   4.123 +     */
   4.124 +    __attribute__((__nonnull__, __warn_unused_result__))
   4.125 +    CxIterator (*iterator_keys)(CxMap const *map);
   4.126 +
   4.127 +    /**
   4.128 +     * Iterator over the values.
   4.129 +     */
   4.130 +    __attribute__((__nonnull__, __warn_unused_result__))
   4.131 +    CxIterator (*iterator_values)(CxMap const *map);
   4.132 +};
   4.133 +
   4.134 +/**
   4.135 + * A map entry.
   4.136 + */
   4.137 +struct cx_map_entry_s {
   4.138 +    /**
   4.139 +     * The key.
   4.140 +     */
   4.141 +    CxDataPtr key;
   4.142 +    /**
   4.143 +     * The value.
   4.144 +     */
   4.145 +    void const *value;
   4.146 +};
   4.147 +
   4.148 +
   4.149 +/**
   4.150 + * Deallocates the memory of the specified map.
   4.151 + *
   4.152 + * @param map the map to be destroyed
   4.153 + */
   4.154 +__attribute__((__nonnull__))
   4.155 +static inline void cxMapDestroy(CxMap *map) {
   4.156 +    // TODO: likely to add auto-free feature for contents in the future
   4.157 +    map->cl->destructor(map);
   4.158 +}
   4.159 +
   4.160 +
   4.161 +/**
   4.162 + * Clears a map by removing all elements.
   4.163 + *
   4.164 + * @param map the map to be cleared
   4.165 + */
   4.166 +__attribute__((__nonnull__))
   4.167 +static inline void cxMapClear(CxMap *map) {
   4.168 +    map->cl->clear(map);
   4.169 +}
   4.170 +
   4.171 +/**
   4.172 + * Puts a key/value-pair into the map.
   4.173 + *
   4.174 + * @param map the map
   4.175 + * @param key the key
   4.176 + * @param value the value
   4.177 + * @return 0 on success, non-zero value on failure
   4.178 + */
   4.179 +__attribute__((__nonnull__))
   4.180 +static inline int cxMapPut(
   4.181 +        CxMap *map,
   4.182 +        CxDataPtr key,
   4.183 +        void const *value
   4.184 +) {
   4.185 +    return map->cl->put(map, key, value);
   4.186 +}
   4.187 +
   4.188 +/**
   4.189 + * Retrieves a value by using a key.
   4.190 + *
   4.191 + * @param map the map
   4.192 + * @param key the key
   4.193 + * @return the value
   4.194 + */
   4.195 +__attribute__((__nonnull__, __warn_unused_result__))
   4.196 +void *cxMapGet(
   4.197 +        CxMap const *map,
   4.198 +        CxDataPtr key
   4.199 +) {
   4.200 +    return map->cl->get(map, key);
   4.201 +}
   4.202 +
   4.203 +/**
   4.204 + * Removes a key/value-pair from the map by using the key.
   4.205 + *
   4.206 + * @param map the map
   4.207 + * @param key the key
   4.208 + * @return the removed value
   4.209 + */
   4.210 +__attribute__((__nonnull__, __warn_unused_result__))
   4.211 +void *cxMapRemove(
   4.212 +        CxMap *map,
   4.213 +        CxDataPtr key
   4.214 +) {
   4.215 +    return map->cl->remove(map, key);
   4.216 +}
   4.217 +
   4.218 +// TODO: set-like map operations (union, intersect, difference)
   4.219 +
   4.220 +/**
   4.221 + * Creates a value iterator for a map.
   4.222 + *
   4.223 + * \note An iterator iterates over all elements successively. Therefore the order
   4.224 + * highly depends on the map implementation and may change arbitrarily when the contents change.
   4.225 + *
   4.226 + * @param map the map to create the iterator for
   4.227 + * @return an iterator for the currently stored values
   4.228 + */
   4.229 +__attribute__((__nonnull__, __warn_unused_result__))
   4.230 +static inline CxIterator cxMapIteratorValues(CxMap const *map) {
   4.231 +    return map->cl->iterator_values(map);
   4.232 +}
   4.233 +
   4.234 +/**
   4.235 + * Creates a key iterator for a map.
   4.236 + *
   4.237 + * \note An iterator iterates over all elements successively. Therefore the order
   4.238 + * highly depends on the map implementation and may change arbitrarily when the contents change.
   4.239 + *
   4.240 + * @param map the map to create the iterator for
   4.241 + * @return an iterator for the currently stored keys
   4.242 + */
   4.243 +__attribute__((__nonnull__, __warn_unused_result__))
   4.244 +static inline CxIterator cxMapIteratorKeys(CxMap const *map) {
   4.245 +    return map->cl->iterator_keys(map);
   4.246 +}
   4.247 +
   4.248 +/**
   4.249 + * Creates an iterator for a map.
   4.250 + *
   4.251 + * The values of the iterator are dynamically created key/value pairs of type CxMapEntry.
   4.252 + *
   4.253 + * \note An iterator iterates over all elements successively. Therefore the order
   4.254 + * highly depends on the map implementation and may change arbitrarily when the contents change.
   4.255 + *
   4.256 + * @param map the map to create the iterator for
   4.257 + * @return an iterator for the currently stored keys
   4.258 + * @see cxMapIteratorKeys()
   4.259 + * @see cxMapIteratorValues()
   4.260 + */
   4.261 +__attribute__((__nonnull__, __warn_unused_result__))
   4.262 +static inline CxIterator cxMapIterator(CxMap const *map) {
   4.263 +    return map->cl->iterator(map);
   4.264 +}
   4.265 +
   4.266 +
   4.267 +#ifdef    __cplusplus
   4.268 +}
   4.269 +#endif
   4.270 +
   4.271 +#endif // UCX_MAP_H
   4.272 \ No newline at end of file
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/hash_map.c	Wed May 18 16:26:32 2022 +0200
     5.3 @@ -0,0 +1,105 @@
     5.4 +/*
     5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     5.6 + *
     5.7 + * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     5.8 + *
     5.9 + * Redistribution and use in source and binary forms, with or without
    5.10 + * modification, are permitted provided that the following conditions are met:
    5.11 + *
    5.12 + *   1. Redistributions of source code must retain the above copyright
    5.13 + *      notice, this list of conditions and the following disclaimer.
    5.14 + *
    5.15 + *   2. Redistributions in binary form must reproduce the above copyright
    5.16 + *      notice, this list of conditions and the following disclaimer in the
    5.17 + *      documentation and/or other materials provided with the distribution.
    5.18 + *
    5.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    5.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    5.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    5.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    5.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    5.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    5.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    5.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    5.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    5.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    5.29 + * POSSIBILITY OF SUCH DAMAGE.
    5.30 + */
    5.31 +
    5.32 +#include <string.h>
    5.33 +#include "cx/hash_map.h"
    5.34 +
    5.35 +/**
    5.36 + * Computes a murmur hash-2.
    5.37 + *
    5.38 + * @param data the data to hash
    5.39 + * @param len the length of the data
    5.40 + * @return the murmur hash-2 of the data
    5.41 + */
    5.42 +static unsigned cx_hash_map_murmur(
    5.43 +        unsigned char const *data,
    5.44 +        size_t len
    5.45 +) {
    5.46 +    unsigned m = 0x5bd1e995;
    5.47 +    unsigned r = 24;
    5.48 +    unsigned h = 25 ^ len;
    5.49 +    unsigned i = 0;
    5.50 +    while (len >= 4) {
    5.51 +        unsigned k = data[i + 0] & 0xFF;
    5.52 +        k |= (data[i + 1] & 0xFF) << 8;
    5.53 +        k |= (data[i + 2] & 0xFF) << 16;
    5.54 +        k |= (data[i + 3] & 0xFF) << 24;
    5.55 +
    5.56 +        k *= m;
    5.57 +        k ^= k >> r;
    5.58 +        k *= m;
    5.59 +
    5.60 +        h *= m;
    5.61 +        h ^= k;
    5.62 +
    5.63 +        i += 4;
    5.64 +        len -= 4;
    5.65 +    }
    5.66 +
    5.67 +    switch (len) {
    5.68 +        case 3:
    5.69 +            h ^= (data[i + 2] & 0xFF) << 16;
    5.70 +                    __attribute__((__fallthrough__));
    5.71 +        case 2:
    5.72 +            h ^= (data[i + 1] & 0xFF) << 8;
    5.73 +                    __attribute__((__fallthrough__));
    5.74 +        case 1:
    5.75 +            h ^= (data[i + 0] & 0xFF);
    5.76 +            h *= m;
    5.77 +                    __attribute__((__fallthrough__));
    5.78 +        default:
    5.79 +            /* do nothing */;
    5.80 +    }
    5.81 +
    5.82 +    h ^= h >> 13;
    5.83 +    h *= m;
    5.84 +    h ^= h >> 15;
    5.85 +
    5.86 +    return h;
    5.87 +}
    5.88 +
    5.89 +
    5.90 +/**
    5.91 + * Creates a hash map key based on the given data.
    5.92 + *
    5.93 + * This function implicitly computes the hash.
    5.94 + *
    5.95 + * @attention The data will be copied to the key structure.
    5.96 + *
    5.97 + * @param data the data for the key
    5.98 + * @return the computed key
    5.99 + */
   5.100 +static struct cx_hash_map_key_s cx_hash_map_key(CxDataPtr data) {
   5.101 +    unsigned char *target = malloc(data.len);
   5.102 +    memcpy(target, data.data, data.len);
   5.103 +    struct cx_hash_map_key_s key;
   5.104 +    key.data.data = target;
   5.105 +    key.data.len = data.len;
   5.106 +    key.hash = cx_hash_map_murmur(target, data.len);
   5.107 +    return key;
   5.108 +}

mercurial