diff --git a/include/irc_dictionary.h b/include/irc_dictionary.h index e5dd6a744..eaf4d7f75 100644 --- a/include/irc_dictionary.h +++ b/include/irc_dictionary.h @@ -149,5 +149,6 @@ extern void *irc_dictionary_delete(struct Dictionary *dtree, const char *key); extern unsigned int irc_dictionary_size(struct Dictionary *dtree); void irc_dictionary_stats(struct Dictionary *dict, void (*cb)(const char *line, void *privdata), void *privdata); +void irc_dictionary_stats_walk(void (*cb)(const char *line, void *privdata), void *privdata); #endif diff --git a/ircd/irc_dictionary.c b/ircd/irc_dictionary.c index 8bfd4ad88..351a46d09 100644 --- a/ircd/irc_dictionary.c +++ b/ircd/irc_dictionary.c @@ -37,8 +37,12 @@ struct Dictionary unsigned int count; char *id; unsigned int dirty:1; + + rb_dlink_node node; }; +static rb_dlink_list dictionary_list = {NULL, NULL, 0}; + /* * irc_dictionary_create(const char *name, DCF compare_cb) * @@ -63,6 +67,8 @@ struct Dictionary *irc_dictionary_create(const char *name, dtree->compare_cb = compare_cb; dtree->id = rb_strdup(name); + rb_dlinkAdd(dtree, &dtree->node, &dictionary_list); + return dtree; } @@ -444,6 +450,8 @@ void irc_dictionary_destroy(struct Dictionary *dtree, rb_free(n); } + rb_dlinkDelete(&dtree->node, &dictionary_list); + rb_free(dtree); } @@ -818,16 +826,19 @@ void irc_dictionary_stats(struct Dictionary *dict, void (*cb)(const char *line, s_assert(dict != NULL); - if (dict->id != NULL) - rb_snprintf(str, sizeof str, "Dictionary stats for %s (%d)", - dict->id, dict->count); - else - rb_snprintf(str, sizeof str, "Dictionary stats for <%p> (%d)", - (void *)dict, dict->count); cb(str, privdata); maxdepth = 0; sum = stats_recurse(dict->root, 0, &maxdepth); - rb_snprintf(str, sizeof str, "Depth sum %d Avg depth %d Max depth %d", sum, sum / dict->count, maxdepth); + rb_snprintf(str, sizeof str, "%s: Objects: %d, Depth sum: %d, Avg depth: %d, Max depth: %d.", dict->id, dict->count, sum, sum / dict->count, maxdepth); cb(str, privdata); - return; +} + +void irc_dictionary_stats_walk(void (*cb)(const char *line, void *privdata), void *privdata) +{ + rb_dlink_node *ptr; + + RB_DLINK_FOREACH(ptr, dictionary_list.head) + { + irc_dictionary_stats(ptr->data, cb, privdata); + } } diff --git a/modules/m_stats.c b/modules/m_stats.c index c37bd6b33..6e3c842c7 100644 --- a/modules/m_stats.c +++ b/modules/m_stats.c @@ -272,10 +272,22 @@ stats_delay(struct Client *source_p) } } +static void +stats_hash_cb(const char *buf, void *client_p) +{ + sendto_one_numeric(client_p, RPL_STATSDEBUG, "B :%s", buf); +} + static void stats_hash(struct Client *source_p) { hash_stats(source_p); + + sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :Dictionary stats:"); + irc_dictionary_stats_walk(stats_hash_cb, source_p); + + sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :Radix tree stats:"); + irc_radixtree_stats_walk(stats_hash_cb, source_p); } static void