Line data Source code
1 0 : /* 2 : * Copyright (c) 2022 Meta 3 : * 4 : * SPDX-License-Identifier: Apache-2.0 5 : */ 6 : 7 : #ifndef ZEPHYR_INCLUDE_SYS_HASH_FUNCTION_H_ 8 : #define ZEPHYR_INCLUDE_SYS_HASH_FUNCTION_H_ 9 : 10 : #include <stddef.h> 11 : #include <stdint.h> 12 : 13 : #include <zephyr/sys/__assert.h> 14 : #include <zephyr/sys/util_macro.h> 15 : 16 : #ifdef __cplusplus 17 : extern "C" { 18 : #endif 19 : 20 : /** 21 : * @ingroup hashmap_apis 22 : * @defgroup hash_functions Hash Functions 23 : * @{ 24 : */ 25 : 26 : /** 27 : * @brief 32-bit Hash function interface 28 : * 29 : * Hash functions are used to map data from an arbitrarily large space to a 30 : * (typically smaller) fixed-size space. For a given input, a hash function will 31 : * consistently generate the same, semi-unique numerical value. Even for 32 : * marginally different data, a good hash function will distribute the entropy 33 : * almost evenly over all bits in the hashed value when combined with modulo 34 : * arithmetic over a finite-sized numeric field. 35 : * 36 : * @param str a string of input data 37 : * @param n the number of bytes in @p str 38 : * 39 : * @return the numeric hash associated with @p str 40 : */ 41 1 : typedef uint32_t (*sys_hash_func32_t)(const void *str, size_t n); 42 : 43 : /** 44 : * @brief The naive identity hash function 45 : * 46 : * This hash function requires that @p n is equal to the size of a primitive 47 : * type, such as `[u]int8_t`, `[u]int16_t`, `[u]int32_t`, `[u]int64_t`, 48 : * `float`, `double`, or `void *`, and that the alignment of @p str agrees 49 : * with that of the respective native type. 50 : * 51 : * @note The identity hash function is used for testing @ref sys_hashmap. 52 : * 53 : * @param str a string of input data 54 : * @param n the number of bytes in @p str 55 : * 56 : * @return the numeric hash associated with @p str 57 : */ 58 1 : static inline uint32_t sys_hash32_identity(const void *str, size_t n) 59 : { 60 : switch (n) { 61 : case sizeof(uint8_t): 62 : return *(uint8_t *)str; 63 : case sizeof(uint16_t): 64 : return *(uint16_t *)str; 65 : case sizeof(uint32_t): 66 : return *(uint32_t *)str; 67 : case sizeof(uint64_t): 68 : return (uint32_t)(*(uint64_t *)str); 69 : default: 70 : break; 71 : } 72 : 73 : __ASSERT(false, "invalid str length %zu", n); 74 : 75 : return 0; 76 : } 77 : 78 : /** 79 : * @brief Daniel J.\ Bernstein's hash function 80 : * 81 : * Some notes: 82 : * - normally, this hash function is used on NUL-terminated strings 83 : * - it has been modified to support arbitrary sequences of bytes 84 : * - it has been modified to use XOR rather than addition 85 : * 86 : * @param str a string of input data 87 : * @param n the number of bytes in @p str 88 : * 89 : * @return the numeric hash associated with @p str 90 : * 91 : * @note enable with @kconfig{CONFIG_SYS_HASH_FUNC32_DJB2} 92 : * 93 : * @see https://theartincode.stanis.me/008-djb2/ 94 : */ 95 1 : uint32_t sys_hash32_djb2(const void *str, size_t n); 96 : 97 : /** 98 : * @brief Murmur3 hash function 99 : * 100 : * @param str a string of input data 101 : * @param n the number of bytes in @p str 102 : * 103 : * @return the numeric hash associated with @p str 104 : * 105 : * @note enable with @kconfig{CONFIG_SYS_HASH_FUNC32_MURMUR3} 106 : * 107 : * @see https://en.wikipedia.org/wiki/MurmurHash 108 : */ 109 1 : uint32_t sys_hash32_murmur3(const void *str, size_t n); 110 : 111 : /** 112 : * @brief System default 32-bit hash function 113 : * 114 : * @param str a string of input data 115 : * @param n the number of bytes in @p str 116 : * 117 : * @return the numeric hash associated with @p str 118 : */ 119 1 : static inline uint32_t sys_hash32(const void *str, size_t n) 120 : { 121 : if (IS_ENABLED(CONFIG_SYS_HASH_FUNC32_CHOICE_IDENTITY)) { 122 : return sys_hash32_identity(str, n); 123 : } 124 : 125 : if (IS_ENABLED(CONFIG_SYS_HASH_FUNC32_CHOICE_DJB2)) { 126 : return sys_hash32_djb2(str, n); 127 : } 128 : 129 : if (IS_ENABLED(CONFIG_SYS_HASH_FUNC32_CHOICE_MURMUR3)) { 130 : return sys_hash32_murmur3(str, n); 131 : } 132 : 133 : __ASSERT(0, "No default 32-bit hash. See CONFIG_SYS_HASH_FUNC32_CHOICE"); 134 : 135 : return 0; 136 : } 137 : 138 : /** 139 : * @} 140 : */ 141 : 142 : #ifdef __cplusplus 143 : } 144 : #endif 145 : 146 : #endif /* ZEPHYR_INCLUDE_SYS_HASH_FUNCTION_H_ */