diff options
-rw-r--r-- | src/htsinthash.c | 73 | ||||
-rw-r--r-- | src/htsinthash.h | 12 |
2 files changed, 58 insertions, 27 deletions
diff --git a/src/htsinthash.c b/src/htsinthash.c index 285b165..6e32aee 100644 --- a/src/htsinthash.c +++ b/src/htsinthash.c @@ -184,6 +184,8 @@ struct struct_inthash { t_inthash_asserthandler fatal; /** opaque argument **/ void *arg; + /** hashtable name for logging **/ + const char *name; } error; } custom; }; @@ -194,14 +196,14 @@ struct struct_inthash { /* Compiler-specific. */ #ifdef __GNUC__ -#define HTS_PRINTF_FUN(fmt, arg) __attribute__ ((format (printf, fmt, arg))) -#define HTS_INLINE __inline__ +#define INTHASH_PRINTF_FUN(fmt, arg) __attribute__ ((format (printf, fmt, arg))) +#define INTHASH_INLINE __inline__ #elif (defined(_MSC_VER)) -#define HTS_PRINTF_FUN(FMT, ARGS) -#define HTS_INLINE __inline +#define INTHASH_PRINTF_FUN(FMT, ARGS) +#define INTHASH_INLINE __inline #else -#define HTS_PRINTF_FUN(FMT, ARGS) -#define HTS_INLINE +#define INTHASH_PRINTF_FUN(FMT, ARGS) +#define INTHASH_INLINE #endif /* Logging level. */ @@ -209,7 +211,7 @@ static void inthash_log(const inthash hashtable, inthash_loglevel level, const char *format, va_list args); #define DECLARE_LOG_FUNCTION(NAME, LEVEL) \ static void NAME(const inthash hashtable, const char *format, ...) \ - HTS_PRINTF_FUN(2, 3); \ + INTHASH_PRINTF_FUN(2, 3); \ static void NAME(const inthash hashtable, const char *format, ...) { \ va_list args; \ va_start(args, format); \ @@ -260,6 +262,9 @@ static void inthash_fail(const char* exp, const char* file, int line) { /* assert failed handler. */ static void inthash_assert_failed(const inthash hashtable, const char* exp, const char* file, int line) { + const char *name = inthash_get_name(hashtable); + inthash_crit(hashtable, "hashtable %s: %s failed at %s:%d", + name != NULL ? name : "<unknown>", exp, file, line); if (hashtable != NULL && hashtable->custom.error.fatal != NULL) { hashtable->custom.error.fatal(hashtable->custom.error.arg, exp, file, line); } else if (global_assert_handler != NULL) { @@ -287,12 +292,17 @@ static void inthash_log(const inthash hashtable, inthash_loglevel level, /* No logging (should be dropped by the compiler) */ static void inthash_nolog(const inthash hashtable, const char *format, ...) - HTS_PRINTF_FUN(2, 3); + INTHASH_PRINTF_FUN(2, 3); static void inthash_nolog(const inthash hashtable, const char *format, ...) { } +const char* inthash_get_name(inthash hashtable) { + return hashtable->custom.error.name; +} + static void inthash_log_stats(inthash hashtable) { - inthash_info(hashtable, "hashtable summary: " + const char *name = inthash_get_name(hashtable); + inthash_info(hashtable, "hashtable %s%s%ssummary: " "size=%"UINT_64_FORMAT" (lg2=%"UINT_64_FORMAT") " "used=%"UINT_64_FORMAT" " "stash-size=%"UINT_64_FORMAT" " @@ -309,6 +319,9 @@ static void inthash_log_stats(inthash hashtable) { "pool-compact=%"UINT_64_FORMAT" " "pool-realloc=%"UINT_64_FORMAT" " "memory=%"UINT_64_FORMAT, + name != NULL ? "\"" : "", + name != NULL ? name : "", + name != NULL ? "\" " : "", (uint64_t) POW2(hashtable->lg_size), (uint64_t) hashtable->lg_size, (uint64_t) hashtable->used, @@ -410,39 +423,39 @@ inthash_keys inthash_hash_value(const char *value) { #endif } -static HTS_INLINE inthash_keys inthash_calc_hashes(inthash hashtable, - const char *value) { +static INTHASH_INLINE inthash_keys inthash_calc_hashes(inthash hashtable, + const char *value) { return hashtable->custom.key.hash == NULL ? inthash_hash_value(value) : hashtable->custom.key.hash(hashtable->custom.key.arg, value); } /* position 'pos' is free ? */ -static HTS_INLINE int inthash_is_free(const inthash hashtable, size_t pos) { +static INTHASH_INLINE int inthash_is_free(const inthash hashtable, size_t pos) { return hashtable->items[pos].name == NULL; } /* compare two keys ; by default using strcmp() */ -static HTS_INLINE int inthash_equals(inthash hashtable, - const char *a, const char *b) { +static INTHASH_INLINE int inthash_equals(inthash hashtable, + const char *a, const char *b) { return hashtable->custom.key.equals == NULL ? strcmp(a, b) == 0 : hashtable->custom.key.equals(hashtable->custom.key.arg, a, b); } -static HTS_INLINE int inthash_matches_(inthash hashtable, - const inthash_item *const item, - const char *name, - const inthash_keys *hashes) { +static INTHASH_INLINE int inthash_matches_(inthash hashtable, + const inthash_item *const item, + const char *name, + const inthash_keys *hashes) { return item->name != NULL && item->hashes.hash1 == hashes->hash1 && item->hashes.hash2 == hashes->hash2 && inthash_equals(hashtable, item->name, name); } -static HTS_INLINE int inthash_matches(inthash hashtable, size_t pos, - const char *name, - const inthash_keys *hashes) { +static INTHASH_INLINE int inthash_matches(inthash hashtable, size_t pos, + const char *name, + const inthash_keys *hashes) { const inthash_item *const item = &hashtable->items[pos]; return inthash_matches_(hashtable, item, name, hashes); } @@ -620,7 +633,7 @@ static char* inthash_dup_name_internal(inthash hashtable, const char *name) { } /* duplicate a key. default is to use the internal pool. */ -static HTS_INLINE char* inthash_dup_name(inthash hashtable, const char *name) { +static INTHASH_INLINE char* inthash_dup_name(inthash hashtable, const char *name) { return hashtable->custom.key.dup == NULL ? inthash_dup_name_internal(hashtable, name) : hashtable->custom.key.dup(hashtable->custom.key.arg, name); @@ -663,14 +676,14 @@ static void inthash_free_key(inthash hashtable, char *name) { } } -static HTS_INLINE size_t inthash_hash_to_pos_(size_t lg_size, - inthash_key hash) { +static INTHASH_INLINE size_t inthash_hash_to_pos_(size_t lg_size, + inthash_key hash) { const inthash_key mask = POW2(lg_size) - 1; return hash & mask; } -static HTS_INLINE size_t inthash_hash_to_pos(const inthash hashtable, - inthash_key hash) { +static INTHASH_INLINE size_t inthash_hash_to_pos(const inthash hashtable, + inthash_key hash) { return inthash_hash_to_pos_(hashtable->lg_size, hash); } @@ -919,7 +932,8 @@ int inthash_write_value(inthash hashtable, const char *name, && half_size > POW2(16) && hashtable->used < half_size / 4) { inthash_warning(hashtable, - "stash size still full despite %"UINT_64_FORMAT" elements used out of %"UINT_64_FORMAT, + "stash size still full despite %"UINT_64_FORMAT + " elements used out of %"UINT_64_FORMAT, hashtable->used, half_size*2); } @@ -1222,6 +1236,7 @@ inthash inthash_new(size_t initial_size) { hashtable->custom.key.equals = NULL; hashtable->custom.key.arg = NULL; hashtable->custom.error.fatal = NULL; + hashtable->custom.error.name = NULL; hashtable->custom.error.arg = NULL; } return hashtable; @@ -1243,6 +1258,10 @@ void inthash_value_is_malloc(inthash hashtable, int flag) { } } +void inthash_set_name(inthash hashtable, const char *name) { + hashtable->custom.error.name = name; +} + void inthash_value_set_value_handler(inthash hashtable, t_inthash_freehandler free, void *arg) { diff --git a/src/htsinthash.h b/src/htsinthash.h index 248a697..037e25d 100644 --- a/src/htsinthash.h +++ b/src/htsinthash.h @@ -241,6 +241,18 @@ void inthash_set_assert_handler(inthash hashtable, void *arg); /** + * Set the hashtable name, for degugging purpose. + * name: the hashtable name (ASCII or UTF-8) + */ +void inthash_set_name(inthash hashtable, const char *name); + +/** + * Get the hashtable name, for degugging purpose. + * Return NULL if no name was defined. + **/ +const char* inthash_get_name(inthash hashtable); + +/** * Read an integer entry from the hashtable. * Return non-zero value upon success and sets intvalue. **/ |