Git fork
at reftables-rust 268 lines 6.9 kB view raw
1#ifndef STRMAP_H 2#define STRMAP_H 3 4#include "hashmap.h" 5 6struct mem_pool; 7struct strmap { 8 struct hashmap map; 9 struct mem_pool *pool; 10 unsigned int strdup_strings:1; 11}; 12 13struct strmap_entry { 14 struct hashmap_entry ent; 15 const char *key; 16 void *value; 17 /* strmap_entry may be allocated extra space to store the key at end */ 18}; 19 20int cmp_strmap_entry(const void *hashmap_cmp_fn_data, 21 const struct hashmap_entry *entry1, 22 const struct hashmap_entry *entry2, 23 const void *keydata); 24 25#define STRMAP_INIT { \ 26 .map = HASHMAP_INIT(cmp_strmap_entry, NULL), \ 27 .strdup_strings = 1, \ 28 } 29#define STRINTMAP_INIT { \ 30 .map = STRMAP_INIT, \ 31 .default_value = 0, \ 32 } 33#define STRSET_INIT { .map = STRMAP_INIT } 34 35/* 36 * Initialize the members of the strmap. Any keys added to the strmap will 37 * be strdup'ed with their memory managed by the strmap. 38 */ 39void strmap_init(struct strmap *map); 40 41/* 42 * Same as strmap_init, but for those who want to control the memory management 43 * carefully instead of using the default of strdup_strings=1 and pool=NULL. 44 */ 45void strmap_init_with_options(struct strmap *map, 46 struct mem_pool *pool, 47 int strdup_strings); 48 49/* 50 * Remove all entries from the map, releasing any allocated resources. 51 */ 52void strmap_clear(struct strmap *map, int free_values); 53 54/* 55 * Similar to strmap_clear() but leaves map->map->table allocated and 56 * pre-sized so that subsequent uses won't need as many rehashings. 57 */ 58void strmap_partial_clear(struct strmap *map, int free_values); 59 60/* 61 * Insert "str" into the map, pointing to "data". 62 * 63 * If an entry for "str" already exists, its data pointer is overwritten, and 64 * the original data pointer returned. Otherwise, returns NULL. 65 */ 66void *strmap_put(struct strmap *map, const char *str, void *data); 67 68/* 69 * Return the strmap_entry mapped by "str", or NULL if there is not such 70 * an item in map. 71 */ 72struct strmap_entry *strmap_get_entry(struct strmap *map, const char *str); 73 74/* 75 * Return the data pointer mapped by "str", or NULL if the entry does not 76 * exist. 77 */ 78void *strmap_get(struct strmap *map, const char *str); 79 80/* 81 * Return non-zero iff "str" is present in the map. This differs from 82 * strmap_get() in that it can distinguish entries with a NULL data pointer. 83 */ 84int strmap_contains(struct strmap *map, const char *str); 85 86/* 87 * Remove the given entry from the strmap. If the string isn't in the 88 * strmap, the map is not altered. 89 */ 90void strmap_remove(struct strmap *map, const char *str, int free_value); 91 92/* 93 * Return how many entries the strmap has. 94 */ 95static inline unsigned int strmap_get_size(struct strmap *map) 96{ 97 return hashmap_get_size(&map->map); 98} 99 100/* 101 * Return whether the strmap is empty. 102 */ 103static inline int strmap_empty(struct strmap *map) 104{ 105 return strmap_get_size(map) == 0; 106} 107 108/* 109 * iterate through @map using @iter, @var is a pointer to a type strmap_entry 110 */ 111#define strmap_for_each_entry(mystrmap, iter, var) \ 112 hashmap_for_each_entry(&(mystrmap)->map, iter, var, ent) 113 114 115/* 116 * strintmap: 117 * A map of string -> int, typecasting the void* of strmap to an int. 118 * 119 * Primary differences: 120 * 1) Since the void* value is just an int in disguise, there is no value 121 * to free. (Thus one fewer argument to strintmap_clear) 122 * 2) strintmap_get() returns an int, or returns the default_value if the 123 * key is not found in the strintmap. 124 * 3) No strmap_put() equivalent; strintmap_set() and strintmap_incr() 125 * instead. 126 */ 127 128struct strintmap { 129 struct strmap map; 130 int default_value; 131}; 132 133#define strintmap_for_each_entry(mystrmap, iter, var) \ 134 strmap_for_each_entry(&(mystrmap)->map, iter, var) 135 136static inline void strintmap_init(struct strintmap *map, int default_value) 137{ 138 strmap_init(&map->map); 139 map->default_value = default_value; 140} 141 142static inline void strintmap_init_with_options(struct strintmap *map, 143 int default_value, 144 struct mem_pool *pool, 145 int strdup_strings) 146{ 147 strmap_init_with_options(&map->map, pool, strdup_strings); 148 map->default_value = default_value; 149} 150 151static inline void strintmap_clear(struct strintmap *map) 152{ 153 strmap_clear(&map->map, 0); 154} 155 156static inline void strintmap_partial_clear(struct strintmap *map) 157{ 158 strmap_partial_clear(&map->map, 0); 159} 160 161static inline int strintmap_contains(struct strintmap *map, const char *str) 162{ 163 return strmap_contains(&map->map, str); 164} 165 166static inline void strintmap_remove(struct strintmap *map, const char *str) 167{ 168 strmap_remove(&map->map, str, 0); 169} 170 171static inline int strintmap_empty(struct strintmap *map) 172{ 173 return strmap_empty(&map->map); 174} 175 176static inline unsigned int strintmap_get_size(struct strintmap *map) 177{ 178 return strmap_get_size(&map->map); 179} 180 181/* 182 * Returns the value for str in the map. If str isn't found in the map, 183 * the map's default_value is returned. 184 */ 185static inline int strintmap_get(struct strintmap *map, const char *str) 186{ 187 struct strmap_entry *result = strmap_get_entry(&map->map, str); 188 if (!result) 189 return map->default_value; 190 return (intptr_t)result->value; 191} 192 193static inline void strintmap_set(struct strintmap *map, const char *str, 194 intptr_t v) 195{ 196 strmap_put(&map->map, str, (void *)v); 197} 198 199/* 200 * Increment the value for str by amt. If str isn't in the map, add it and 201 * set its value to default_value + amt. 202 */ 203void strintmap_incr(struct strintmap *map, const char *str, intptr_t amt); 204 205/* 206 * strset: 207 * A set of strings. 208 * 209 * Primary differences with strmap: 210 * 1) The value is always NULL, and ignored. As there is no value to free, 211 * there is one fewer argument to strset_clear 212 * 2) No strset_get() because there is no value. 213 * 3) No strset_put(); use strset_add() instead. 214 */ 215 216struct strset { 217 struct strmap map; 218}; 219 220#define strset_for_each_entry(mystrset, iter, var) \ 221 strmap_for_each_entry(&(mystrset)->map, iter, var) 222 223static inline void strset_init(struct strset *set) 224{ 225 strmap_init(&set->map); 226} 227 228static inline void strset_init_with_options(struct strset *set, 229 struct mem_pool *pool, 230 int strdup_strings) 231{ 232 strmap_init_with_options(&set->map, pool, strdup_strings); 233} 234 235static inline void strset_clear(struct strset *set) 236{ 237 strmap_clear(&set->map, 0); 238} 239 240static inline void strset_partial_clear(struct strset *set) 241{ 242 strmap_partial_clear(&set->map, 0); 243} 244 245static inline int strset_contains(struct strset *set, const char *str) 246{ 247 return strmap_contains(&set->map, str); 248} 249 250static inline void strset_remove(struct strset *set, const char *str) 251{ 252 strmap_remove(&set->map, str, 0); 253} 254 255static inline int strset_empty(struct strset *set) 256{ 257 return strmap_empty(&set->map); 258} 259 260static inline unsigned int strset_get_size(struct strset *set) 261{ 262 return strmap_get_size(&set->map); 263} 264 265/* Returns 1 if str is added to the set; returns 0 if str was already in set */ 266int strset_add(struct strset *set, const char *str); 267 268#endif /* STRMAP_H */