1 #include "git-compat-util.h"
5 int cmp_strmap_entry(const void *hashmap_cmp_fn_data
,
6 const struct hashmap_entry
*entry1
,
7 const struct hashmap_entry
*entry2
,
10 const struct strmap_entry
*e1
, *e2
;
12 e1
= container_of(entry1
, const struct strmap_entry
, ent
);
13 e2
= container_of(entry2
, const struct strmap_entry
, ent
);
14 return strcmp(e1
->key
, e2
->key
);
17 static struct strmap_entry
*find_strmap_entry(struct strmap
*map
,
20 struct strmap_entry entry
;
21 hashmap_entry_init(&entry
.ent
, strhash(str
));
23 return hashmap_get_entry(&map
->map
, &entry
, ent
, NULL
);
26 void strmap_init(struct strmap
*map
)
28 strmap_init_with_options(map
, NULL
, 1);
31 void strmap_init_with_options(struct strmap
*map
,
32 struct mem_pool
*pool
,
35 hashmap_init(&map
->map
, cmp_strmap_entry
, NULL
, 0);
37 map
->strdup_strings
= strdup_strings
;
40 static void strmap_free_entries_(struct strmap
*map
, int free_values
)
42 struct hashmap_iter iter
;
43 struct strmap_entry
*e
;
48 if (!free_values
&& map
->pool
)
49 /* Memory other than util is owned by and freed with the pool */
53 * We need to iterate over the hashmap entries and free
54 * e->key and e->value ourselves; hashmap has no API to
55 * take care of that for us. Since we're already iterating over
56 * the hashmap, though, might as well free e too and avoid the need
57 * to make some call into the hashmap API to do that.
59 hashmap_for_each_entry(&map
->map
, &iter
, e
, ent
) {
67 void strmap_clear(struct strmap
*map
, int free_values
)
69 strmap_free_entries_(map
, free_values
);
70 hashmap_clear(&map
->map
);
73 void strmap_partial_clear(struct strmap
*map
, int free_values
)
75 strmap_free_entries_(map
, free_values
);
76 hashmap_partial_clear(&map
->map
);
79 static struct strmap_entry
*create_entry(struct strmap
*map
,
83 struct strmap_entry
*entry
;
85 if (map
->strdup_strings
) {
87 FLEXPTR_ALLOC_STR(entry
, key
, str
);
89 size_t len
= st_add(strlen(str
), 1); /* include NUL */
90 entry
= mem_pool_alloc(map
->pool
,
91 st_add(sizeof(*entry
), len
));
92 memcpy(entry
+ 1, str
, len
);
93 entry
->key
= (void *)(entry
+ 1);
95 } else if (!map
->pool
) {
96 entry
= xmalloc(sizeof(*entry
));
98 entry
= mem_pool_alloc(map
->pool
, sizeof(*entry
));
100 hashmap_entry_init(&entry
->ent
, strhash(str
));
101 if (!map
->strdup_strings
)
107 void *strmap_put(struct strmap
*map
, const char *str
, void *data
)
109 struct strmap_entry
*entry
= find_strmap_entry(map
, str
);
112 void *old
= entry
->value
;
117 entry
= create_entry(map
, str
, data
);
118 hashmap_add(&map
->map
, &entry
->ent
);
122 struct strmap_entry
*strmap_get_entry(struct strmap
*map
, const char *str
)
124 return find_strmap_entry(map
, str
);
127 void *strmap_get(struct strmap
*map
, const char *str
)
129 struct strmap_entry
*entry
= find_strmap_entry(map
, str
);
130 return entry
? entry
->value
: NULL
;
133 int strmap_contains(struct strmap
*map
, const char *str
)
135 return find_strmap_entry(map
, str
) != NULL
;
138 void strmap_remove(struct strmap
*map
, const char *str
, int free_value
)
140 struct strmap_entry entry
, *ret
;
141 hashmap_entry_init(&entry
.ent
, strhash(str
));
143 ret
= hashmap_remove_entry(&map
->map
, &entry
, ent
, NULL
);
152 void strintmap_incr(struct strintmap
*map
, const char *str
, intptr_t amt
)
154 struct strmap_entry
*entry
= find_strmap_entry(&map
->map
, str
);
156 intptr_t *whence
= (intptr_t*)&entry
->value
;
160 strintmap_set(map
, str
, map
->default_value
+ amt
);
163 int strset_add(struct strset
*set
, const char *str
)
166 * Cannot use strmap_put() because it'll return NULL in both cases:
167 * - cannot find str: NULL means "not found"
168 * - does find str: NULL is the value associated with str
170 struct strmap_entry
*entry
= find_strmap_entry(&set
->map
, str
);
175 entry
= create_entry(&set
->map
, str
, NULL
);
176 hashmap_add(&set
->map
.map
, &entry
->ent
);