ucx/cx/hash_key.h

changeset 888
af685cc9d623
parent 854
1c8401ece69e
--- a/ucx/cx/hash_key.h	Sun Aug 31 14:39:13 2025 +0200
+++ b/ucx/cx/hash_key.h	Sat Nov 08 23:06:11 2025 +0100
@@ -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;
 };
 
 /**
@@ -76,8 +79,45 @@
  * @see cx_hash_key()
  */
 cx_attr_nonnull
-cx_attr_export
-void cx_hash_murmur(CxHashKey *key);
+CX_EXPORT 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_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_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_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_EXPORT CxHashKey cx_hash_key_u64(uint64_t x);
 
 /**
  * Computes a hash key from a string.
@@ -87,10 +127,22 @@
  * @param str the string
  * @return the hash key
  */
-cx_attr_nodiscard
-cx_attr_cstr_arg(1)
-cx_attr_export
-CxHashKey cx_hash_key_str(const char *str);
+cx_attr_nodiscard cx_attr_cstr_arg(1)
+CX_EXPORT 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_EXPORT CxHashKey cx_hash_key_ustr(const unsigned char *str);
 
 /**
  * Computes a hash key from a byte array.
@@ -99,13 +151,8 @@
  * @param len the length
  * @return the hash key
  */
-cx_attr_nodiscard
-cx_attr_access_r(1, 2)
-cx_attr_export
-CxHashKey cx_hash_key_bytes(
-        const unsigned char *bytes,
-        size_t len
-);
+cx_attr_nodiscard cx_attr_access_r(1, 2)
+CX_EXPORT CxHashKey cx_hash_key_bytes(const unsigned char *bytes, size_t len);
 
 /**
  * Computes a hash key for an arbitrary object.
@@ -115,16 +162,21 @@
  * 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
 cx_attr_access_r(1, 2)
-cx_attr_export
-CxHashKey cx_hash_key(
-        const void *obj,
-        size_t len
-);
+CX_EXPORT CxHashKey cx_hash_key(const void *obj, size_t len);
+
+/**
+ * Computes a hash key from a UCX string.
+ *
+ * @param str the string
+ * @return the hash key
+ */
+cx_attr_nodiscard
+CX_EXPORT CxHashKey cx_hash_key_cxstr(cxstring str);
 
 /**
  * Computes a hash key from a UCX string.
@@ -133,20 +185,91 @@
  * @return the hash key
  */
 cx_attr_nodiscard
-static inline CxHashKey cx_hash_key_cxstr(cxstring str) {
-    return cx_hash_key(str.ptr, str.length);
-}
+CX_EXPORT CxHashKey cx_hash_key_mutstr(cxmutstr str);
 
 /**
- * Computes a hash key from a UCX string.
+ * 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
+CX_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 str (@c cxstring or @c cxmutstr) the string
- * @return (@c CxHashKey) the hash key
+ * @param key the key data
+ * @returns the @c CxHashKey
  */
-#define cx_hash_key_cxstr(str) cx_hash_key_cxstr(cx_strcast(str))
+#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
+
+/**
+ * Compare function for hash keys.
+ *
+ * The pointers are untyped to be compatible with the cx_compare_func signature.
+ *
+ * @param left (@c CxHashKey*) the first key
+ * @param right (@c CxHashKey*) the second key
+ * @return zero when the keys equal, non-zero when they differ
+ */
+cx_attr_nodiscard cx_attr_nonnull
+CX_EXPORT int cx_hash_key_cmp(const void *left, const void *right);
 
 #ifdef __cplusplus
 } // extern "C"
+
+// ----------------------------------------------------------
+// Overloads of CX_HASH_KEY (the C++ version of a _Generic)
+// ----------------------------------------------------------
+
+CX_CPPDECL CxHashKey CX_HASH_KEY(CxHashKey key) {
+    return key;
+}
+
+CX_CPPDECL CxHashKey CX_HASH_KEY(cxstring str) {
+    return cx_hash_key_cxstr(str);
+}
+
+CX_CPPDECL CxHashKey CX_HASH_KEY(cxmutstr str) {
+    return cx_hash_key_mutstr(str);
+}
+
+CX_CPPDECL CxHashKey CX_HASH_KEY(const char *str) {
+    return cx_hash_key_str(str);
+}
+
+CX_CPPDECL CxHashKey CX_HASH_KEY(const unsigned char *str) {
+    return cx_hash_key_ustr(str);
+}
+
+CX_CPPDECL CxHashKey CX_HASH_KEY(uint32_t key) {
+    return cx_hash_key_u32(key);
+}
+
+CX_CPPDECL CxHashKey CX_HASH_KEY(uint64_t key) {
+    return cx_hash_key_u64(key);
+}
 #endif
 
 #endif // UCX_HASH_KEY_H

mercurial