Search code examples
cdata-structureshashtableglib

Search HashTable not by unique key


I have a struct comprising a key and a trile of integers:

struct MyStruct
{
guint32 key;
guint64 field1;
guint64 field2
guint64 field3;
};

which I need to store into some kind of dictionarty structure. I have chosen a GHashTable (glib).

MyStruct member key is unique, therfore I chose to use that as the key. However I need to retrieve each struct instance by doing a search over field1, and possibly over field1 and field2.

Please find below my hash and equal functions.

static guint32
my_struct_oid_hash(gconstpointer k)
{
    my_struct *my_data = (my_struct *)k;

    return my_data->key;
}


static gint
my_struct_oid_equal(gconstpointer k1, gconstpointer k2)
{
    my_struct *my_data1;
    my_struct *my_data2;

    my_data1 = (my_struct *)k1;
    my_data2 = (my_struct *)k2;

    return ((my_data1->field1 == my_data2->field1) && (my_data1->field2 == my_data2->field2));
}

The problem is that both the lookup and lookup_extenede functions always returns NULL.

my_struct* my_key;

    my_key->key=0; //set key to 0 just for the sake of inizializazion. It is not used for the comparison in the my_struct_oid_equal function.

    my_key->field1=1;
    my_key->field2=2;


my_data = ((my_struct*)(g_hash_table_lookup(my_hashtable, my_key)));

What am I doing wrong?

I changed the last line of my_struct_oid_hash to

return ((guint32)*((const my_struct *)my_data));

and I tried the approach suggested here, but I got the following compiling errors:

error C2440: 'type cast' : cannot convert from 'const my_struct' to 'guint32'
warning C4033: 'my_struct_oid_hash' must return a value.

Howvever I do not believe that is the way to go as casting my_struct to guint would not make much sense.

I have also thought that a hashtable may not be the best solution as I am not searching by the key value. In this case, apart from GList, what would be the other options with direct access in glib?


Solution

  • First of all, you are getting a NULL because you are looking for a struct, not a key. Instead of:

    my_data = ((my_struct*)(g_hash_table_lookup(my_hashtable, my_key)));
    

    Use

    my_data = ((my_struct*)(g_hash_table_lookup(my_hashtable, my_key->key)));
    

    Or

    my_data = ((my_struct*)(g_hash_table_lookup(my_hashtable, 0)));
    

    Anyway, looks like you want a three data value as key (key, field1 and field2), so you need another way to store your key, because GHashTable only use one parameter for the key...

    Perhaps a string key with the three values, separated by a string like "|" (i.e. "0|1|2"), parsing the data in the hash equal function.

    Hope it help.