Skip to content

Commit 4fa1d50

Browse files
newrengitster
authored andcommitted
strmap: add functions facilitating use as a string->int map
Although strmap could be used as a string->int map, one either had to allocate an int for every entry and then deallocate later, or one had to do a bunch of casting between (void*) and (intptr_t). Add some special functions that do the casting. Also, rename put->set for such wrapper functions since 'put' implied there may be some deallocation needed if the string was already found in the map, which isn't the case when we're storing an int value directly in the void* slot instead of using the void* slot as a pointer to data. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6ccdfc2 commit 4fa1d50

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

strmap.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,14 @@ void strmap_remove(struct strmap *map, const char *str, int free_value)
123123
free((char*)ret->key);
124124
free(ret);
125125
}
126+
127+
void strintmap_incr(struct strintmap *map, const char *str, intptr_t amt)
128+
{
129+
struct strmap_entry *entry = find_strmap_entry(&map->map, str);
130+
if (entry) {
131+
intptr_t *whence = (intptr_t*)&entry->value;
132+
*whence += amt;
133+
}
134+
else
135+
strintmap_set(map, str, map->default_value + amt);
136+
}

strmap.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ int cmp_strmap_entry(const void *hashmap_cmp_fn_data,
2323
.map = HASHMAP_INIT(cmp_strmap_entry, NULL), \
2424
.strdup_strings = 1, \
2525
}
26+
#define STRINTMAP_INIT { \
27+
.map = STRMAP_INIT, \
28+
.default_value = 0, \
29+
}
2630

2731
/*
2832
* Initialize the members of the strmap. Any keys added to the strmap will
@@ -102,4 +106,94 @@ static inline int strmap_empty(struct strmap *map)
102106
#define strmap_for_each_entry(mystrmap, iter, var) \
103107
hashmap_for_each_entry(&(mystrmap)->map, iter, var, ent)
104108

109+
110+
/*
111+
* strintmap:
112+
* A map of string -> int, typecasting the void* of strmap to an int.
113+
*
114+
* Primary differences:
115+
* 1) Since the void* value is just an int in disguise, there is no value
116+
* to free. (Thus one fewer argument to strintmap_clear)
117+
* 2) strintmap_get() returns an int, or returns the default_value if the
118+
* key is not found in the strintmap.
119+
* 3) No strmap_put() equivalent; strintmap_set() and strintmap_incr()
120+
* instead.
121+
*/
122+
123+
struct strintmap {
124+
struct strmap map;
125+
int default_value;
126+
};
127+
128+
#define strintmap_for_each_entry(mystrmap, iter, var) \
129+
strmap_for_each_entry(&(mystrmap)->map, iter, var)
130+
131+
static inline void strintmap_init(struct strintmap *map, int default_value)
132+
{
133+
strmap_init(&map->map);
134+
map->default_value = default_value;
135+
}
136+
137+
static inline void strintmap_init_with_options(struct strintmap *map,
138+
int default_value,
139+
int strdup_strings)
140+
{
141+
strmap_init_with_options(&map->map, strdup_strings);
142+
map->default_value = default_value;
143+
}
144+
145+
static inline void strintmap_clear(struct strintmap *map)
146+
{
147+
strmap_clear(&map->map, 0);
148+
}
149+
150+
static inline void strintmap_partial_clear(struct strintmap *map)
151+
{
152+
strmap_partial_clear(&map->map, 0);
153+
}
154+
155+
static inline int strintmap_contains(struct strintmap *map, const char *str)
156+
{
157+
return strmap_contains(&map->map, str);
158+
}
159+
160+
static inline void strintmap_remove(struct strintmap *map, const char *str)
161+
{
162+
return strmap_remove(&map->map, str, 0);
163+
}
164+
165+
static inline int strintmap_empty(struct strintmap *map)
166+
{
167+
return strmap_empty(&map->map);
168+
}
169+
170+
static inline unsigned int strintmap_get_size(struct strintmap *map)
171+
{
172+
return strmap_get_size(&map->map);
173+
}
174+
175+
/*
176+
* Returns the value for str in the map. If str isn't found in the map,
177+
* the map's default_value is returned.
178+
*/
179+
static inline int strintmap_get(struct strintmap *map, const char *str)
180+
{
181+
struct strmap_entry *result = strmap_get_entry(&map->map, str);
182+
if (!result)
183+
return map->default_value;
184+
return (intptr_t)result->value;
185+
}
186+
187+
static inline void strintmap_set(struct strintmap *map, const char *str,
188+
intptr_t v)
189+
{
190+
strmap_put(&map->map, str, (void *)v);
191+
}
192+
193+
/*
194+
* Increment the value for str by amt. If str isn't in the map, add it and
195+
* set its value to default_value + amt.
196+
*/
197+
void strintmap_incr(struct strintmap *map, const char *str, intptr_t amt);
198+
105199
#endif /* STRMAP_H */

0 commit comments

Comments
 (0)