--- a/ucx/cx/hash_key.h Sat Oct 04 14:54:25 2025 +0200 +++ b/ucx/cx/hash_key.h Sun Oct 19 21:20:08 2025 +0200 @@ -46,14 +46,17 @@ /** Internal structure for a key within a hash map. */ struct cx_hash_key_s { - /** The key data. */ + /** + * The key data. + * May be NULL when the hash is collision-free. + */ const void *data; /** * The key data length. */ size_t len; /** The hash value of the key data. */ - unsigned hash; + uint64_t hash; }; /** @@ -80,6 +83,48 @@ void cx_hash_murmur(CxHashKey *key); /** + * Mixes up a 32-bit integer to be used as a hash. + * + * This function produces no collisions and has a good statistical distribution. + * + * @param x the integer + * @return the hash + */ +cx_attr_export +uint32_t cx_hash_u32(uint32_t x); + +/** + * Mixes up a 64-bit integer to be used as a hash. + * + * This function produces no collisions and has a good statistical distribution. + * + * @param x the integer + * @return the hash + */ +cx_attr_export +uint64_t cx_hash_u64(uint64_t x); + +/** + * Computes a hash key from a 32-bit integer. + * + * @param x the integer + * @return the hash key + */ +cx_attr_nodiscard +cx_attr_export +CxHashKey cx_hash_key_u32(uint32_t x); + +/** + * Computes a hash key from a 64-bit integer. + * + * @param x the integer + * @return the hash key + */ +cx_attr_nodiscard +cx_attr_export +CxHashKey cx_hash_key_u64(uint64_t x); + +/** * Computes a hash key from a string. * * The string needs to be zero-terminated. @@ -93,6 +138,24 @@ CxHashKey cx_hash_key_str(const char *str); /** + * Computes a hash key from a string. + * + * Use this function when the string is represented + * as an unsigned char array. + * + * The string needs to be zero-terminated. + * + * @param str the string + * @return the hash key + */ +cx_attr_nodiscard +cx_attr_cstr_arg(1) +cx_attr_export +static inline CxHashKey cx_hash_key_ustr(const unsigned char *str) { + return cx_hash_key_str((const char*)str); +} + +/** * Computes a hash key from a byte array. * * @param bytes the array @@ -115,7 +178,7 @@ * used for data exchange with different machines. * * @param obj a pointer to an arbitrary object - * @param len the length of object in memory + * @param len the length of the object in memory * @return the hash key */ cx_attr_nodiscard @@ -140,13 +203,106 @@ /** * Computes a hash key from a UCX string. * + * @param str the string + * @return the hash key + */ +cx_attr_nodiscard +static inline CxHashKey cx_hash_key_mutstr(cxmutstr str) { + return cx_hash_key(str.ptr, str.length); +} + +/** + * The identity function for the CX_HASH_KEY() macro. + * You should never need to use this manually. + * + * @param key the key + * @return a copy of the key + */ +cx_attr_nodiscard +static inline CxHashKey cx_hash_key_identity(CxHashKey key) { + return key; +} + +#ifndef __cplusplus +/** + * Creates a hash key from any of the supported types with implicit length. + * + * Does nothing when passing a CxHashkey. + * + * Supported types are UCX strings, zero-terminated C strings, + * and 32-bit or 64-bit unsigned integers. + * + * @param key the key data + * @returns the @c CxHashKey + */ +#define CX_HASH_KEY(key) _Generic((key), \ + CxHashKey: cx_hash_key_identity, \ + cxstring: cx_hash_key_cxstr, \ + cxmutstr: cx_hash_key_mutstr, \ + char*: cx_hash_key_str, \ + const char*: cx_hash_key_str, \ + unsigned char*: cx_hash_key_ustr, \ + const unsigned char*: cx_hash_key_ustr, \ + uint32_t: cx_hash_key_u32, \ + uint64_t: cx_hash_key_u64) \ + (key) +#endif // __cplusplus + +/** + * Computes a hash key from a UCX string. + * Convenience macro that accepts both cxstring and cxmutstr. + * @deprecated use the CX_HASH_KEY() macro instead * @param str (@c cxstring or @c cxmutstr) the string * @return (@c CxHashKey) the hash key */ #define cx_hash_key_cxstr(str) cx_hash_key_cxstr(cx_strcast(str)) +/** + * Compare function for hash keys. + * + * @param left the first key + * @param right the second key + * @return zero when the keys equal, non-zero when they differ + */ +cx_attr_nodiscard +cx_attr_nonnull +cx_attr_export +int cx_hash_key_cmp(const CxHashKey *left, const CxHashKey *right); + #ifdef __cplusplus } // extern "C" + +// ---------------------------------------------------------- +// Overloads of CX_HASH_KEY (the C++ version of a _Generic) +// ---------------------------------------------------------- + +static inline CxHashKey CX_HASH_KEY(CxHashKey key) { + return key; +} + +static inline CxHashKey CX_HASH_KEY(cxstring str) { + return cx_hash_key_cxstr(str); +} + +static inline CxHashKey CX_HASH_KEY(cxmutstr str) { + return cx_hash_key_mutstr(str); +} + +static inline CxHashKey CX_HASH_KEY(const char *str) { + return cx_hash_key_str(str); +} + +static inline CxHashKey CX_HASH_KEY(const unsigned char *str) { + return cx_hash_key_ustr(str); +} + +static inline CxHashKey CX_HASH_KEY(uint32_t key) { + return cx_hash_key_u32(key); +} + +static inline CxHashKey CX_HASH_KEY(uint64_t key) { + return cx_hash_key_u64(key); +} #endif #endif // UCX_HASH_KEY_H