]> jfr.im git - solanum.git/blobdiff - ircd/hash.c
ircd: hash: use an irc_radixtree for storing resv's
[solanum.git] / ircd / hash.c
index 74aa5551e184ce01f8d3166bbc374b14f617927c..11831bea15a431c916b51828114d2956eeb7cc82 100644 (file)
 #include "cache.h"
 #include "s_newconf.h"
 #include "s_assert.h"
-
-#define ZCONNID_MAX 64 /* i doubt we'll have this many ziplinks ;) */
-
-#define hash_cli_connid(x)     (x % CLI_CONNID_MAX)
-#define hash_zconnid(x)                (x % ZCONNID_MAX)
-
-static rb_dlink_list clientbyconnidTable[CLI_CONNID_MAX];
-static rb_dlink_list clientbyzconnidTable[ZCONNID_MAX];
+#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
  */
@@ -102,10 +100,13 @@ 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);
 }
 
-#ifndef RICER_HASHING
 u_int32_t
 fnv_hash_upper(const unsigned char *s, int bits)
 {
@@ -165,7 +166,6 @@ fnv_hash_upper_len(const unsigned char *s, int bits, int len)
                h = ((h >> bits) ^ h) & ((1<<bits)-1);
        return h;
 }
-#endif
 
 /* hash_nick()
  *
@@ -208,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
@@ -277,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()
@@ -368,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()
@@ -624,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;
@@ -651,77 +626,55 @@ 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
 add_to_zconnid_hash(struct Client *client_p)
 {
-       unsigned int hashv;
-       hashv = hash_zconnid(client_p->localClient->zconnid);
-       rb_dlinkAddAlloc(client_p, &clientbyzconnidTable[hashv]);       
+       irc_dictionary_add(client_zconnid_tree, IRC_UINT_TO_POINTER(client_p->localClient->zconnid), client_p);
 }
 
 void
 del_from_zconnid_hash(struct Client *client_p)
 {
-       unsigned int hashv;
-       hashv = hash_zconnid(client_p->localClient->zconnid);
-       rb_dlinkFindDestroy(client_p, &clientbyzconnidTable[hashv]); 
+       irc_dictionary_delete(client_zconnid_tree, IRC_UINT_TO_POINTER(client_p->localClient->zconnid));
 }
 
 void
 add_to_cli_connid_hash(struct Client *client_p)
 {
-       unsigned int hashv;
-       hashv = hash_cli_connid(client_p->localClient->connid);
-       rb_dlinkAddAlloc(client_p, &clientbyconnidTable[hashv]);
+       irc_dictionary_add(client_connid_tree, IRC_UINT_TO_POINTER(client_p->localClient->connid), client_p);
 }
 
 void
 del_from_cli_connid_hash(struct Client *client_p)
 {
-       unsigned int hashv;
-       hashv = hash_cli_connid(client_p->localClient->connid);
-       rb_dlinkFindDestroy(client_p, &clientbyconnidTable[hashv]);
+       irc_dictionary_delete(client_connid_tree, IRC_UINT_TO_POINTER(client_p->localClient->connid));
 }
 
 struct Client *
-find_cli_connid_hash(int connid)
+find_cli_connid_hash(uint32_t connid)
 {
        struct Client *target_p;
-       rb_dlink_node *ptr;
-       unsigned int hashv;
-       hashv = hash_cli_connid(connid);
-       RB_DLINK_FOREACH(ptr, clientbyconnidTable[hashv].head)
-       {
-               target_p = ptr->data;
-               if(target_p->localClient->connid == connid)
-                       return target_p;
-       }
 
-       hashv = hash_zconnid(connid);
-       RB_DLINK_FOREACH(ptr, clientbyzconnidTable[hashv].head)
-       {
-               target_p = ptr->data;
-               if(target_p->localClient->zconnid == connid)
-                       return target_p;
-       }
+       target_p = irc_dictionary_retrieve(client_connid_tree, IRC_UINT_TO_POINTER(connid));
+       if (target_p != NULL)
+               return target_p;
+
+       target_p = irc_dictionary_retrieve(client_zconnid_tree, IRC_UINT_TO_POINTER(connid));
+       if (target_p != NULL)
+               return target_p;
 
        return NULL;
 }
@@ -800,6 +753,4 @@ hash_stats(struct Client *source_p)
        count_hash(source_p, idTable, U_MAX, "ID");
        sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
        count_hash(source_p, hostTable, HOST_MAX, "Hostname");
-       sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
-       count_hash(source_p, clientbyconnidTable, CLI_CONNID_MAX, "Client by connection id");
 }