summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hash_table.c8
-rw-r--r--hash_table.h10
2 files changed, 12 insertions, 6 deletions
diff --git a/hash_table.c b/hash_table.c
index efe15e9..a7d182a 100644
--- a/hash_table.c
+++ b/hash_table.c
@@ -144,9 +144,7 @@ hash_table_destroy(struct hash_table *ht,
if (delete_function) {
struct hash_entry *entry;
- for (entry = hash_table_next_entry(ht, NULL);
- entry != NULL;
- entry = hash_table_next_entry(ht, entry)) {
+ hash_table_foreach(ht, entry) {
delete_function(entry);
}
}
@@ -210,9 +208,7 @@ hash_table_rehash(struct hash_table *ht, int new_size_index)
ht->entries = 0;
ht->deleted_entries = 0;
- for (entry = old_ht.table;
- entry != old_ht.table + old_ht.size;
- entry++) {
+ hash_table_foreach(&old_ht, entry) {
if (entry_is_present(entry)) {
hash_table_insert(ht, entry->hash,
entry->key, entry->data);
diff --git a/hash_table.h b/hash_table.h
index ffa3ec7..9afb4cd 100644
--- a/hash_table.h
+++ b/hash_table.h
@@ -60,3 +60,13 @@ struct hash_entry *hash_table_next_entry(struct hash_table *ht,
struct hash_entry *
hash_table_random_entry(struct hash_table *ht,
int (*predicate)(struct hash_entry *entry));
+
+/**
+ * This foreach function is safe against deletion (which just replaces
+ * an entry's data with the deleted marker), but not against insertion
+ * (which may rehash the table, making entry a dangling pointer).
+ */
+#define hash_table_foreach(ht, entry) \
+ for (entry = hash_table_next_entry(ht, NULL); \
+ entry != NULL; \
+ entry = hash_table_next_entry(ht, entry))