From 45dfdf46c88f0f74f0982ffca1a8b94944966f7a Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Sat, 9 Jan 2016 04:09:40 -0600 Subject: [PATCH] ircd: irc_dictionary: allow storage of non-string types as keys --- include/irc_dictionary.h | 30 +++++++++++++++++++++++------- ircd/irc_dictionary.c | 31 ++++++++++++------------------- 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/include/irc_dictionary.h b/include/irc_dictionary.h index eaf4d7f7..7af9cd10 100644 --- a/include/irc_dictionary.h +++ b/include/irc_dictionary.h @@ -27,13 +27,13 @@ struct Dictionary; /* defined in src/dictionary.c */ -typedef int (*DCF)(const char *a, const char *b); +typedef int (*DCF)(/* const void *a, const void *b */); struct DictionaryElement { struct DictionaryElement *left, *right, *prev, *next; void *data; - const char *key; + const void *key; int position; }; @@ -70,7 +70,7 @@ extern DCF irc_dictionary_get_comparator_func(struct Dictionary *dict); * irc_dictionary_get_linear_index() returns the linear index of an object in the * DTree structure. */ -extern int irc_dictionary_get_linear_index(struct Dictionary *dict, const char *key); +extern int irc_dictionary_get_linear_index(struct Dictionary *dict, const void *key); /* * irc_dictionary_destroy() destroys all entries in a dtree, and also optionally calls @@ -126,22 +126,22 @@ extern void irc_dictionary_foreach_next(struct Dictionary *dtree, /* * irc_dictionary_add() adds a key->value entry to the dictionary tree. */ -extern struct DictionaryElement *irc_dictionary_add(struct Dictionary *dtree, const char *key, void *data); +extern struct DictionaryElement *irc_dictionary_add(struct Dictionary *dtree, const void *key, void *data); /* * irc_dictionary_find() returns a struct DictionaryElement container from a dtree for key 'key'. */ -extern struct DictionaryElement *irc_dictionary_find(struct Dictionary *dtree, const char *key); +extern struct DictionaryElement *irc_dictionary_find(struct Dictionary *dtree, const void *key); /* * irc_dictionary_find() returns data from a dtree for key 'key'. */ -extern void *irc_dictionary_retrieve(struct Dictionary *dtree, const char *key); +extern void *irc_dictionary_retrieve(struct Dictionary *dtree, const void *key); /* * irc_dictionary_delete() deletes a key->value entry from the dictionary tree. */ -extern void *irc_dictionary_delete(struct Dictionary *dtree, const char *key); +extern void *irc_dictionary_delete(struct Dictionary *dtree, const void *key); /* * irc_dictionary_size() returns the number of elements in a dictionary tree. @@ -151,4 +151,20 @@ 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); +#define IRC_POINTER_TO_INT(x) ((int32_t) (long) (x)) +#define IRC_INT_TO_POINTER(x) ((void *) (long) (int32_t) (x)) + +#define IRC_POINTER_TO_UINT(x) ((uint32_t) (unsigned long) (x)) +#define IRC_UINT_TO_POINTER(x) ((void *) (unsigned long) (uint32_t) (x)) + +static inline int irc_int32cmp(const void *a, const void *b) +{ + return IRC_POINTER_TO_INT(b) - IRC_POINTER_TO_INT(a); +} + +static inline int irc_uint32cmp(const void *a, const void *b) +{ + return IRC_POINTER_TO_UINT(b) - IRC_POINTER_TO_UINT(a); +} + #endif diff --git a/ircd/irc_dictionary.c b/ircd/irc_dictionary.c index 3ce2c16f..5be9d479 100644 --- a/ircd/irc_dictionary.c +++ b/ircd/irc_dictionary.c @@ -122,7 +122,7 @@ irc_dictionary_get_comparator_func(struct Dictionary *dict) /* * irc_dictionary_get_linear_index(struct Dictionary *dict, - * const char *key) + * const void *key) * * Gets a linear index number for key. * @@ -137,7 +137,7 @@ irc_dictionary_get_comparator_func(struct Dictionary *dict) * - 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; @@ -165,7 +165,7 @@ irc_dictionary_get_linear_index(struct Dictionary *dict, const char *key) } /* - * 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. * @@ -179,7 +179,7 @@ irc_dictionary_get_linear_index(struct Dictionary *dict, const char *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; @@ -634,7 +634,7 @@ void irc_dictionary_foreach_next(struct Dictionary *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. * @@ -649,7 +649,7 @@ void irc_dictionary_foreach_next(struct Dictionary *dtree, * 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); @@ -664,7 +664,7 @@ struct DictionaryElement *irc_dictionary_find(struct Dictionary *dict, const cha } /* - * 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. * @@ -680,7 +680,7 @@ struct DictionaryElement *irc_dictionary_find(struct Dictionary *dict, const cha * 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; @@ -693,20 +693,13 @@ struct DictionaryElement *irc_dictionary_add(struct Dictionary *dict, const char delem->key = key; delem->data = data; - /* TBD: is this needed? --nenolod */ - if (delem->key == NULL) - { - rb_free(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. * @@ -724,7 +717,7 @@ struct DictionaryElement *irc_dictionary_add(struct Dictionary *dict, const char * 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; @@ -741,7 +734,7 @@ void *irc_dictionary_delete(struct Dictionary *dtree, const char *key) } /* - * irc_dictionary_retrieve(struct Dictionary *dtree, const char *key) + * irc_dictionary_retrieve(struct Dictionary *dtree, const void *key) * * Retrieves data from a dictionary. * @@ -756,7 +749,7 @@ void *irc_dictionary_delete(struct Dictionary *dtree, const char *key) * 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);