ircd: hostname lists are now stored in a radix tree

This commit is contained in:
William Pitcock 2016-01-23 11:40:17 -05:00
parent b47f8a4fda
commit d38c08c178

View file

@ -42,8 +42,6 @@
#include "irc_dictionary.h" #include "irc_dictionary.h"
#include "irc_radixtree.h" #include "irc_radixtree.h"
rb_dlink_list *hostTable;
struct Dictionary *client_connid_tree = NULL; struct Dictionary *client_connid_tree = NULL;
struct Dictionary *client_zconnid_tree = NULL; struct Dictionary *client_zconnid_tree = NULL;
struct irc_radixtree *client_id_tree = NULL; struct irc_radixtree *client_id_tree = NULL;
@ -51,6 +49,7 @@ struct irc_radixtree *client_name_tree = NULL;
struct irc_radixtree *channel_tree = NULL; struct irc_radixtree *channel_tree = NULL;
struct irc_radixtree *resv_tree = NULL; struct irc_radixtree *resv_tree = NULL;
struct irc_radixtree *hostname_tree = NULL;
/* /*
* look in whowas.c for the missing ...[WW_MAX]; entry * look in whowas.c for the missing ...[WW_MAX]; entry
@ -63,8 +62,6 @@ struct irc_radixtree *resv_tree = NULL;
void void
init_hash(void) init_hash(void)
{ {
hostTable = rb_malloc(sizeof(rb_dlink_list) * HOST_MAX);
client_connid_tree = irc_dictionary_create("client connid", irc_uint32cmp); client_connid_tree = irc_dictionary_create("client connid", irc_uint32cmp);
client_zconnid_tree = irc_dictionary_create("client zconnid", irc_uint32cmp); client_zconnid_tree = irc_dictionary_create("client zconnid", irc_uint32cmp);
client_id_tree = irc_radixtree_create("client id", NULL); client_id_tree = irc_radixtree_create("client id", NULL);
@ -72,6 +69,8 @@ init_hash(void)
channel_tree = irc_radixtree_create("channel", irc_radixtree_irccasecanon); channel_tree = irc_radixtree_create("channel", irc_radixtree_irccasecanon);
resv_tree = irc_radixtree_create("resv", irc_radixtree_irccasecanon); resv_tree = irc_radixtree_create("resv", irc_radixtree_irccasecanon);
hostname_tree = irc_radixtree_create("hostname", irc_radixtree_irccasecanon);
} }
u_int32_t u_int32_t
@ -134,17 +133,6 @@ fnv_hash_upper_len(const unsigned char *s, int bits, int len)
return h; return h;
} }
/* hash_hostname()
*
* hashes a hostname, based on first 30 chars only, as thats likely to
* be more dynamic than rest.
*/
static u_int32_t
hash_hostname(const char *name)
{
return fnv_hash_upper_len((const unsigned char *) name, HOST_MAX_BITS, 30);
}
/* add_to_id_hash() /* add_to_id_hash()
* *
* adds an entry to the id hash table * adds an entry to the id hash table
@ -180,15 +168,23 @@ add_to_client_hash(const char *name, struct Client *client_p)
void void
add_to_hostname_hash(const char *hostname, struct Client *client_p) add_to_hostname_hash(const char *hostname, struct Client *client_p)
{ {
unsigned int hashv; rb_dlink_list *list;
s_assert(hostname != NULL); s_assert(hostname != NULL);
s_assert(client_p != NULL); s_assert(client_p != NULL);
if(EmptyString(hostname) || (client_p == NULL)) if(EmptyString(hostname) || (client_p == NULL))
return; return;
hashv = hash_hostname(hostname); list = irc_radixtree_retrieve(hostname_tree, hostname);
rb_dlinkAddAlloc(client_p, &hostTable[hashv]); if (list != NULL)
{
rb_dlinkAddAlloc(client_p, list);
return;
}
list = rb_malloc(sizeof(*list));
irc_radixtree_add(hostname_tree, hostname, list);
rb_dlinkAddAlloc(client_p, list);
} }
/* add_to_resv_hash() /* add_to_resv_hash()
@ -260,14 +256,22 @@ del_from_channel_hash(const char *name, struct Channel *chptr)
void void
del_from_hostname_hash(const char *hostname, struct Client *client_p) del_from_hostname_hash(const char *hostname, struct Client *client_p)
{ {
unsigned int hashv; rb_dlink_list *list;
if(hostname == NULL || client_p == NULL) if(hostname == NULL || client_p == NULL)
return; return;
hashv = hash_hostname(hostname); list = irc_radixtree_retrieve(hostname_tree, hostname);
if (list == NULL)
return;
rb_dlinkFindDestroy(client_p, &hostTable[hashv]); rb_dlinkFindDestroy(client_p, list);
if (rb_dlink_list_length(list) == 0)
{
irc_radixtree_delete(hostname_tree, hostname);
rb_free(list);
}
} }
/* del_from_resv_hash() /* del_from_resv_hash()
@ -368,14 +372,16 @@ find_server(struct Client *source_p, const char *name)
rb_dlink_node * rb_dlink_node *
find_hostname(const char *hostname) find_hostname(const char *hostname)
{ {
unsigned int hashv; rb_dlink_list *hlist;
if(EmptyString(hostname)) if(EmptyString(hostname))
return NULL; return NULL;
hashv = hash_hostname(hostname); hlist = irc_radixtree_retrieve(hostname_tree, hostname);
if (hlist == NULL)
return NULL;
return hostTable[hashv].head; return hlist->head;
} }
/* find_channel() /* find_channel()