[utils] some convenience functions for generic hashtables (incr, get, etc)
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
// Maps
|
||||
|
||||
KHASH_MAP_INIT_INT(int_uint32, uint32_t)
|
||||
KHASH_MAP_INIT_INT64(int64_uint32, uint32_t)
|
||||
|
||||
#define kh_char_hash_func(key) (uint32_t)(key)
|
||||
#define kh_char_hash_equal(a, b) ((a) == (b))
|
||||
@@ -33,6 +34,7 @@ KHASH_MAP_INIT_STR(str_str, char *)
|
||||
// Sets
|
||||
|
||||
KHASH_SET_INIT_INT(int_set)
|
||||
KHASH_SET_INIT_INT64(int64_set)
|
||||
KHASH_SET_INIT_STR(str_set)
|
||||
|
||||
// Vectors
|
||||
@@ -84,4 +86,115 @@ KSORT_INIT_STR
|
||||
KHASH_SORT_BY_VALUE(str_uint32, char *, uint32_t, uint32_array)
|
||||
KHASH_SORT_BY_VALUE(str_double, char *, double, double_array)
|
||||
|
||||
#define KHASH_STR_GET(name, key_type, val_type) \
|
||||
static bool name##_hash_get(khash_t(name) *h, key_type *key, val_type *val) { \
|
||||
khiter_t k; \
|
||||
k = kh_get(name, h, (const key_type)key); \
|
||||
if (k != kh_end(h)) { \
|
||||
*val = kh_value(h, k); \
|
||||
return true; \
|
||||
} \
|
||||
return false; \
|
||||
}
|
||||
|
||||
KHASH_STR_GET(str_uint32, kh_cstr_t, uint32_t)
|
||||
|
||||
#define KHASH_STR_INCR(name, val_type) \
|
||||
static bool name##_hash_incr_by_exists(khash_t(name) *h, const char *key, val_type val, bool *exists) { \
|
||||
khiter_t k; \
|
||||
int ret = 0; \
|
||||
k = kh_get(name, h, key); \
|
||||
if (k == kh_end(h)) { \
|
||||
char *key_copy = strdup(key); \
|
||||
if (key_copy == NULL) { \
|
||||
return false; \
|
||||
} \
|
||||
k = kh_put(name, h, key_copy, &ret); \
|
||||
if (ret < 0) { \
|
||||
free(key_copy); \
|
||||
return false; \
|
||||
} \
|
||||
kh_value(h, k) = (val_type)0; \
|
||||
*exists = false; \
|
||||
} else { \
|
||||
*exists = true; \
|
||||
} \
|
||||
kh_value(h, k) += val; \
|
||||
return true; \
|
||||
} \
|
||||
static bool name##_hash_incr_exists(khash_t(name) *h, const char *key, bool *exists) { \
|
||||
return name##_hash_incr_by_exists(h, key, (val_type)1, exists); \
|
||||
} \
|
||||
static bool name##_hash_incr_by(khash_t(name) *h, const char *key, val_type val) { \
|
||||
bool exists = false; \
|
||||
return name##_hash_incr_by_exists(h, key, val, &exists); \
|
||||
} \
|
||||
static bool name##_hash_incr(khash_t(name) *h, const char *key) { \
|
||||
bool exists = false; \
|
||||
return name##_hash_incr_by_exists(h, key, (val_type)1, &exists); \
|
||||
}
|
||||
|
||||
KHASH_STR_INCR(str_uint32, uint32_t)
|
||||
|
||||
#define KHASH_STR_TO_ID(name, val_type) \
|
||||
static bool name##_hash_to_id_exists(khash_t(name) *h, const char *key, val_type *val, bool *exists) { \
|
||||
khiter_t k; \
|
||||
int ret = 0; \
|
||||
k = kh_get(name, h, key); \
|
||||
if (k == kh_end(h)) { \
|
||||
char *key_copy = strdup(key); \
|
||||
if (key_copy == NULL) { \
|
||||
return false; \
|
||||
} \
|
||||
k = kh_put(name, h, key_copy, &ret); \
|
||||
if (ret < 0) { \
|
||||
free(key_copy); \
|
||||
return false; \
|
||||
} \
|
||||
kh_value(h, k) = (val_type)kh_size(h); \
|
||||
*exists = false; \
|
||||
} \
|
||||
*val = kh_value(h, k); \
|
||||
return true; \
|
||||
} \
|
||||
static bool name##_hash_to_id(khash_t(name) *h, const char *key, val_type *val) { \
|
||||
bool exists = false; \
|
||||
return name##_hash_to_id_exists(h, key, val, &exists); \
|
||||
}
|
||||
|
||||
KHASH_STR_TO_ID(str_uint32, uint32_t)
|
||||
|
||||
#define KHASH_INCR(name, key_type, val_type) \
|
||||
static bool name##_hash_incr_by_exists(khash_t(name) *h, key_type key, val_type val, bool *exists) { \
|
||||
khiter_t k; \
|
||||
int ret = 0; \
|
||||
k = kh_get(name, h, key); \
|
||||
if (k == kh_end(h)) { \
|
||||
k = kh_put(name, h, key, &ret); \
|
||||
if (ret < 0) { \
|
||||
return false; \
|
||||
} \
|
||||
kh_value(h, k) = (val_type)0; \
|
||||
*exists = false; \
|
||||
} else { \
|
||||
*exists = true; \
|
||||
} \
|
||||
kh_value(h, k) += val; \
|
||||
return true; \
|
||||
} \
|
||||
static bool name##_hash_incr_exists(khash_t(name) *h, key_type key, bool *exists) { \
|
||||
return name##_hash_incr_by_exists(h, key, (val_type)1, exists); \
|
||||
} \
|
||||
static bool name##_hash_incr_by(khash_t(name) *h, key_type key, val_type val) { \
|
||||
bool exists = false; \
|
||||
return name##_hash_incr_by_exists(h, key, val, &exists); \
|
||||
} \
|
||||
static bool name##_hash_incr(khash_t(name) *h, key_type key) { \
|
||||
bool exists = false; \
|
||||
return name##_hash_incr_by_exists(h, key, (val_type)1, &exists); \
|
||||
}
|
||||
|
||||
KHASH_INCR(int_uint32, khint32_t, uint32_t)
|
||||
KHASH_INCR(int64_uint32, khint64_t, uint32_t)
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user