diff options
author | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2005-04-26 17:01:59 +0000 |
---|---|---|
committer | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2005-04-26 17:01:59 +0000 |
commit | 6d56b904fc9bf79dc954d2bd02ce7cc99f99b479 (patch) | |
tree | 25308fc368e2a6a5e602e71c674362903e0c3cfa | |
parent | 4327b13b6fe651261a8877e7a79cfd2752563ccb (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.h | 8 | ||||
-rw-r--r-- | src/channels.cpp | 26 | ||||
-rw-r--r-- | src/inspircd.cpp | 299 |
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)) |