summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2005-04-26 17:01:59 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2005-04-26 17:01:59 +0000
commit6d56b904fc9bf79dc954d2bd02ce7cc99f99b479 (patch)
tree25308fc368e2a6a5e602e71c674362903e0c3cfa
parent4327b13b6fe651261a8877e7a79cfd2752563ccb (diff)
Major *MAJOR* optimizations by double-referencing channels to users
(never need to scan the entire user hash again except in very rare circumstances) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@1197 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/channels.h8
-rw-r--r--src/channels.cpp26
-rw-r--r--src/inspircd.cpp299
3 files changed, 249 insertions, 84 deletions
diff --git a/include/channels.h b/include/channels.h
index 9b74c546d..3f5c69dff 100644
--- a/include/channels.h
+++ b/include/channels.h
@@ -105,6 +105,11 @@ class chanrec : public Extensible
/** Count of users on the channel used for fast user counting
*/
long users;
+
+ /** User list (casted to char*'s to stop forward declaration stuff)
+ * (chicken and egg scenario!)
+ */
+ std::vector<char*> internal_userlist;
/** Channel topic.
* If this is an empty string, no channel topic is set.
@@ -186,6 +191,9 @@ class chanrec : public Extensible
void DecUserCounter();
long GetUserCounter();
+ void AddUser(char* castuser);
+ void DelUser(char* castuser);
+ std::vector<char*> *GetUsers();
/** Creates a channel record and initialises it with default values
*/
diff --git a/src/channels.cpp b/src/channels.cpp
index 41ca0468f..b586871ea 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -119,6 +119,7 @@ chanrec::chanrec()
strcpy(key,"");
created = topicset = limit = users = 0;
topiclock = noexternal = inviteonly = moderated = secret = c_private = false;
+ internal_userlist.clear();
}
void chanrec::SetCustomMode(char mode,bool mode_on)
@@ -215,3 +216,28 @@ long chanrec::GetUserCounter()
{
return (this->users);
}
+
+void chanrec::AddUser(char* castuser)
+{
+ internal_userlist.push_back(castuser);
+ log(DEBUG,"Added casted user to channel's internal list");
+}
+
+void chanrec::DelUser(char* castuser)
+{
+ for (std::vector<char*>::iterator a = internal_userlist.begin(); a < internal_userlist.end(); a++)
+ {
+ if (*a == castuser)
+ {
+ log(DEBUG,"Removed casted user from channel's internal list");
+ internal_userlist.erase(a);
+ return;
+ }
+ }
+ log(DEBUG,"BUG BUG BUG! Attempt to remove an uncasted user from the internal list of %s!",name);
+}
+
+std::vector<char*> *chanrec::GetUsers()
+{
+ return &internal_userlist;
+}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index b28dd9281..015f07b3a 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -661,14 +661,31 @@ void WriteChannel(chanrec* Ptr, userrec* user, char* text, ...)
va_start (argsPtr, text);
vsnprintf(textbuffer, MAXBUF, text, argsPtr);
va_end(argsPtr);
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- if (has_channel(i->second,Ptr))
- {
- if (i->second->fd != FD_MAGIC_NUMBER)
- WriteTo(user,i->second,"%s",textbuffer);
+
+ for (int i = 0; i < MAXCHANS; i++)
+ {
+ if (user->chans[i].channel == Ptr)
+ {
+ std::vector<char*> *ulist = user->chans[i].channel->GetUsers();
+ for (int j = 0; j < ulist->size(); j++)
+ {
+ char* o = (*ulist)[j];
+ userrec* otheruser = (userrec*)o;
+ if (otheruser->fd != FD_MAGIC_NUMBER)
+ WriteTo(user,otheruser,"%s",textbuffer);
+ }
}
}
+
+
+ //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
+ //{
+ // if (has_channel(i->second,Ptr))
+ // {
+ // if (i->second->fd != FD_MAGIC_NUMBER)
+ // WriteTo(user,i->second,"%s",textbuffer);
+ // }
+ //}
}
/* write formatted text from a source user to all users on a channel
@@ -687,23 +704,40 @@ void WriteChannelLocal(chanrec* Ptr, userrec* user, char* text, ...)
va_start (argsPtr, text);
vsnprintf(textbuffer, MAXBUF, text, argsPtr);
va_end(argsPtr);
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- if (has_channel(i->second,Ptr))
- {
- if ((i->second->fd != -1) && (i->second->fd != FD_MAGIC_NUMBER))
- {
- if (!user)
- {
- WriteServ(i->second->fd,"%s",textbuffer);
- }
- else
- {
- WriteTo(user,i->second,"%s",textbuffer);
- }
- }
- }
- }
+
+ for (int i = 0; i < MAXCHANS; i++)
+ {
+ if (user->chans[i].channel == Ptr)
+ {
+ std::vector<char*> *ulist = user->chans[i].channel->GetUsers();
+ for (int j = 0; j < ulist->size(); j++)
+ {
+ char* o = (*ulist)[j];
+ userrec* otheruser = (userrec*)o;
+ if ((otheruser->fd != FD_MAGIC_NUMBER) && (otheruser->fd != -1))
+ WriteTo(user,otheruser,"%s",textbuffer);
+ }
+ }
+ }
+
+
+ //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
+ //{
+ // if (has_channel(i->second,Ptr))
+ // {
+ // if ((i->second->fd != -1) && (i->second->fd != FD_MAGIC_NUMBER))
+ // {
+ // if (!user)
+ // {
+ // WriteServ(i->second->fd,"%s",textbuffer);
+ // }
+ // else
+ // {
+ // WriteTo(user,i->second,"%s",textbuffer);
+ // }
+ // }
+ // }
+ //}
}
@@ -719,16 +753,35 @@ void WriteChannelWithServ(char* ServName, chanrec* Ptr, userrec* user, char* tex
va_start (argsPtr, text);
vsnprintf(textbuffer, MAXBUF, text, argsPtr);
va_end(argsPtr);
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- if (i->second)
- {
- if ((has_channel(i->second,Ptr)) && (i->second->fd != FD_MAGIC_NUMBER))
- {
- WriteServ(i->second->fd,"%s",textbuffer);
- }
- }
- }
+
+
+ for (int i = 0; i < MAXCHANS; i++)
+ {
+ if (user->chans[i].channel == Ptr)
+ {
+ std::vector<char*> *ulist = user->chans[i].channel->GetUsers();
+ for (int j = 0; j < ulist->size(); j++)
+ {
+ char* o = (*ulist)[j];
+ userrec* otheruser = (userrec*)o;
+ if (otheruser->fd != FD_MAGIC_NUMBER)
+ WriteServ(otheruser->fd,"%s",textbuffer);
+ }
+ }
+ }
+
+
+
+ //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
+ //{
+ // if (i->second)
+ // {
+ // if ((has_channel(i->second,Ptr)) && (i->second->fd != FD_MAGIC_NUMBER))
+ // {
+ // WriteServ(i->second->fd,"%s",textbuffer);
+ // }
+ // }
+ //}
}
@@ -748,16 +801,31 @@ void ChanExceptSender(chanrec* Ptr, userrec* user, char* text, ...)
vsnprintf(textbuffer, MAXBUF, text, argsPtr);
va_end(argsPtr);
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- if (i->second)
- {
- if ((has_channel(i->second,Ptr)) && (user != i->second) && (i->second->fd != FD_MAGIC_NUMBER))
- {
- WriteTo(user,i->second,"%s",textbuffer);
- }
- }
- }
+ for (int i = 0; i < MAXCHANS; i++)
+ {
+ if (user->chans[i].channel == Ptr)
+ {
+ std::vector<char*> *ulist = user->chans[i].channel->GetUsers();
+ for (int j = 0; j < ulist->size(); j++)
+ {
+ char* o = (*ulist)[j];
+ userrec* otheruser = (userrec*)o;
+ if ((otheruser->fd != FD_MAGIC_NUMBER) && (user != otheruser))
+ WriteFrom(otheruser->fd,user,"%s",textbuffer);
+ }
+ }
+ }
+
+ //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
+ //{
+ // if (i->second)
+ // {
+ // if ((has_channel(i->second,Ptr)) && (user != i->second) && (i->second->fd != FD_MAGIC_NUMBER))
+ // {
+ // WriteTo(user,i->second,"%s",textbuffer);
+ // }
+ // }
+ //}
}
@@ -804,16 +872,30 @@ void WriteCommon(userrec *u, char* text, ...)
WriteFrom(u->fd,u,"%s",textbuffer);
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- if (i->second)
- {
- if ((common_channels(u,i->second) && (i->second != u)) && (i->second->fd != FD_MAGIC_NUMBER))
- {
- WriteFrom(i->second->fd,u,"%s",textbuffer);
- }
- }
- }
+ for (int i = 0; i < MAXCHANS; i++)
+ {
+ if (u->chans[i].channel)
+ {
+ std::vector<char*> *ulist = u->chans[i].channel->GetUsers();
+ for (int j = 0; j < ulist->size(); j++)
+ {
+ char* o = (*ulist)[j];
+ userrec* otheruser = (userrec*)o;
+ WriteFrom(otheruser->fd,u,"%s",textbuffer);
+ }
+ }
+ }
+
+ //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
+ //{
+ // if (i->second)
+ // {
+ // if ((common_channels(u,i->second) && (i->second != u)) && (i->second->fd != FD_MAGIC_NUMBER))
+ // {
+ // WriteFrom(i->second->fd,u,"%s",textbuffer);
+ // }
+ // }
+ //}
}
/* write a formatted string to all users who share at least one common
@@ -838,16 +920,31 @@ void WriteCommonExcept(userrec *u, char* text, ...)
vsnprintf(textbuffer, MAXBUF, text, argsPtr);
va_end(argsPtr);
- for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- if (i->second)
- {
- if ((common_channels(u,i->second)) && (u != i->second))
- {
- WriteFrom(i->second->fd,u,"%s",textbuffer);
- }
- }
- }
+ for (int i = 0; i < MAXCHANS; i++)
+ {
+ if (u->chans[i].channel)
+ {
+ std::vector<char*> *ulist = u->chans[i].channel->GetUsers();
+ for (int j = 0; j < ulist->size(); j++)
+ {
+ char* o = (*ulist)[j];
+ userrec* otheruser = (userrec*)o;
+ if (u != otheruser)
+ WriteFrom(otheruser->fd,u,"%s",textbuffer);
+ }
+ }
+ }
+
+ //for (user_hash::const_iterator i = clientlist.begin(); i != clientlist.end(); i++)
+ //{
+ // if (i->second)
+ // {
+ // if ((common_channels(u,i->second)) && (u != i->second))
+ // {
+ // WriteFrom(i->second->fd,u,"%s",textbuffer);
+ // }
+ // }
+ //}
}
void WriteOpers(char* text, ...)
@@ -886,16 +983,27 @@ void WriteOpers(char* text, ...)
bool ChanAnyOnThisServer(chanrec *c,char* servername)
{
log(DEBUG,"ChanAnyOnThisServer");
- for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- if (has_channel(i->second,c))
- {
- if (!strcasecmp(i->second->server,servername))
- {
- return true;
- }
- }
- }
+
+ std::vector<char*> *ulist = c->GetUsers();
+ for (int j = 0; j < ulist->size(); j++)
+ {
+ char* o = (*ulist)[j];
+ userrec* user = (userrec*)o;
+ if (!strcasecmp(user->server,servername))
+ return true;
+ }
+ return false;
+
+ //for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
+ //{
+ // if (has_channel(i->second,c))
+ // {
+ // if (!strcasecmp(i->second->server,servername))
+ // {
+ // return true;
+ // }
+ // }
+ //}
return false;
}
@@ -904,18 +1012,35 @@ bool ChanAnyOnThisServer(chanrec *c,char* servername)
bool CommonOnThisServer(userrec* u,const char* servername)
{
log(DEBUG,"ChanAnyOnThisServer");
- for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
- {
- if ((common_channels(u,i->second)) && (u != i->second))
- {
- if (!strcasecmp(i->second->server,servername))
- {
- log(DEBUG,"%s is common to %s sharing with %s",i->second->nick,servername,u->nick);
- return true;
- }
- }
- }
+
+ for (int i = 0; i < MAXCHANS; i++)
+ {
+ if (u->chans[i].channel)
+ {
+ std::vector<char*> *ulist = u->chans[i].channel->GetUsers();
+ for (int j = 0; j < ulist->size(); j++)
+ {
+ char* o = (*ulist)[j];
+ userrec* user = (userrec*)o;
+ if (!strcasecmp(user->server,servername))
+ return true;
+ }
+ }
+ }
return false;
+
+ //for (user_hash::iterator i = clientlist.begin(); i != clientlist.end(); i++)
+ //{
+ // if ((common_channels(u,i->second)) && (u != i->second))
+ // {
+ // if (!strcasecmp(i->second->server,servername))
+ // {
+ // log(DEBUG,"%s is common to %s sharing with %s",i->second->nick,servername,u->nick);
+ // return true;
+ // }
+ // }
+ //}
+ //return false;
}
@@ -1227,7 +1352,10 @@ void purge_empty_chans(userrec* u)
// firstly decrement the count on each channel
for (int f = 0; f < MAXCHANS; f++)
if (u->chans[f].channel)
+ {
u->chans[f].channel->DecUserCounter();
+ u->chans[f].channel->DelUser((char*)u);
+ }
for (int i = 0; i < MAXCHANS; i++)
{
@@ -1634,6 +1762,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
}
user->chans[index].channel = Ptr;
Ptr->IncUserCounter();
+ Ptr->AddUser((char*)user);
WriteChannel(Ptr,user,"JOIN :%s",Ptr->name);
if (!override) // we're not overriding... so this isnt part of a netburst, broadcast it.
@@ -1736,6 +1865,7 @@ chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool
}
Ptr->DecUserCounter();
+ Ptr->DelUser((char*)user);
/* if there are no users left on the channel */
if (!usercount(Ptr))
@@ -1820,6 +1950,7 @@ void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason)
}
Ptr->DecUserCounter();
+ Ptr->DelUser((char*)user);
/* if there are no users left on the channel */
if (!usercount(Ptr))