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 struct strmap blank
= STRMAP_INIT
;
29 memcpy(map
, &blank
, sizeof(*map
));
32 void strmap_init_with_options(struct strmap
*map
,
33 struct mem_pool
*pool
,
36 hashmap_init(&map
->map
, cmp_strmap_entry
, NULL
, 0);
38 map
->strdup_strings
= strdup_strings
;
41 static void strmap_free_entries_(struct strmap
*map
, int free_values
)
43 struct hashmap_iter iter
;
44 struct strmap_entry
*e
;
49 if (!free_values
&& map
->pool
)
50 /* Memory other than util is owned by and freed with the pool */
54 * We need to iterate over the hashmap entries and free
55 * e->key and e->value ourselves; hashmap has no API to
56 * take care of that for us. Since we're already iterating over
57 * the hashmap, though, might as well free e too and avoid the need
58 * to make some call into the hashmap API to do that.
60 hashmap_for_each_entry(&map
->map
, &iter
, e
, ent
) {
68 void strmap_clear(struct strmap
*map
, int free_values
)
70 strmap_free_entries_(map
, free_values
);
71 hashmap_clear(&map
->map
);
74 void strmap_partial_clear(struct strmap
*map
, int free_values
)
76 strmap_free_entries_(map
, free_values
);
77 hashmap_partial_clear(&map
->map
);
80 static struct strmap_entry
*create_entry(struct strmap
*map
,
84 struct strmap_entry
*entry
;
86 if (map
->strdup_strings
) {
88 FLEXPTR_ALLOC_STR(entry
, key
, str
);
90 size_t len
= st_add(strlen(str
), 1); /* include NUL */
91 entry
= mem_pool_alloc(map
->pool
,
92 st_add(sizeof(*entry
), len
));
93 memcpy(entry
+ 1, str
, len
);
94 entry
->key
= (void *)(entry
+ 1);
96 } else if (!map
->pool
) {
97 entry
= xmalloc(sizeof(*entry
));
99 entry
= mem_pool_alloc(map
->pool
, sizeof(*entry
));
101 hashmap_entry_init(&entry
->ent
, strhash(str
));
102 if (!map
->strdup_strings
)
108 void *strmap_put(struct strmap
*map
, const char *str
, void *data
)
110 struct strmap_entry
*entry
= find_strmap_entry(map
, str
);
113 void *old
= entry
->value
;
118 entry
= create_entry(map
, str
, data
);
119 hashmap_add(&map
->map
, &entry
->ent
);
123 struct strmap_entry
*strmap_get_entry(struct strmap
*map
, const char *str
)
125 return find_strmap_entry(map
, str
);
128 void *strmap_get(struct strmap
*map
, const char *str
)
130 struct strmap_entry
*entry
= find_strmap_entry(map
, str
);
131 return entry
? entry
->value
: NULL
;
134 int strmap_contains(struct strmap
*map
, const char *str
)
136 return find_strmap_entry(map
, str
) != NULL
;
139 void strmap_remove(struct strmap
*map
, const char *str
, int free_value
)
141 struct strmap_entry entry
, *ret
;
142 hashmap_entry_init(&entry
.ent
, strhash(str
));
144 ret
= hashmap_remove_entry(&map
->map
, &entry
, ent
, NULL
);
153 void strintmap_incr(struct strintmap
*map
, const char *str
, intptr_t amt
)
155 struct strmap_entry
*entry
= find_strmap_entry(&map
->map
, str
);
157 intptr_t *whence
= (intptr_t*)&entry
->value
;
161 strintmap_set(map
, str
, map
->default_value
+ amt
);
164 int strset_add(struct strset
*set
, const char *str
)
167 * Cannot use strmap_put() because it'll return NULL in both cases:
168 * - cannot find str: NULL means "not found"
169 * - does find str: NULL is the value associated with str
171 struct strmap_entry
*entry
= find_strmap_entry(&set
->map
, str
);
176 entry
= create_entry(&set
->map
, str
, NULL
);
177 hashmap_add(&set
->map
.map
, &entry
->ent
);