mirror of
https://github.com/inspircd/inspircd.git
synced 2025-04-21 23:41:27 -04:00
Optimize common_channels
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@4567 e03df62e-2008-0410-955e-edbf42e46eb7
This commit is contained in:
parent
2696e5f05d
commit
e2495e9748
@ -49,30 +49,39 @@ extern time_t TIME;
|
||||
extern ServerConfig* Config;
|
||||
|
||||
/* return 0 or 1 depending if users u and u2 share one or more common channels
|
||||
* (used by QUIT, NICK etc which arent channel specific notices) */
|
||||
|
||||
* (used by QUIT, NICK etc which arent channel specific notices)
|
||||
*
|
||||
* The old algorithm in 1.0 for this was relatively inefficient, iterating over
|
||||
* the first users channels then the second users channels within the outer loop,
|
||||
* therefore it was a maximum of x*y iterations (upon returning 0 and checking
|
||||
* all possible iterations). However this new function instead checks against the
|
||||
* channel's userlist in the inner loop which is a std::map<userrec*,userrec*>
|
||||
* and saves us time as we already know what pointer value we are after.
|
||||
* Don't quote me on the maths as i am not a mathematician or computer scientist,
|
||||
* but i believe this algorithm is now x+(log y) maximum iterations instead.
|
||||
*/
|
||||
int common_channels(userrec *u, userrec *u2)
|
||||
{
|
||||
/* TODO: We need to get rid of this arbitary '7' and make bitmask enums for it */
|
||||
if ((!u) || (!u2) || (u->registered != 7) || (u2->registered != 7))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Outer loop */
|
||||
for (std::vector<ucrec*>::const_iterator i = u->chans.begin(); i != u->chans.end(); i++)
|
||||
{
|
||||
for (std::vector<ucrec*>::const_iterator z = u2->chans.begin(); z != u2->chans.end(); z++)
|
||||
{
|
||||
if ((((ucrec*)(*i))->channel != NULL) && (((ucrec*)(*z))->channel != NULL))
|
||||
{
|
||||
if ((((ucrec*)(*i))->channel == ((ucrec*)(*z))->channel))
|
||||
{
|
||||
if ((c_count(u)) && (c_count(u2)))
|
||||
/* Fetch the channel from the user */
|
||||
ucrec* user_channel = (ucrec*)(*i);
|
||||
|
||||
if (user_channel->channel)
|
||||
{
|
||||
/* Eliminate the inner loop (which used to be ~equal in size to the outer loop)
|
||||
* by replacing it with a map::find which *should* be more efficient
|
||||
*/
|
||||
CUList* channel_user_map = user_channel->channel->GetUsers();
|
||||
if (channel_user_map->find(u2) != channel_user_map->end())
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user