#include "stdinc.h"
#include "ircd_defs.h"
-#include "tools.h"
#include "s_conf.h"
#include "channel.h"
#include "client.h"
#include "common.h"
#include "hash.h"
-#include "irc_string.h"
+#include "match.h"
#include "ircd.h"
#include "numeric.h"
#include "send.h"
-#include "memory.h"
#include "msg.h"
#include "cache.h"
#include "s_newconf.h"
+#include "s_assert.h"
-dlink_list *clientTable;
-dlink_list *channelTable;
-dlink_list *idTable;
-dlink_list *resvTable;
-dlink_list *hostTable;
-dlink_list *helpTable;
+#define hash_cli_fd(x) (x % CLI_FD_MAX)
+
+static rb_dlink_list clientbyfdTable[U_MAX];
+
+rb_dlink_list *clientTable;
+rb_dlink_list *channelTable;
+rb_dlink_list *idTable;
+rb_dlink_list *resvTable;
+rb_dlink_list *hostTable;
/*
* look in whowas.c for the missing ...[WW_MAX]; entry
*
* A - GOPbot, B - chang, C - hanuaway, D - *.mu.OZ.AU
*
- * The order shown above is just one instant of the server.
+ * The order shown above is just one instant of the server.
*
*
* The hash functions currently used are based Fowler/Noll/Vo hashes
* which work amazingly well and have a extremely low collision rate
* For more info see http://www.isthe.com/chongo/tech/comp/fnv/index.html
*
- *
+ *
*/
/* init_hash()
void
init_hash(void)
{
- clientTable = MyMalloc(sizeof(dlink_list) * U_MAX);
- idTable = MyMalloc(sizeof(dlink_list) * U_MAX);
- channelTable = MyMalloc(sizeof(dlink_list) * CH_MAX);
- hostTable = MyMalloc(sizeof(dlink_list) * HOST_MAX);
- resvTable = MyMalloc(sizeof(dlink_list) * R_MAX);
- helpTable = MyMalloc(sizeof(dlink_list) * HELP_MAX);
+ clientTable = rb_malloc(sizeof(rb_dlink_list) * U_MAX);
+ 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);
}
#ifndef RICER_HASHING
h ^= ToUpper(*s++);
h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
}
- h = (h >> bits) ^ (h & ((2^bits)-1));
+ if (bits < 32)
+ h = ((h >> bits) ^ h) & ((1<<bits)-1);
return h;
}
h ^= *s++;
h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
}
- h = (h >> bits) ^ (h & ((2^bits)-1));
+ if (bits < 32)
+ h = ((h >> bits) ^ h) & ((1<<bits)-1);
return h;
}
h ^= *s++;
h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
}
- h = (h >> bits) ^ (h & ((2^bits)-1));
+ if (bits < 32)
+ h = ((h >> bits) ^ h) & ((1<<bits)-1);
return h;
}
h ^= ToUpper(*s++);
h += (h<<1) + (h<<4) + (h<<7) + (h << 8) + (h << 24);
}
- h = (h >> bits) ^ (h & ((2^bits)-1));
+ if (bits < 32)
+ h = ((h >> bits) ^ h) & ((1<<bits)-1);
return h;
}
#endif
return fnv_hash_upper_len((const unsigned char *) name, R_MAX_BITS, 30);
}
-static unsigned int
-hash_help(const char *name)
-{
- unsigned int h = 0;
-
- while(*name)
- {
- h += (unsigned int) (ToLower(*name++) & 0xDF);
- }
-
- return (h % HELP_MAX);
-}
-
/* add_to_id_hash()
*
* adds an entry to the id hash table
return;
hashv = hash_id(name);
- dlinkAddAlloc(client_p, &idTable[hashv]);
+ rb_dlinkAddAlloc(client_p, &idTable[hashv]);
}
/* add_to_client_hash()
return;
hashv = hash_nick(name);
- dlinkAddAlloc(client_p, &clientTable[hashv]);
+ rb_dlinkAddAlloc(client_p, &clientTable[hashv]);
}
/* add_to_hostname_hash()
return;
hashv = hash_hostname(hostname);
- dlinkAddAlloc(client_p, &hostTable[hashv]);
+ rb_dlinkAddAlloc(client_p, &hostTable[hashv]);
}
/* add_to_resv_hash()
return;
hashv = hash_resv(name);
- dlinkAddAlloc(aconf, &resvTable[hashv]);
-}
-
-void
-add_to_help_hash(const char *name, struct cachefile *hptr)
-{
- unsigned int hashv;
-
- if(EmptyString(name) || hptr == NULL)
- return;
-
- hashv = hash_help(name);
- dlinkAddAlloc(hptr, &helpTable[hashv]);
+ rb_dlinkAddAlloc(aconf, &resvTable[hashv]);
}
/* del_from_id_hash()
return;
hashv = hash_id(id);
- dlinkFindDestroy(client_p, &idTable[hashv]);
+ rb_dlinkFindDestroy(client_p, &idTable[hashv]);
}
/* del_from_client_hash()
return;
hashv = hash_nick(name);
- dlinkFindDestroy(client_p, &clientTable[hashv]);
+ rb_dlinkFindDestroy(client_p, &clientTable[hashv]);
}
/* del_from_channel_hash()
- *
+ *
* removes a channel from the channel hash table
*/
void
return;
hashv = hash_channel(name);
- dlinkFindDestroy(chptr, &channelTable[hashv]);
+ rb_dlinkFindDestroy(chptr, &channelTable[hashv]);
}
/* del_from_hostname_hash()
hashv = hash_hostname(hostname);
- dlinkFindDestroy(client_p, &hostTable[hashv]);
+ rb_dlinkFindDestroy(client_p, &hostTable[hashv]);
}
/* del_from_resv_hash()
hashv = hash_resv(name);
- dlinkFindDestroy(aconf, &resvTable[hashv]);
-}
-
-void
-clear_help_hash(void)
-{
- dlink_node *ptr;
- dlink_node *next_ptr;
- int i;
-
- HASH_WALK_SAFE(i, HELP_MAX, ptr, next_ptr, helpTable)
- {
- free_cachefile(ptr->data);
- dlinkDestroy(ptr, &helpTable[i]);
- }
- HASH_WALK_END
+ rb_dlinkFindDestroy(aconf, &resvTable[hashv]);
}
/* find_id()
find_id(const char *name)
{
struct Client *target_p;
- dlink_node *ptr;
+ rb_dlink_node *ptr;
unsigned int hashv;
if(EmptyString(name))
hashv = hash_id(name);
- DLINK_FOREACH(ptr, idTable[hashv].head)
+ RB_DLINK_FOREACH(ptr, idTable[hashv].head)
{
target_p = ptr->data;
find_client(const char *name)
{
struct Client *target_p;
- dlink_node *ptr;
+ rb_dlink_node *ptr;
unsigned int hashv;
s_assert(name != NULL);
hashv = hash_nick(name);
- DLINK_FOREACH(ptr, clientTable[hashv].head)
+ RB_DLINK_FOREACH(ptr, clientTable[hashv].head)
{
target_p = ptr->data;
find_named_client(const char *name)
{
struct Client *target_p;
- dlink_node *ptr;
+ rb_dlink_node *ptr;
unsigned int hashv;
s_assert(name != NULL);
hashv = hash_nick(name);
- DLINK_FOREACH(ptr, clientTable[hashv].head)
+ RB_DLINK_FOREACH(ptr, clientTable[hashv].head)
{
target_p = ptr->data;
find_server(struct Client *source_p, const char *name)
{
struct Client *target_p;
- dlink_node *ptr;
+ rb_dlink_node *ptr;
unsigned int hashv;
-
+
if(EmptyString(name))
return NULL;
- if((source_p == NULL || !MyClient(source_p)) &&
+ if((source_p == NULL || !MyClient(source_p)) &&
IsDigit(*name) && strlen(name) == 3)
{
target_p = find_id(name);
hashv = hash_nick(name);
- DLINK_FOREACH(ptr, clientTable[hashv].head)
+ RB_DLINK_FOREACH(ptr, clientTable[hashv].head)
{
target_p = ptr->data;
/* find_hostname()
*
- * finds a hostname dlink list from the hostname hash table.
- * we return the full dlink list, because you can have multiple
+ * finds a hostname rb_dlink list from the hostname hash table.
+ * we return the full rb_dlink list, because you can have multiple
* entries with the same hostname
*/
-dlink_node *
+rb_dlink_node *
find_hostname(const char *hostname)
{
unsigned int hashv;
find_channel(const char *name)
{
struct Channel *chptr;
- dlink_node *ptr;
+ rb_dlink_node *ptr;
unsigned int hashv;
s_assert(name != NULL);
hashv = hash_channel(name);
- DLINK_FOREACH(ptr, channelTable[hashv].head)
+ RB_DLINK_FOREACH(ptr, channelTable[hashv].head)
{
chptr = ptr->data;
get_or_create_channel(struct Client *client_p, const char *chname, int *isnew)
{
struct Channel *chptr;
- dlink_node *ptr;
+ rb_dlink_node *ptr;
unsigned int hashv;
int len;
const char *s = chname;
hashv = hash_channel(s);
- DLINK_FOREACH(ptr, channelTable[hashv].head)
+ RB_DLINK_FOREACH(ptr, channelTable[hashv].head)
{
chptr = ptr->data;
chptr = allocate_channel(s);
- dlinkAdd(chptr, &chptr->node, &global_channel_list);
+ rb_dlinkAdd(chptr, &chptr->node, &global_channel_list);
- chptr->channelts = CurrentTime; /* doesn't hurt to set it here */
+ chptr->channelts = rb_current_time(); /* doesn't hurt to set it here */
- dlinkAddAlloc(chptr, &channelTable[hashv]);
+ rb_dlinkAddAlloc(chptr, &channelTable[hashv]);
return chptr;
}
hash_find_resv(const char *name)
{
struct ConfItem *aconf;
- dlink_node *ptr;
+ rb_dlink_node *ptr;
unsigned int hashv;
s_assert(name != NULL);
hashv = hash_resv(name);
- DLINK_FOREACH(ptr, resvTable[hashv].head)
+ RB_DLINK_FOREACH(ptr, resvTable[hashv].head)
{
aconf = ptr->data;
- if(!irccmp(name, aconf->name))
+ if(!irccmp(name, aconf->host))
{
aconf->port++;
return aconf;
return NULL;
}
-struct cachefile *
-hash_find_help(const char *name, int flags)
-{
- struct cachefile *hptr;
- dlink_node *ptr;
- unsigned int hashv;
-
- if(EmptyString(name))
- return NULL;
-
- hashv = hash_help(name);
-
- DLINK_FOREACH(ptr, helpTable[hashv].head)
- {
- hptr = ptr->data;
-
- if((irccmp(name, hptr->name) == 0) &&
- (hptr->flags & flags))
- return hptr;
- }
-
- return NULL;
-}
-
void
clear_resv_hash(void)
{
struct ConfItem *aconf;
- dlink_node *ptr;
- dlink_node *next_ptr;
+ rb_dlink_node *ptr;
+ rb_dlink_node *next_ptr;
int i;
HASH_WALK_SAFE(i, R_MAX, ptr, next_ptr, resvTable)
continue;
free_conf(ptr->data);
- dlinkDestroy(ptr, &resvTable[i]);
+ rb_dlinkDestroy(ptr, &resvTable[i]);
}
HASH_WALK_END
}
+void
+add_to_cli_fd_hash(struct Client *client_p)
+{
+ rb_dlinkAddAlloc(client_p, &clientbyfdTable[hash_cli_fd(rb_get_fd(client_p->localClient->F))]);
+}
+
+
+void
+del_from_cli_fd_hash(struct Client *client_p)
+{
+ unsigned int hashv;
+ hashv = hash_cli_fd(rb_get_fd(client_p->localClient->F));
+ rb_dlinkFindDestroy(client_p, &clientbyfdTable[hashv]);
+}
+
+struct Client *
+find_cli_fd_hash(int fd)
+{
+ struct Client *target_p;
+ rb_dlink_node *ptr;
+ unsigned int hashv;
+ hashv = hash_cli_fd(fd);
+ RB_DLINK_FOREACH(ptr, clientbyfdTable[hashv].head)
+ {
+ target_p = ptr->data;
+ if(rb_get_fd(target_p->localClient->F) == fd)
+ return target_p;
+ }
+ return NULL;
+}
+
static void
output_hash(struct Client *source_p, const char *name, int length, int *counts, int deepest)
{
unsigned long total = 0;
int i;
+ char buf[128];
sendto_one_numeric(source_p, RPL_STATSDEBUG,
"B :%s Hash Statistics", name);
- sendto_one_numeric(source_p, RPL_STATSDEBUG,
- "B :Size: %d Empty: %d (%.3f%%)",
- length, counts[0],
+ snprintf(buf, sizeof buf, "%.3f%%",
(float) ((counts[0]*100) / (float) length));
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "B :Size: %d Empty: %d (%s)",
+ length, counts[0], buf);
for(i = 1; i < 11; i++)
{
/* dont want to divide by 0! --fl */
if(counts[0] != length)
- sendto_one_numeric(source_p, RPL_STATSDEBUG,
- "B :Average depth: %.3f/%.3f Highest depth: %d",
+ {
+ snprintf(buf, sizeof buf, "%.3f/%.3f",
(float) (total / (length - counts[0])),
- (float) (total / length), deepest);
+ (float) (total / length));
+ sendto_one_numeric(source_p, RPL_STATSDEBUG,
+ "B :Average depth: %s Highest depth: %d",
+ buf, deepest);
+ }
for(i = 0; i < 11; i++)
{
i, counts[i]);
}
}
-
+
static void
-count_hash(struct Client *source_p, dlink_list *table, int length, const char *name)
+count_hash(struct Client *source_p, rb_dlink_list *table, int length, const char *name)
{
int counts[11];
int deepest = 0;
int i;
memset(counts, 0, sizeof(counts));
-
+
for(i = 0; i < length; i++)
{
- if(dlink_list_length(&table[i]) >= 10)
+ if(rb_dlink_list_length(&table[i]) >= 10)
counts[10]++;
else
- counts[dlink_list_length(&table[i])]++;
+ counts[rb_dlink_list_length(&table[i])]++;
- if(dlink_list_length(&table[i]) > deepest)
- deepest = dlink_list_length(&table[i]);
+ if(rb_dlink_list_length(&table[i]) > deepest)
+ deepest = rb_dlink_list_length(&table[i]);
}
output_hash(source_p, name, length, counts, deepest);
count_hash(source_p, idTable, U_MAX, "ID");
sendto_one_numeric(source_p, RPL_STATSDEBUG, "B :--");
count_hash(source_p, hostTable, HOST_MAX, "Hostname");
-}
+}