commands and aliases go from horrible hashtable code to dictionary... try 1
This commit is contained in:
parent
c98390004f
commit
8ac7552983
4 changed files with 48 additions and 190 deletions
|
@ -32,15 +32,6 @@
|
|||
struct Message;
|
||||
struct Client;
|
||||
|
||||
struct MessageHash
|
||||
{
|
||||
char *cmd;
|
||||
struct Message *msg;
|
||||
struct MessageHash *next;
|
||||
};
|
||||
|
||||
#define MAX_MSG_HASH 387
|
||||
|
||||
extern void parse(struct Client *, char *, char *);
|
||||
extern void handle_encap(struct Client *, struct Client *,
|
||||
const char *, int, const char *parv[]);
|
||||
|
@ -49,6 +40,6 @@ extern void mod_add_cmd(struct Message *msg);
|
|||
extern void mod_del_cmd(struct Message *msg);
|
||||
extern void report_messages(struct Client *);
|
||||
|
||||
extern dlink_list alias_hash_table[MAX_MSG_HASH];
|
||||
extern struct Dictionary *alias_dict;
|
||||
|
||||
#endif /* INCLUDED_parse_h_h */
|
||||
|
|
|
@ -1580,20 +1580,6 @@ conf_set_service_name(void *data)
|
|||
target_p->flags |= FLAGS_SERVICE;
|
||||
}
|
||||
|
||||
static int
|
||||
alias_hash(const char *p)
|
||||
{
|
||||
int hash_val = 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
hash_val += ((int) (*p) & 0xDF);
|
||||
p++;
|
||||
}
|
||||
|
||||
return (hash_val % MAX_MSG_HASH);
|
||||
}
|
||||
|
||||
static int
|
||||
conf_begin_alias(struct TopConf *tc)
|
||||
{
|
||||
|
@ -1611,8 +1597,6 @@ conf_begin_alias(struct TopConf *tc)
|
|||
static int
|
||||
conf_end_alias(struct TopConf *tc)
|
||||
{
|
||||
int hashval;
|
||||
|
||||
if (yy_alias == NULL)
|
||||
return -1;
|
||||
|
||||
|
@ -1634,9 +1618,10 @@ conf_end_alias(struct TopConf *tc)
|
|||
return -1;
|
||||
}
|
||||
|
||||
hashval = alias_hash(yy_alias->name);
|
||||
if (!alias_dict)
|
||||
alias_dict = irc_dictionary_create(alias_dict);
|
||||
|
||||
dlinkAddAlloc(yy_alias, &alias_hash_table[hashval]);
|
||||
irc_dictionary_add(alias_dict, yy_alias->name, yy_alias);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
178
src/parse.c
178
src/parse.c
|
@ -1,10 +1,11 @@
|
|||
/*
|
||||
* ircd-ratbox: A slightly useful ircd.
|
||||
* charybdis: an advanced ircd.
|
||||
* parse.c: The message parser.
|
||||
*
|
||||
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
||||
* Copyright (C) 1996-2002 Hybrid Development Team
|
||||
* Copyright (C) 2002-2005 ircd-ratbox development team
|
||||
* Copyright (C) 2007 William Pitcock
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -43,6 +44,9 @@
|
|||
#include "s_serv.h"
|
||||
#include "packet.h"
|
||||
|
||||
static struct Dictionary *cmd_dict = NULL;
|
||||
struct Dictionary *alias_dict = NULL;
|
||||
|
||||
/*
|
||||
* NOTE: parse() should not be called recursively by other functions!
|
||||
*/
|
||||
|
@ -60,15 +64,9 @@ static void do_alias(struct alias_entry *, struct Client *, char *);
|
|||
static int handle_command(struct Message *, struct Client *, struct Client *, int, const char**);
|
||||
|
||||
static int cmd_hash(const char *p);
|
||||
static struct Message *hash_parse(const char *);
|
||||
static struct alias_entry *alias_parse(const char *);
|
||||
|
||||
struct MessageHash *msg_hash_table[MAX_MSG_HASH];
|
||||
|
||||
static char buffer[1024];
|
||||
|
||||
dlink_list alias_hash_table[MAX_MSG_HASH];
|
||||
|
||||
/* turn a string into a parc/parv pair */
|
||||
|
||||
|
||||
|
@ -220,7 +218,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
|
|||
if((s = strchr(ch, ' ')))
|
||||
*s++ = '\0';
|
||||
|
||||
mptr = hash_parse(ch);
|
||||
mptr = irc_dictionary_retrieve(cmd_dict, mptr);
|
||||
|
||||
/* no command or its encap only, error */
|
||||
if(!mptr || !mptr->cmd)
|
||||
|
@ -240,7 +238,7 @@ parse(struct Client *client_p, char *pbuffer, char *bufend)
|
|||
{
|
||||
if (IsPerson(client_p))
|
||||
{
|
||||
struct alias_entry *aptr = alias_parse(ch);
|
||||
struct alias_entry *aptr = irc_dictionary_retrieve(alias_dict, ch);
|
||||
if (aptr != NULL)
|
||||
{
|
||||
do_alias(aptr, client_p, s);
|
||||
|
@ -391,7 +389,7 @@ handle_encap(struct Client *client_p, struct Client *source_p,
|
|||
|
||||
parv[0] = source_p->name;
|
||||
|
||||
mptr = hash_parse(command);
|
||||
mptr = irc_dictionary_retrieve(cmd_dict, command);
|
||||
|
||||
if(mptr == NULL || mptr->cmd == NULL)
|
||||
return;
|
||||
|
@ -418,7 +416,7 @@ handle_encap(struct Client *client_p, struct Client *source_p,
|
|||
void
|
||||
clear_hash_parse()
|
||||
{
|
||||
memset(msg_hash_table, 0, sizeof(msg_hash_table));
|
||||
cmd_dict = irc_dictionary_create(strcasecmp);
|
||||
}
|
||||
|
||||
/* mod_add_cmd
|
||||
|
@ -433,38 +431,18 @@ clear_hash_parse()
|
|||
void
|
||||
mod_add_cmd(struct Message *msg)
|
||||
{
|
||||
struct MessageHash *ptr;
|
||||
struct MessageHash *last_ptr = NULL;
|
||||
struct MessageHash *new_ptr;
|
||||
int msgindex;
|
||||
|
||||
s_assert(msg != NULL);
|
||||
if(msg == NULL)
|
||||
return;
|
||||
|
||||
msgindex = cmd_hash(msg->cmd);
|
||||
|
||||
for (ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
|
||||
{
|
||||
if(strcasecmp(msg->cmd, ptr->cmd) == 0)
|
||||
return; /* Its already added */
|
||||
last_ptr = ptr;
|
||||
}
|
||||
|
||||
new_ptr = (struct MessageHash *) MyMalloc(sizeof(struct MessageHash));
|
||||
|
||||
new_ptr->next = NULL;
|
||||
DupString(new_ptr->cmd, msg->cmd);
|
||||
new_ptr->msg = msg;
|
||||
if (irc_dictionary_find(cmd_dict, msg->cmd) != NULL)
|
||||
return;
|
||||
|
||||
msg->count = 0;
|
||||
msg->rcount = 0;
|
||||
msg->bytes = 0;
|
||||
|
||||
if(last_ptr == NULL)
|
||||
msg_hash_table[msgindex] = new_ptr;
|
||||
else
|
||||
last_ptr->next = new_ptr;
|
||||
irc_dictionary_add(cmd_dict, msg->cmd, msg);
|
||||
}
|
||||
|
||||
/* mod_del_cmd
|
||||
|
@ -476,101 +454,11 @@ mod_add_cmd(struct Message *msg)
|
|||
void
|
||||
mod_del_cmd(struct Message *msg)
|
||||
{
|
||||
struct MessageHash *ptr;
|
||||
struct MessageHash *last_ptr = NULL;
|
||||
int msgindex;
|
||||
|
||||
s_assert(msg != NULL);
|
||||
if(msg == NULL)
|
||||
return;
|
||||
|
||||
msgindex = cmd_hash(msg->cmd);
|
||||
|
||||
for (ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
|
||||
{
|
||||
if(strcasecmp(msg->cmd, ptr->cmd) == 0)
|
||||
{
|
||||
MyFree(ptr->cmd);
|
||||
if(last_ptr != NULL)
|
||||
last_ptr->next = ptr->next;
|
||||
else
|
||||
msg_hash_table[msgindex] = ptr->next;
|
||||
MyFree(ptr);
|
||||
return;
|
||||
}
|
||||
last_ptr = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* hash_parse
|
||||
*
|
||||
* inputs - command name
|
||||
* output - pointer to struct Message
|
||||
* side effects -
|
||||
*/
|
||||
static struct Message *
|
||||
hash_parse(const char *cmd)
|
||||
{
|
||||
struct MessageHash *ptr;
|
||||
int msgindex;
|
||||
|
||||
msgindex = cmd_hash(cmd);
|
||||
|
||||
for (ptr = msg_hash_table[msgindex]; ptr; ptr = ptr->next)
|
||||
{
|
||||
if(strcasecmp(cmd, ptr->cmd) == 0)
|
||||
return (ptr->msg);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* alias_parse
|
||||
*
|
||||
* inputs - command name
|
||||
* output - pointer to struct Message
|
||||
* side effects -
|
||||
*/
|
||||
static struct alias_entry *
|
||||
alias_parse(const char *cmd)
|
||||
{
|
||||
dlink_node *ptr;
|
||||
int msgindex;
|
||||
|
||||
msgindex = cmd_hash(cmd);
|
||||
|
||||
DLINK_FOREACH(ptr, alias_hash_table[msgindex].head)
|
||||
{
|
||||
struct alias_entry *ent = (struct alias_entry *) ptr->data;
|
||||
|
||||
if(strcasecmp(cmd, ent->name) == 0)
|
||||
return ent;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* hash
|
||||
*
|
||||
* inputs - char string
|
||||
* output - hash index
|
||||
* side effects - NONE
|
||||
*
|
||||
* BUGS - This a HORRIBLE hash function
|
||||
*/
|
||||
static int
|
||||
cmd_hash(const char *p)
|
||||
{
|
||||
int hash_val = 0;
|
||||
|
||||
while (*p)
|
||||
{
|
||||
hash_val += ((int) (*p) & 0xDF);
|
||||
p++;
|
||||
}
|
||||
|
||||
return (hash_val % MAX_MSG_HASH);
|
||||
irc_dictionary_delete(cmd_dict, msg->cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -583,33 +471,25 @@ cmd_hash(const char *p)
|
|||
void
|
||||
report_messages(struct Client *source_p)
|
||||
{
|
||||
int i;
|
||||
struct MessageHash *ptr;
|
||||
dlink_node *pptr;
|
||||
struct DictionaryIter iter;
|
||||
struct Message *msg;
|
||||
struct alias_entry *amsg;
|
||||
|
||||
for (i = 0; i < MAX_MSG_HASH; i++)
|
||||
IRC_DICTIONARY_FOREACH(msg, &iter, cmd_dict)
|
||||
{
|
||||
for (ptr = msg_hash_table[i]; ptr; ptr = ptr->next)
|
||||
{
|
||||
s_assert(ptr->msg != NULL);
|
||||
s_assert(ptr->cmd != NULL);
|
||||
s_assert(msg->cmd != NULL);
|
||||
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
|
||||
form_str(RPL_STATSCOMMANDS),
|
||||
msg->cmd, msg->count,
|
||||
msg->bytes, msg->rcount);
|
||||
}
|
||||
|
||||
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
|
||||
form_str(RPL_STATSCOMMANDS),
|
||||
ptr->cmd, ptr->msg->count,
|
||||
ptr->msg->bytes, ptr->msg->rcount);
|
||||
}
|
||||
|
||||
DLINK_FOREACH(pptr, alias_hash_table[i].head)
|
||||
{
|
||||
struct alias_entry *aptr = (struct alias_entry *) pptr->data;
|
||||
|
||||
s_assert(aptr->name != NULL);
|
||||
|
||||
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
|
||||
form_str(RPL_STATSCOMMANDS),
|
||||
aptr->name, aptr->hits, 0, 0);
|
||||
}
|
||||
IRC_DICTIONARY_FOREACH(amsg, &iter, alias_dict)
|
||||
{
|
||||
s_assert(amsg->name != NULL);
|
||||
sendto_one_numeric(source_p, RPL_STATSCOMMANDS,
|
||||
form_str(RPL_STATSCOMMANDS),
|
||||
amsg->name, amsg->hits, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
28
src/s_conf.c
28
src/s_conf.c
|
@ -1199,6 +1199,19 @@ read_conf_files(int cold)
|
|||
fclose(conf_fbfile_in);
|
||||
}
|
||||
|
||||
/*
|
||||
* free an alias{} entry.
|
||||
*/
|
||||
static void
|
||||
free_alias_cb(struct DictionaryElement *ptr, void *unused)
|
||||
{
|
||||
struct alias_entry *aptr = ptr->data;
|
||||
|
||||
MyFree(aptr->name);
|
||||
MyFree(aptr->target);
|
||||
MyFree(aptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* clear_out_old_conf
|
||||
*
|
||||
|
@ -1269,19 +1282,8 @@ clear_out_old_conf(void)
|
|||
}
|
||||
|
||||
/* remove any aliases... -- nenolod */
|
||||
for (i = 0; i < MAX_MSG_HASH; i++)
|
||||
{
|
||||
DLINK_FOREACH_SAFE(ptr, next_ptr, alias_hash_table[i].head)
|
||||
{
|
||||
struct alias_entry *aptr = ptr->data;
|
||||
|
||||
MyFree(aptr->name);
|
||||
MyFree(aptr->target);
|
||||
MyFree(aptr);
|
||||
|
||||
dlinkDestroy(ptr, &alias_hash_table[i]);
|
||||
}
|
||||
}
|
||||
irc_dictionary_destroy(alias_dict, free_alias_cb, NULL);
|
||||
alias_dict = NULL;
|
||||
|
||||
destroy_blacklists();
|
||||
|
||||
|
|
Loading…
Reference in a new issue