mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 05:56:14 +01:00
Preserve consistency when removing all nodes from a hash table
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.
This commit is contained in:
parent
b92861b5a0
commit
5d7b67a6c3
14
glib/ghash.c
14
glib/ghash.c
@ -200,8 +200,10 @@
|
|||||||
|
|
||||||
#define HASH_TABLE_MIN_SHIFT 3 /* 1 << 3 == 8 buckets */
|
#define HASH_TABLE_MIN_SHIFT 3 /* 1 << 3 == 8 buckets */
|
||||||
|
|
||||||
#define HASH_IS_UNUSED(h_) ((h_) == 0)
|
#define UNUSED_HASH_VALUE 0
|
||||||
#define HASH_IS_TOMBSTONE(h_) ((h_) == 1)
|
#define TOMBSTONE_HASH_VALUE 1
|
||||||
|
#define HASH_IS_UNUSED(h_) ((h_) == UNUSED_HASH_VALUE)
|
||||||
|
#define HASH_IS_TOMBSTONE(h_) ((h_) == TOMBSTONE_HASH_VALUE)
|
||||||
#define HASH_IS_REAL(h_) ((h_) >= 2)
|
#define HASH_IS_REAL(h_) ((h_) >= 2)
|
||||||
|
|
||||||
struct _GHashTable
|
struct _GHashTable
|
||||||
@ -426,7 +428,7 @@ g_hash_table_remove_node (GHashTable *hash_table,
|
|||||||
value = hash_table->values[i];
|
value = hash_table->values[i];
|
||||||
|
|
||||||
/* Erect tombstone */
|
/* Erect tombstone */
|
||||||
hash_table->hashes[i] = 1;
|
hash_table->hashes[i] = TOMBSTONE_HASH_VALUE;
|
||||||
|
|
||||||
/* Be GC friendly */
|
/* Be GC friendly */
|
||||||
hash_table->keys[i] = NULL;
|
hash_table->keys[i] = NULL;
|
||||||
@ -482,7 +484,7 @@ g_hash_table_remove_all_nodes (GHashTable *hash_table,
|
|||||||
key = hash_table->keys[i];
|
key = hash_table->keys[i];
|
||||||
value = hash_table->values[i];
|
value = hash_table->values[i];
|
||||||
|
|
||||||
hash_table->hashes[i] = 0;
|
hash_table->hashes[i] = UNUSED_HASH_VALUE;
|
||||||
hash_table->keys[i] = NULL;
|
hash_table->keys[i] = NULL;
|
||||||
hash_table->values[i] = NULL;
|
hash_table->values[i] = NULL;
|
||||||
|
|
||||||
@ -492,6 +494,10 @@ g_hash_table_remove_all_nodes (GHashTable *hash_table,
|
|||||||
if (hash_table->value_destroy_func != NULL)
|
if (hash_table->value_destroy_func != NULL)
|
||||||
hash_table->value_destroy_func (value);
|
hash_table->value_destroy_func (value);
|
||||||
}
|
}
|
||||||
|
else if (HASH_IS_TOMBSTONE (hash_table->hashes[i]))
|
||||||
|
{
|
||||||
|
hash_table->hashes[i] = UNUSED_HASH_VALUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user