summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorXavier Roche <xroche@users.noreply.github.com>2014-05-14 17:45:51 +0000
committerXavier Roche <xroche@users.noreply.github.com>2014-05-14 17:45:51 +0000
commit7323230eb3c8fc4818d0cf34974497b3782a7279 (patch)
treee4026d34f6009bd06ce6f6bc232863eb63d232ed /src
parentc9f656fdeb0d762bbfc678121bc850a4c0bae7ca (diff)
Added debug logging facility.
Diffstat (limited to 'src')
-rw-r--r--src/htsinthash.c73
-rw-r--r--src/htsinthash.h18
2 files changed, 90 insertions, 1 deletions
diff --git a/src/htsinthash.c b/src/htsinthash.c
index 6e32aee..a14f37e 100644
--- a/src/htsinthash.c
+++ b/src/htsinthash.c
@@ -187,6 +187,16 @@ struct struct_inthash {
/** hashtable name for logging **/
const char *name;
} error;
+
+ /** How to handle pretty-print (debug) (might be NULL). **/
+ struct {
+ /** key print() **/
+ t_inthash_printkeyhandler key;
+ /** value print() **/
+ t_inthash_printvaluehandler value;
+ /** opaque argument **/
+ void *arg;
+ } print;
} custom;
};
@@ -889,10 +899,59 @@ static int inthash_add_item_(inthash hashtable, inthash_item item) {
(int) hashtable->stash.size);
return 1; /* added */
} else {
+ /* debugging */
+ if (hashtable->custom.print.key != NULL
+ && hashtable->custom.print.value != NULL) {
+ size_t i;
+ for(i = 0 ; i < hashtable->stash.size ; i++) {
+ inthash_item *const item = &hashtable->stash.items[i];
+ const size_t pos1 = inthash_hash_to_pos(hashtable, item->hashes.hash1);
+ const size_t pos2 = inthash_hash_to_pos(hashtable, item->hashes.hash2);
+ inthash_crit(hashtable, "stash[%u]: key='%s' value='%s' pos1=%d pos2=%d hash1=%04x hash2=%04x",
+ (int) i,
+ hashtable->custom.print.key(hashtable->custom.print.arg, item->name),
+ hashtable->custom.print.value(hashtable->custom.print.arg, item->value.ptr),
+ (int) pos1, (int) pos2,
+ item->hashes.hash1, item->hashes.hash2);
+ if (!inthash_is_free(hashtable, pos1)) {
+ inthash_item *const item = &hashtable->items[pos1];
+ const size_t pos1 = inthash_hash_to_pos(hashtable, item->hashes.hash1);
+ const size_t pos2 = inthash_hash_to_pos(hashtable, item->hashes.hash2);
+ inthash_crit(hashtable, "\t.. collisionning with key='%s' value='%s' pos1=%d pos2=%d hash1=%04x hash2=%04x",
+ hashtable->custom.print.key(hashtable->custom.print.arg, item->name),
+ hashtable->custom.print.value(hashtable->custom.print.arg, item->value.ptr),
+ (int) pos1, (int) pos2,
+ item->hashes.hash1, item->hashes.hash2);
+ } else {
+ inthash_crit(hashtable, "\t.. collisionning with a free slot (%d)!", (int) pos1);
+ }
+ if (!inthash_is_free(hashtable, pos2)) {
+ inthash_item *const item = &hashtable->items[pos2];
+ const size_t pos1 = inthash_hash_to_pos(hashtable, item->hashes.hash1);
+ const size_t pos2 = inthash_hash_to_pos(hashtable, item->hashes.hash2);
+ inthash_crit(hashtable, "\t.. collisionning with key='%s' value='%s' pos1=%d pos2=%d hash1=%04x hash2=%04x",
+ hashtable->custom.print.key(hashtable->custom.print.arg, item->name),
+ hashtable->custom.print.value(hashtable->custom.print.arg, item->value.ptr),
+ (int) pos1, (int) pos2,
+ item->hashes.hash1, item->hashes.hash2);
+ } else {
+ inthash_crit(hashtable, "\t.. collisionning with a free slot (%d)!", (int) pos2);
+ }
+ }
+ //struct_inthash_enum e = inthash_enum_new(hashtable);
+ //while((item = inthash_enum_next(&e)) != NULL) {
+ // inthash_crit(hashtable, "element key='%s' value='%s' hash1=%04x hash2=%04x",
+ // hashtable->custom.print.key(hashtable->custom.print.arg, item->name),
+ // hashtable->custom.print.value(hashtable->custom.print.arg, item->value.ptr),
+ // item->hashes.hash1, item->hashes.hash2);
+ //}
+ }
+
/* we are doomed. hopefully the probability is lower than being killed
by a wandering radioactive monkey */
inthash_log_stats(hashtable);
inthash_assert(hashtable, ! "hashtable internal error: cuckoo/stash collision");
+
/* not reachable code */
return -1;
}
@@ -1235,9 +1294,13 @@ inthash inthash_new(size_t initial_size) {
hashtable->custom.key.hash = NULL;
hashtable->custom.key.equals = NULL;
hashtable->custom.key.arg = NULL;
+ hashtable->custom.error.log = NULL;
hashtable->custom.error.fatal = NULL;
hashtable->custom.error.name = NULL;
hashtable->custom.error.arg = NULL;
+ hashtable->custom.print.key = NULL;
+ hashtable->custom.print.value = NULL;
+ hashtable->custom.print.arg = NULL;
}
return hashtable;
}
@@ -1288,12 +1351,20 @@ void inthash_set_assert_handler(inthash hashtable,
t_inthash_loghandler log,
t_inthash_asserthandler fatal,
void *arg) {
- inthash_assert(hashtable, fatal != NULL);
hashtable->custom.error.log = log;
hashtable->custom.error.fatal = fatal;
hashtable->custom.error.arg = arg;
}
+void inthash_set_print_handler(inthash hashtable,
+ t_inthash_printkeyhandler key,
+ t_inthash_printvaluehandler value,
+ void *arg) {
+ hashtable->custom.print.key = key;
+ hashtable->custom.print.value = value;
+ hashtable->custom.print.arg = arg;
+}
+
size_t inthash_nitems(inthash hashtable) {
if (hashtable != NULL)
return hashtable->used;
diff --git a/src/htsinthash.h b/src/htsinthash.h
index 7150911..f8aee07 100644
--- a/src/htsinthash.h
+++ b/src/htsinthash.h
@@ -141,6 +141,12 @@ typedef void (*t_inthash_loghandler)(void *arg, inthash_loglevel level,
/** Hashtable fatal assertion failure. **/
typedef void (*t_inthash_asserthandler)(void *arg, const char* exp, const char* file, int line);
+/** Key printer (debug) **/
+typedef const char* (*t_inthash_printkeyhandler)(void *arg, const char *name);
+
+/** Value printer (debug) **/
+typedef const char* (*t_inthash_printvaluehandler)(void *arg, void *value);
+
/**
* Value comparison handler (returns non-zero value if strings are equal).
**/
@@ -242,6 +248,18 @@ void inthash_set_assert_handler(inthash hashtable,
void *arg);
/**
+ * Set pretty print loggers (debug). Both handlers must return a string
+ * pointer which shall be valid until the next call. Both key and value
+ * pointers shall be valid at the same time.
+ * name: handler called to print the string representation of the name
+ * value: handler called to print the string representation of the value
+ **/
+void inthash_set_print_handler(inthash hashtable,
+ t_inthash_printkeyhandler key,
+ t_inthash_printvaluehandler value,
+ void *arg);
+
+/**
* Set the hashtable name, for degugging purpose.
* name: the hashtable name (ASCII or UTF-8)
*/