diff --git a/extensions/m_sendbans.c b/extensions/m_sendbans.c index 67df6df2..16cb5eb9 100644 --- a/extensions/m_sendbans.c +++ b/extensions/m_sendbans.c @@ -43,6 +43,7 @@ #include "hash.h" #include "modules.h" #include "messages.h" +#include "irc_radixtree.h" static int mo_sendbans(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]); @@ -89,6 +90,7 @@ static int mo_sendbans(struct Client *client_p, struct Client *source_p, int par int i, count; const char *target, *mask2; struct Client *server_p; + struct irc_radixtree_iteration_state state; if (!IsOperRemoteBan(source_p)) { @@ -142,9 +144,8 @@ static int mo_sendbans(struct Client *client_p, struct Client *source_p, int par target, aconf->host, aconf->passwd); } - HASH_WALK(i, R_MAX, ptr, resvTable) + IRC_RADIXTREE_FOREACH(aconf, &state, resv_tree) { - aconf = ptr->data; if (aconf->hold) continue; sendto_match_servs(source_p, target, @@ -152,7 +153,6 @@ static int mo_sendbans(struct Client *client_p, struct Client *source_p, int par "ENCAP %s RESV 0 %s 0 :%s", target, aconf->host, aconf->passwd); } - HASH_WALK_END RB_DLINK_FOREACH(ptr, xline_conf_list.head) { diff --git a/include/hash.h b/include/hash.h index 0c408371..e3e4af22 100644 --- a/include/hash.h +++ b/include/hash.h @@ -28,15 +28,16 @@ #define INCLUDED_hash_h struct Dictionary; +struct irc_radixtree; extern rb_dlink_list *clientTable; extern rb_dlink_list *channelTable; extern rb_dlink_list *idTable; -extern rb_dlink_list *resvTable; extern rb_dlink_list *hostTable; extern rb_dlink_list *helpTable; extern struct Dictionary *nd_dict; +extern struct irc_radixtree *resv_tree; /* Magic value for FNV hash functions */ #define FNV1_32_INIT 0x811c9dc5UL diff --git a/ircd/hash.c b/ircd/hash.c index 74b1666c..11831bea 100644 --- a/ircd/hash.c +++ b/ircd/hash.c @@ -40,16 +40,18 @@ #include "s_newconf.h" #include "s_assert.h" #include "irc_dictionary.h" +#include "irc_radixtree.h" rb_dlink_list *clientTable; rb_dlink_list *channelTable; rb_dlink_list *idTable; -rb_dlink_list *resvTable; rb_dlink_list *hostTable; struct Dictionary *client_connid_tree = NULL; struct Dictionary *client_zconnid_tree = NULL; +struct irc_radixtree *resv_tree = NULL; + /* * look in whowas.c for the missing ...[WW_MAX]; entry */ @@ -98,10 +100,11 @@ init_hash(void) idTable = rb_malloc(sizeof(rb_dlink_list) * U_MAX); channelTable = rb_malloc(sizeof(rb_dlink_list) * CH_MAX); hostTable = rb_malloc(sizeof(rb_dlink_list) * HOST_MAX); - resvTable = rb_malloc(sizeof(rb_dlink_list) * R_MAX); client_connid_tree = irc_dictionary_create("client connid", irc_uint32cmp); client_zconnid_tree = irc_dictionary_create("client zconnid", irc_uint32cmp); + + resv_tree = irc_radixtree_create("resv", irc_radixtree_irccasecanon); } u_int32_t @@ -205,16 +208,6 @@ hash_hostname(const char *name) return fnv_hash_upper_len((const unsigned char *) name, HOST_MAX_BITS, 30); } -/* hash_resv() - * - * hashes a resv channel name, based on first 30 chars only - */ -static u_int32_t -hash_resv(const char *name) -{ - return fnv_hash_upper_len((const unsigned char *) name, R_MAX_BITS, 30); -} - /* add_to_id_hash() * * adds an entry to the id hash table @@ -274,15 +267,12 @@ add_to_hostname_hash(const char *hostname, struct Client *client_p) void add_to_resv_hash(const char *name, struct ConfItem *aconf) { - unsigned int hashv; - s_assert(!EmptyString(name)); s_assert(aconf != NULL); if(EmptyString(name) || aconf == NULL) return; - hashv = hash_resv(name); - rb_dlinkAddAlloc(aconf, &resvTable[hashv]); + irc_radixtree_add(resv_tree, name, aconf); } /* del_from_id_hash() @@ -365,16 +355,12 @@ del_from_hostname_hash(const char *hostname, struct Client *client_p) void del_from_resv_hash(const char *name, struct ConfItem *aconf) { - unsigned int hashv; - s_assert(name != NULL); s_assert(aconf != NULL); if(EmptyString(name) || aconf == NULL) return; - hashv = hash_resv(name); - - rb_dlinkFindDestroy(aconf, &resvTable[hashv]); + irc_radixtree_delete(resv_tree, name); } /* find_id() @@ -621,24 +607,16 @@ struct ConfItem * hash_find_resv(const char *name) { struct ConfItem *aconf; - rb_dlink_node *ptr; - unsigned int hashv; s_assert(name != NULL); if(EmptyString(name)) return NULL; - hashv = hash_resv(name); - - RB_DLINK_FOREACH(ptr, resvTable[hashv].head) + aconf = irc_radixtree_retrieve(resv_tree, name); + if (aconf != NULL) { - aconf = ptr->data; - - if(!irccmp(name, aconf->host)) - { - aconf->port++; - return aconf; - } + aconf->port++; + return aconf; } return NULL; @@ -648,22 +626,17 @@ void clear_resv_hash(void) { struct ConfItem *aconf; - rb_dlink_node *ptr; - rb_dlink_node *next_ptr; - int i; + struct irc_radixtree_iteration_state iter; - HASH_WALK_SAFE(i, R_MAX, ptr, next_ptr, resvTable) + IRC_RADIXTREE_FOREACH(aconf, &iter, resv_tree) { - aconf = ptr->data; - /* skip temp resvs */ if(aconf->hold) continue; - free_conf(ptr->data); - rb_dlinkDestroy(ptr, &resvTable[i]); + irc_radixtree_delete(resv_tree, aconf->host); + free_conf(aconf); } - HASH_WALK_END } void diff --git a/ircd/s_newconf.c b/ircd/s_newconf.c index acda72d9..5099487b 100644 --- a/ircd/s_newconf.c +++ b/ircd/s_newconf.c @@ -44,6 +44,7 @@ #include "newconf.h" #include "hash.h" #include "irc_dictionary.h" +#include "irc_radixtree.h" #include "s_assert.h" #include "logger.h" #include "dns.h" @@ -687,11 +688,10 @@ expire_temp_rxlines(void *unused) rb_dlink_node *ptr; rb_dlink_node *next_ptr; int i; + struct irc_radixtree_iteration_state state; - HASH_WALK_SAFE(i, R_MAX, ptr, next_ptr, resvTable) + IRC_RADIXTREE_FOREACH(aconf, &state, resv_tree) { - aconf = ptr->data; - if(aconf->lifetime != 0) continue; if(aconf->hold && aconf->hold <= rb_current_time()) @@ -701,11 +701,10 @@ expire_temp_rxlines(void *unused) "Temporary RESV for [%s] expired", aconf->host); + irc_radixtree_delete(resv_tree, aconf->host); free_conf(aconf); - rb_dlinkDestroy(ptr, &resvTable[i]); } } - HASH_WALK_END RB_DLINK_FOREACH_SAFE(ptr, next_ptr, resv_conf_list.head) { diff --git a/modules/m_rehash.c b/modules/m_rehash.c index 84b542d0..005ef352 100644 --- a/modules/m_rehash.c +++ b/modules/m_rehash.c @@ -43,6 +43,7 @@ #include "reject.h" #include "hash.h" #include "cache.h" +#include "irc_radixtree.h" static int mo_rehash(struct Client *, struct Client *, int, const char **); static int me_rehash(struct Client *, struct Client *, int, const char **); @@ -185,6 +186,7 @@ static void rehash_tresvs(struct Client *source_p) { struct ConfItem *aconf; + struct irc_radixtree_iteration_state iter; rb_dlink_node *ptr; rb_dlink_node *next_ptr; int i; @@ -194,17 +196,14 @@ rehash_tresvs(struct Client *source_p) if (!MyConnect(source_p)) remote_rehash_oper_p = source_p; - HASH_WALK_SAFE(i, R_MAX, ptr, next_ptr, resvTable) + IRC_RADIXTREE_FOREACH(aconf, &iter, resv_tree) { - aconf = ptr->data; - if(!aconf->hold || aconf->lifetime) continue; + irc_radixtree_delete(resv_tree, aconf->host); free_conf(aconf); - rb_dlinkDestroy(ptr, &resvTable[i]); } - HASH_WALK_END RB_DLINK_FOREACH_SAFE(ptr, next_ptr, resv_conf_list.head) { diff --git a/modules/m_stats.c b/modules/m_stats.c index 6e3c842c..ce0f14d7 100644 --- a/modules/m_stats.c +++ b/modules/m_stats.c @@ -831,6 +831,7 @@ static void stats_tresv(struct Client *source_p) { struct ConfItem *aconf; + struct irc_radixtree_iteration_state state; rb_dlink_node *ptr; int i; @@ -843,15 +844,13 @@ stats_tresv(struct Client *source_p) 'q', aconf->port, aconf->host, aconf->passwd); } - HASH_WALK(i, R_MAX, ptr, resvTable) + IRC_RADIXTREE_FOREACH(aconf, &state, resv_tree) { - aconf = ptr->data; if(aconf->hold) sendto_one_numeric(source_p, RPL_STATSQLINE, form_str(RPL_STATSQLINE), 'q', aconf->port, aconf->host, aconf->passwd); } - HASH_WALK_END } @@ -859,6 +858,7 @@ static void stats_resv(struct Client *source_p) { struct ConfItem *aconf; + struct irc_radixtree_iteration_state state; rb_dlink_node *ptr; int i; @@ -871,15 +871,13 @@ stats_resv(struct Client *source_p) 'Q', aconf->port, aconf->host, aconf->passwd); } - HASH_WALK(i, R_MAX, ptr, resvTable) + IRC_RADIXTREE_FOREACH(aconf, &state, resv_tree) { - aconf = ptr->data; if(!aconf->hold) sendto_one_numeric(source_p, RPL_STATSQLINE, form_str(RPL_STATSQLINE), 'Q', aconf->port, aconf->host, aconf->passwd); } - HASH_WALK_END } static void