#include "git-compat-util.h"
#include "strmap.h"
+#include "mem-pool.h"
int cmp_strmap_entry(const void *hashmap_cmp_fn_data,
const struct hashmap_entry *entry1,
void strmap_init(struct strmap *map)
{
- strmap_init_with_options(map, 1);
+ strmap_init_with_options(map, NULL, 1);
}
void strmap_init_with_options(struct strmap *map,
+ struct mem_pool *pool,
int strdup_strings)
{
hashmap_init(&map->map, cmp_strmap_entry, NULL, 0);
+ map->pool = pool;
map->strdup_strings = strdup_strings;
}
if (!map)
return;
+ if (!free_values && map->pool)
+ /* Memory other than util is owned by and freed with the pool */
+ return;
+
/*
* We need to iterate over the hashmap entries and free
* e->key and e->value ourselves; hashmap has no API to
hashmap_for_each_entry(&map->map, &iter, e, ent) {
if (free_values)
free(e->value);
- if (map->strdup_strings)
- free((char*)e->key);
- free(e);
+ if (!map->pool)
+ free(e);
}
}
hashmap_partial_clear(&map->map);
}
+static struct strmap_entry *create_entry(struct strmap *map,
+ const char *str,
+ void *data)
+{
+ struct strmap_entry *entry;
+
+ if (map->strdup_strings) {
+ if (!map->pool) {
+ FLEXPTR_ALLOC_STR(entry, key, str);
+ } else {
+ size_t len = st_add(strlen(str), 1); /* include NUL */
+ entry = mem_pool_alloc(map->pool,
+ st_add(sizeof(*entry), len));
+ memcpy(entry + 1, str, len);
+ entry->key = (void *)(entry + 1);
+ }
+ } else if (!map->pool) {
+ entry = xmalloc(sizeof(*entry));
+ } else {
+ entry = mem_pool_alloc(map->pool, sizeof(*entry));
+ }
+ hashmap_entry_init(&entry->ent, strhash(str));
+ if (!map->strdup_strings)
+ entry->key = str;
+ entry->value = data;
+ return entry;
+}
+
void *strmap_put(struct strmap *map, const char *str, void *data)
{
struct strmap_entry *entry = find_strmap_entry(map, str);
- void *old = NULL;
if (entry) {
- old = entry->value;
+ void *old = entry->value;
entry->value = data;
- } else {
- const char *key = str;
-
- entry = xmalloc(sizeof(*entry));
- hashmap_entry_init(&entry->ent, strhash(str));
-
- if (map->strdup_strings)
- key = xstrdup(str);
- entry->key = key;
- entry->value = data;
- hashmap_add(&map->map, &entry->ent);
+ return old;
}
- return old;
+
+ entry = create_entry(map, str, data);
+ hashmap_add(&map->map, &entry->ent);
+ return NULL;
}
struct strmap_entry *strmap_get_entry(struct strmap *map, const char *str)
return;
if (free_value)
free(ret->value);
- if (map->strdup_strings)
- free((char*)ret->key);
- free(ret);
+ if (!map->pool)
+ free(ret);
}
void strintmap_incr(struct strintmap *map, const char *str, intptr_t amt)
else
strintmap_set(map, str, map->default_value + amt);
}
+
+int strset_add(struct strset *set, const char *str)
+{
+ /*
+ * Cannot use strmap_put() because it'll return NULL in both cases:
+ * - cannot find str: NULL means "not found"
+ * - does find str: NULL is the value associated with str
+ */
+ struct strmap_entry *entry = find_strmap_entry(&set->map, str);
+
+ if (entry)
+ return 0;
+
+ entry = create_entry(&set->map, str, NULL);
+ hashmap_add(&set->map.map, &entry->ent);
+ return 1;
+}