【问题标题】:GHashTable that using uint64_t as key and a struct as value使用 uint64_t 作为键和结构作为值的 GHashTable
【发布时间】:2014-08-14 00:33:01
【问题描述】:

我正在研究GHashTable。虽然 Stackoverflow 中已经有一些示例,但它们只是一些常见情况。所以我仍然不确定如何实现我的要求并决定寻求帮助。
我想使用 uint64_t 作为键和 struct 作为值。我发现GLib 中没有这样的内置哈希函数。只有一个g_int64_hash()。虽然密钥是uint64_t,但它只有大约 52 位。所以我认为gint64 可以。但我看到一些使用GINT_TO_POINTER() 转换值的示例(有时他们没有)。所以只是对此感到困惑。
非常感谢!

【问题讨论】:

    标签: c linux hashtable glibc


    【解决方案1】:

    ghash.c 中查看g_int64_hashg_int64_equal 是如何实现的:

    ...
    gboolean
    g_int64_equal (gconstpointer v1,
                   gconstpointer v2)
    {
      return *((const gint64*) v1) == *((const gint64*) v2);
    }
    ...
    guint
    g_int64_hash (gconstpointer v)
    {
      return (guint) *(const gint64*) v;
    }
    ...
    

    你可以写你赢的uint64_t_hashuint64_equal类似:

    gboolean
    uint64_t_equal (gconstpointer v1,
                    gconstpointer v2)
    {
      return *((const uint64_t*) v1) == *((const uint64_t*) v2);
    }
    
    guint
    uint64_t_hash (gconstpointer v)
    {
      return (guint) *(const uint64_t*) v;
    }
    

    看一个例子:

    #include <glib.h>
    #include <stdio.h>
    #include <inttypes.h>
    
    /* the value structure */
    typedef struct __MyStruct
    {
      int a;
      int b;
    } MyStruct;
    
    /* the hash equality function */
    static gboolean
    uint64_t_equal (gconstpointer v1,
                    gconstpointer v2)
    {
      return *((const uint64_t*) v1) == *((const uint64_t*) v2);
    }
    
    /* the hash function */
    static guint
    uint64_t_hash (gconstpointer v)
    {
      return (guint) *(const uint64_t*) v;
    }
    
    /* the hash function */
    static void
    print_hash(gpointer key,
               gpointer value,
               gpointer user_data)
    {
      printf("%" PRIu64 " = {%d, %d}\n",
        *(uint64_t*) key, ((MyStruct *) value)->a, ((MyStruct *) value)->b);
    }
    
    int
    main(int argc, char **argv)
    {
      GHashTable *hash;
    
      /* key => value */
      uint64_t k1 = 11; MyStruct s1 = {1, 11};
      uint64_t k2 = 22; MyStruct s2 = {2, 22};
      uint64_t k3 = 33; MyStruct s3 = {3, 33};
    
      hash = g_hash_table_new(uint64_t_hash, uint64_t_equal);
    
      /* insert values */
      g_hash_table_insert(hash, &k1, &s1);
      g_hash_table_insert(hash, &k2, &s2);
      g_hash_table_insert(hash, &k3, &s3);
    
      /* iterate over the values in the hash table */
      g_hash_table_foreach(hash, print_hash, NULL);
      g_hash_table_destroy(hash);
      return 0;
    }
    

    【讨论】:

    • 谢谢!我没有能力找出里面的东西。:) 那我应该像这样调用 g_hash_talbe_insert() 吗? uint64_t key; struct A val; g_hash_table_insert(table, &amp;key, &amp;val);g_hash_table_insert(table, key, &amp;val);
    • @tamlok 第一个是正确的,insert 期望在键和值中都有一个指针。好的,我添加了一个完整的示例。
    • 谢谢,它有效。但是当我使用g_hash_table_lookup(hash, &amp;k1) 时,它返回NULL。为什么?
    • @tamlok 它对我来说很好,确保k1s1 是活着的,你可能需要将它们分配在堆上而不是堆栈上,如果它们会死掉的话。
    • 是的,它有效!我只是犯了一个愚蠢的错误。我用if (!result) { print(result); } else { print("lookup returns NULL"); }。再次非常感谢您及时耐心的指导! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 2015-10-17
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多