few ideas for GList and GHashTable
@stanislav-brabec
Submitted by Stanislav Brabec Link to original bug (#630336)
Description
Using GList and GHashTable, I found need for some functions that are missing. Some of them are trivial enhancements, that can be written on few lines, other cannot be written outside without performance loss or use of private structures.
Please let me know whether there is any interest for patch for particular functions.
I have been thinking about optimization of this task: oldvalue = g_hash_table_lookup (table, key); /* first lookup / if (something (key, oldvalue, value)) g_hash_table_insert (table, newkey, value); / second lookup */
This is not effective: You need two lookups, but one lookup may be enough.
Now imagine, that the value is GList and you need to do g_list_something with it. You surely don't want to destroy the old list, just store the new list head reference.
Reference: bug 596192
You can do it by g_hash_table_steal(), but it requires third lookup.
It could be fixed by:
- Define g_hash_table_replace(), an alternative of g_hash_table_insert() that does not call destructor of the old value.
To get everything in a single lookup, we would need:
Solution 1: Make GHashNode available:
-
Publickly define (probably opaque) GHashNode.
-
Define g_hash_node_get_key (GHashNode *node), g_hash_node_get_value (GHashNode *node) and g_hash_node_insert_value (GHashNode *node) (with calling destructor of the old value) g_hash_node_replace_value (GHashNode *node) (without calling destructor) (making them inline would create faster code but hardcode the ABI)
-
It would be nice to make g_hash_table_remove_node() public (e. g. via wrallers g_hash_node_steal and g_hash_node_remove).
-
Define GHashNode counterpart to existing functions that read key or return return value.
Solution 2: Define function for arbitrary value operation in a single step:
For example define g_hash_table_lookup_and_alter would() that will have a value processing function as an argument.
This solution seems to be uncomforable: Each operation needs custom callback, there is no easy way to automatically call destructor, so the callback would have to call destructor explicitly.
g_list_index_custom: Just like g_list_index, but accepts GCompareFunc line g_list_find_custom.
G_COMPARE_FUNC and G_EQUAL_FUNC retype of GEqualFunc to GCompareFunc wherever only equity is importang.
GEqualFunc: Documentation should refer to instances present in glib (For example: You need to find string in g_list_index_custom. g_str_equal may do exactly what you need.)
Reference: https://bugs.freedesktop.org/show_bug.cgi?id=30214