#include "s_assert.h"
#include "logger.h"
-static rb_bh *elem_heap = NULL;
-
struct Dictionary
{
DCF compare_cb;
unsigned int count;
char *id;
unsigned int dirty:1;
-};
-
-/*
- * irc_dictionary_create(DCF compare_cb)
- *
- * Dictionary object factory.
- *
- * Inputs:
- * - function to use for comparing two entries in the dtree
- *
- * Outputs:
- * - on success, a new dictionary object.
- *
- * Side Effects:
- * - if services runs out of memory and cannot allocate the object,
- * the program will abort.
- */
-struct Dictionary *irc_dictionary_create(DCF compare_cb)
-{
- struct Dictionary *dtree = (struct Dictionary *) rb_malloc(sizeof(struct Dictionary));
-
- dtree->compare_cb = compare_cb;
- if (!elem_heap)
- elem_heap = rb_bh_create(sizeof(struct DictionaryElement), 1024, "dictionary_elem_heap");
+ rb_dlink_node node;
+};
- return dtree;
-}
+static rb_dlink_list dictionary_list = {NULL, NULL, 0};
/*
- * irc_dictionary_create_named(const char *name,
- * DCF compare_cb)
+ * irc_dictionary_create(const char *name, DCF compare_cb)
*
* Dictionary object factory.
*
* - if services runs out of memory and cannot allocate the object,
* the program will abort.
*/
-struct Dictionary *irc_dictionary_create_named(const char *name,
+struct Dictionary *irc_dictionary_create(const char *name,
DCF compare_cb)
{
struct Dictionary *dtree = (struct Dictionary *) rb_malloc(sizeof(struct Dictionary));
dtree->compare_cb = compare_cb;
dtree->id = rb_strdup(name);
- if (!elem_heap)
- elem_heap = rb_bh_create(sizeof(struct DictionaryElement), 1024, "dictionary_elem_heap");
+ rb_dlinkAdd(dtree, &dtree->node, &dictionary_list);
return dtree;
}
/*
* irc_dictionary_get_linear_index(struct Dictionary *dict,
- * const char *key)
+ * const void *key)
*
* Gets a linear index number for key.
*
* - rebuilds the linear index if the tree is marked as dirty.
*/
int
-irc_dictionary_get_linear_index(struct Dictionary *dict, const char *key)
+irc_dictionary_get_linear_index(struct Dictionary *dict, const void *key)
{
struct DictionaryElement *elem;
}
/*
- * irc_dictionary_retune(struct Dictionary *dict, const char *key)
+ * irc_dictionary_retune(struct Dictionary *dict, const void *key)
*
* Retunes the tree, self-optimizing for the element which belongs to key.
*
* - a new root node is nominated.
*/
static void
-irc_dictionary_retune(struct Dictionary *dict, const char *key)
+irc_dictionary_retune(struct Dictionary *dict, const void *key)
{
struct DictionaryElement n, *tn, *left, *right, *node;
int ret;
dict->root->data = delem->data;
dict->count--;
- rb_bh_free(elem_heap, delem);
+ rb_free(delem);
}
}
}
if (destroy_cb != NULL)
(*destroy_cb)(n, privdata);
- rb_bh_free(elem_heap, n);
+ rb_free(n);
}
+ rb_dlinkDelete(&dtree->node, &dictionary_list);
+ rb_free(dtree->id);
rb_free(dtree);
}
}
/*
- * irc_dictionary_find(struct Dictionary *dtree, const char *key)
+ * irc_dictionary_find(struct Dictionary *dtree, const void *key)
*
* Looks up a DTree node by name.
*
* Side Effects:
* - none
*/
-struct DictionaryElement *irc_dictionary_find(struct Dictionary *dict, const char *key)
+struct DictionaryElement *irc_dictionary_find(struct Dictionary *dict, const void *key)
{
s_assert(dict != NULL);
s_assert(key != NULL);
}
/*
- * irc_dictionary_add(struct Dictionary *dtree, const char *key, void *data)
+ * irc_dictionary_add(struct Dictionary *dtree, const void *key, void *data)
*
* Creates a new DTree node and binds data to it.
*
* Side Effects:
* - data is inserted into the DTree.
*/
-struct DictionaryElement *irc_dictionary_add(struct Dictionary *dict, const char *key, void *data)
+struct DictionaryElement *irc_dictionary_add(struct Dictionary *dict, const void *key, void *data)
{
struct DictionaryElement *delem;
s_assert(data != NULL);
s_assert(irc_dictionary_find(dict, key) == NULL);
- delem = rb_bh_alloc(elem_heap);
+ delem = rb_malloc(sizeof(*delem));
delem->key = key;
delem->data = data;
- /* TBD: is this needed? --nenolod */
- if (delem->key == NULL)
- {
- rb_bh_free(elem_heap, delem);
- return NULL;
- }
-
irc_dictionary_link(dict, delem);
return delem;
}
/*
- * irc_dictionary_delete(struct Dictionary *dtree, const char *key)
+ * irc_dictionary_delete(struct Dictionary *dtree, const void *key)
*
* Deletes data from a dictionary tree.
*
* Notes:
* - the returned data needs to be mowgli_freed/released manually!
*/
-void *irc_dictionary_delete(struct Dictionary *dtree, const char *key)
+void *irc_dictionary_delete(struct Dictionary *dtree, const void *key)
{
struct DictionaryElement *delem = irc_dictionary_find(dtree, key);
void *data;
data = delem->data;
irc_dictionary_unlink_root(dtree);
- rb_bh_free(elem_heap, delem);
+ rb_free(delem);
return data;
}
/*
- * irc_dictionary_retrieve(struct Dictionary *dtree, const char *key)
+ * irc_dictionary_retrieve(struct Dictionary *dtree, const void *key)
*
* Retrieves data from a dictionary.
*
* Side Effects:
* - none
*/
-void *irc_dictionary_retrieve(struct Dictionary *dtree, const char *key)
+void *irc_dictionary_retrieve(struct Dictionary *dtree, const void *key)
{
struct DictionaryElement *delem = irc_dictionary_find(dtree, key);
if (depth > *pmaxdepth)
*pmaxdepth = depth;
result = depth;
- if (delem->left)
+ if (delem && delem->left)
result += stats_recurse(delem->left, depth + 1, pmaxdepth);
- if (delem->right)
+ if (delem && delem->right)
result += stats_recurse(delem->right, depth + 1, pmaxdepth);
return result;
}
s_assert(dict != NULL);
- if (dict->id != NULL)
- rb_snprintf(str, sizeof str, "Dictionary stats for %s (%d)",
- dict->id, dict->count);
+ if (dict->count)
+ {
+ maxdepth = 0;
+ sum = stats_recurse(dict->root, 0, &maxdepth);
+ snprintf(str, sizeof str, "%-30s %-15s %-10d %-10d %-10d %-10d", dict->id, "DICT", dict->count, sum, sum / dict->count, maxdepth);
+ }
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);
+ {
+ snprintf(str, sizeof str, "%-30s %-15s %-10s %-10s %-10s %-10s", dict->id, "DICT", "0", "0", "0", "0");
+ }
+
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);
+ }
}