ircd: irc_radixtree: add some convenience functions for tracking radix tree stats

This commit is contained in:
William Pitcock 2016-01-09 00:54:57 -06:00
parent 8e6ba6f9ce
commit 325cc939b7
2 changed files with 22 additions and 41 deletions

View file

@ -60,7 +60,7 @@ struct irc_radixtree_iteration_state
* compare_cb is the canonizing function. * compare_cb is the canonizing function.
*/ */
extern struct irc_radixtree *irc_radixtree_create(void (*canonize_cb)(char *key)); extern struct irc_radixtree *irc_radixtree_create(const char *name, void (*canonize_cb)(char *key));
/* /*
* irc_radixtree_shutdown() deallocates all heaps used in patricia trees. This is * irc_radixtree_shutdown() deallocates all heaps used in patricia trees. This is
@ -136,5 +136,6 @@ void *irc_radixtree_elem_get_data(struct irc_radixtree_leaf *elem);
unsigned int irc_radixtree_size(struct irc_radixtree *dict); unsigned int irc_radixtree_size(struct irc_radixtree *dict);
void irc_radixtree_stats(struct irc_radixtree *dict, void (*cb)(const char *line, void *privdata), void *privdata); void irc_radixtree_stats(struct irc_radixtree *dict, void (*cb)(const char *line, void *privdata), void *privdata);
void irc_radixtree_stats_walk(void (*cb)(const char *line, void *privdata), void *privdata);
#endif #endif

View file

@ -36,6 +36,8 @@
#include "s_assert.h" #include "s_assert.h"
#include "irc_radixtree.h" #include "irc_radixtree.h"
rb_dlink_list radixtree_list = {NULL, NULL, 0};
/* /*
* Patricia tree. * Patricia tree.
* *
@ -59,6 +61,8 @@ struct irc_radixtree
unsigned int count; unsigned int count;
char *id; char *id;
rb_dlink_node node;
}; };
#define POINTERS_PER_NODE 16 #define POINTERS_PER_NODE 16
@ -137,34 +141,6 @@ first_leaf(union irc_radixtree_elem *delem)
return delem; return delem;
} }
/*
* irc_radixtree_create(void (*canonize_cb)(char *key))
*
* Dictionary object factory.
*
* Inputs:
* - function to use for canonizing keys (for example, use
* a function that makes the string upper case to create
* a patricia with case-insensitive matching)
*
* Outputs:
* - on success, a new patricia object.
*
* Side Effects:
* - if services runs out of memory and cannot allocate the object,
* the program will abort.
*/
struct irc_radixtree *
irc_radixtree_create(void (*canonize_cb)(char *key))
{
struct irc_radixtree *dtree = (struct irc_radixtree *) rb_malloc(sizeof(struct irc_radixtree));
dtree->canonize_cb = canonize_cb;
dtree->root = NULL;
return dtree;
}
/* /*
* irc_radixtree_create_named(const char *name, * irc_radixtree_create_named(const char *name,
* void (*canonize_cb)(char *key)) * void (*canonize_cb)(char *key))
@ -185,7 +161,7 @@ irc_radixtree_create(void (*canonize_cb)(char *key))
* the program will abort. * the program will abort.
*/ */
struct irc_radixtree * struct irc_radixtree *
irc_radixtree_create_named(const char *name, void (*canonize_cb)(char *key)) irc_radixtree_create(const char *name, void (*canonize_cb)(char *key))
{ {
struct irc_radixtree *dtree = (struct irc_radixtree *) rb_malloc(sizeof(struct irc_radixtree)); struct irc_radixtree *dtree = (struct irc_radixtree *) rb_malloc(sizeof(struct irc_radixtree));
@ -193,6 +169,8 @@ irc_radixtree_create_named(const char *name, void (*canonize_cb)(char *key))
dtree->id = rb_strdup(name); dtree->id = rb_strdup(name);
dtree->root = NULL; dtree->root = NULL;
rb_dlinkAdd(dtree, &dtree->node, &radixtree_list);
return dtree; return dtree;
} }
@ -1053,26 +1031,28 @@ irc_radixtree_stats(struct irc_radixtree *dict, void (*cb)(const char *line, voi
s_assert(dict != NULL); s_assert(dict != NULL);
if (dict->id != NULL)
snprintf(str, sizeof str, "Dictionary stats for %s (%d)",
dict->id, dict->count);
else
snprintf(str, sizeof str, "Dictionary stats for <%p> (%d)",
(void *) dict, dict->count);
cb(str, privdata);
maxdepth = 0; maxdepth = 0;
if (dict->count > 0) if (dict->count > 0)
{ {
sum = stats_recurse(dict->root, 0, &maxdepth); sum = stats_recurse(dict->root, 0, &maxdepth);
snprintf(str, sizeof str, "Depth sum %d Avg depth %d Max depth %d", sum, sum / dict->count, maxdepth); 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);
} }
else else
{ {
snprintf(str, sizeof str, "Depth sum 0 Avg depth 0 Max depth 0"); snprintf(str, sizeof str, "%s: Objects: 0, Depth sum: 0, Avg depth: 0, Max depth: 0.", dict->id);
} }
cb(str, privdata); cb(str, privdata);
return; return;
} }
void
irc_radixtree_stats_walk(void (*cb)(const char *line, void *privdata), void *privdata)
{
rb_dlink_node *ptr;
RB_DLINK_FOREACH(ptr, radixtree_list.head)
{
irc_radixtree_stats(ptr->data, cb, privdata);
}
}