GHashTable remains a set for as long as all of the keys are exactly
equal (in pointer value) to all of the values. We check this by
comparing keys to values when we do inserts.
Unfortunately, when doing g_hash_table_insert() when a key is already in
the table, the old key pointer value is kept, but the new value pointer
is used. Now we have a situation where a key pointer is unequal to a
value pointer, but we were not treating this case properly.
Fix that.
https://bugzilla.gnome.org/show_bug.cgi?id=692815
When G_DISABLE_ASSERT is not defined, g_hash_table_foreach and
g_hash_table_find dereferences the hash table argument before
checking if it's NULL. This causes a crash when one of this function
is mistakenly called with a NULL argument instead of returning
with a warning through g_return_if_fail.
During the recent refactorings of GHashTable a bug was introduced
where removing all nodes from a hash table would leave tombstones
behind, but make the counts appear like there are none.
Reported and tracked down by Carlos Garnacho,
https://bugzilla.gnome.org/show_bug.cgi?id=651141
This commit also adds a test that checks the internal consistency
of GHashTable over several insert/remove/remove-all operations.
Make hash tables start out in a mode in which they don't store
values at all, until the first insertion of a non-identical
key-value pair.
This reduces memory requirements by 1/3 when using hash tables
to store sets.
Based on a patch by Morten Welinder,
https://bugzilla.gnome.org/show_bug.cgi?id=644437
Kill g_hash_table_lookup_node and rename g_hash_table_lookup_node_for_insertion
to g_hash_table_lookup_node. Since at this point we already check for
toombstones in all callers of g_hash_table_lookup_node this doesn't make
a difference.
https://bugzilla.gnome.org/show_bug.cgi?id=644437
This reduces memory requirements by 1/6 on 64-bit machines since
no padding is needed. It also puts less strain on the memory
allocator since we no longer need one giant slab of memory.
https://bugzilla.gnome.org/show_bug.cgi?id=644437
* glib/ghash.c: changed "#GHashTableIterator" to "#GHashTableIter"
in the documentation-comments above g_hash_table_foreach_remove()
and g_hash_table_foreach_steal() to correctly name and link to
GHashTableIter. This affects the GNOME documentation website
as well, so further steps are likely necessary beyond this subproject.
* ChangeLog modified to reflect this.
-Joseph (solarion)
svn path=/trunk/; revision=7631
2008-09-19 Hans Petter Jansson <hpj@novell.com>
Rewrite most of GHashTable to use open addressing with quadratic
probing instead of chaining. This has the potential to reduce memory
fragmentation significantly, while being slightly faster due to
better locality and no need to call alloc/free functions for nodes.
Benchmarks suggest it also uses less memory overall.
* glib/ghash.c (prime_mod): Table of suitable primes for
initial-probe distribution.
(g_hash_table_set_shift): New function.
(g_hash_table_find_closest_shift): New function.
(g_hash_table_set_shift_from_size): New function.
(g_hash_table_lookup_node_for_insertion): New function.
(g_hash_table_lookup_node): Rewritten to return node index instead of
pointer, use quadratic probe on flat table, and not return insertion
data. The latter saves some computation for read-only lookups.
(g_hash_table_remove_node): Rewrite to take a pointer directly to the
node structure to remove, and clear that. Remove unlinking code.
(g_hash_table_remove_all_nodes): Rewrite to not clear nodes
individually, but en masse using memset () after potentially calling
notify functions.
(iter_remove_or_steal): Use new data structure and algorithm. Vastly
simplified - now just a call to g_hash_table_remove_node ().
(g_hash_table_resize): New resize code, re-indexing with new prime
and cleaning up tombstones.
(g_hash_table_maybe_resize): Table may hold 8 buckets minimum, no less
than 1/4 load excluding tombstones, and no more than 15/16 load
including tombstones. These numbers are the results of a lot of
benchmarking with multiple complex applications, and should not be
changed lightly.
(g_hash_table_iter_next)
(g_hash_table_lookup)
(g_hash_table_lookup_extended)
(g_hash_table_insert_internal)
(g_hash_table_remove_internal)
(g_hash_table_foreach_remove_or_steal)
(g_hash_table_foreach)
(g_hash_table_find)
(g_hash_table_get_keys)
(g_hash_table_get_values): Use new data structure and algorithm,
fairly trivial changes.
svn path=/trunk/; revision=7518
2008-01-02 Alvaro Lopez Ortega <alvaro@sun.com>
* glib/ghash.c (g_hash_table_replace, g_hash_table_insert): These
functions prototype defines its output as void, and therefore they
should not return any value. This patch fixes a compilation error:
the "return" clauses were incompatible with the functions prototype.
svn path=/trunk/; revision=6230