@@ -174,22 +174,37 @@ void hashmap_init(struct hashmap *map, hashmap_cmp_fn equals_function,
map->do_count_items = 1;
}
+static void free_individual_entries(struct hashmap *map, ssize_t entry_offset)
+{
+ struct hashmap_iter iter;
+ struct hashmap_entry *e;
+
+ hashmap_iter_init(map, &iter);
+ while ((e = hashmap_iter_next(&iter)))
+ /*
+ * like container_of, but using caller-calculated
+ * offset (caller being hashmap_free_entries)
+ */
+ free((char *)e - entry_offset);
+}
+
+void hashmap_partial_clear_(struct hashmap *map, ssize_t entry_offset)
+{
+ if (!map || !map->table)
+ return;
+ if (entry_offset >= 0) /* called by hashmap_clear_entries */
+ free_individual_entries(map, entry_offset);
+ memset(map->table, 0, map->tablesize * sizeof(struct hashmap_entry *));
+ map->shrink_at = 0;
+ map->private_size = 0;
+}
+
void hashmap_free_(struct hashmap *map, ssize_t entry_offset)
{
if (!map || !map->table)
return;
- if (entry_offset >= 0) { /* called by hashmap_free_entries */
- struct hashmap_iter iter;
- struct hashmap_entry *e;
-
- hashmap_iter_init(map, &iter);
- while ((e = hashmap_iter_next(&iter)))
- /*
- * like container_of, but using caller-calculated
- * offset (caller being hashmap_free_entries)
- */
- free((char *)e - entry_offset);
- }
+ if (entry_offset >= 0) /* called by hashmap_free_entries */
+ free_individual_entries(map, entry_offset);
free(map->table);
memset(map, 0, sizeof(*map));
}
@@ -235,7 +235,8 @@ void hashmap_init(struct hashmap *map,
const void *equals_function_data,
size_t initial_size);
-/* internal function for freeing hashmap */
+/* internal functions for clearing or freeing hashmap */
+void hashmap_partial_clear_(struct hashmap *map, ssize_t offset);
void hashmap_free_(struct hashmap *map, ssize_t offset);
/*
@@ -268,6 +269,16 @@ void hashmap_free_(struct hashmap *map, ssize_t offset);
*/
#define hashmap_free(map) hashmap_free_(map, -1)
+/*
+ * Basically the same as calling hashmap_free() followed by hashmap_init(),
+ * but doesn't incur the overhead of deallocating and reallocating
+ * map->table; it leaves map->table allocated and the same size but zeroes
+ * it out so it's ready for use again as an empty map. As with
+ * hashmap_free(), you may need to free the entries yourself before calling
+ * this function.
+ */
+#define hashmap_partial_clear(map) hashmap_partial_clear_(map, -1)
+
/*
* Frees @map and all entries. @type is the struct type of the entry
* where @member is the hashmap_entry struct used to associate with @map.