diff options
author | Attila Molnar <attilamolnar@hush.com> | 2014-01-24 12:58:01 +0100 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2014-01-24 12:58:01 +0100 |
commit | 932e8d13f81c7c94a89dc3702f6d45bc185f5dcf (patch) | |
tree | cb50264af2ff50ccf8070ce9123ee350d95ff7f8 | |
parent | 9a962e1c512ffc00bcfce105e9dbdabd9abcdd86 (diff) |
Convert UserChanList to an intrusively linked list
-rw-r--r-- | include/inspircd.h | 1 | ||||
-rw-r--r-- | include/membership.h | 3 | ||||
-rw-r--r-- | include/modules.h | 2 | ||||
-rw-r--r-- | include/typedefs.h | 6 | ||||
-rw-r--r-- | src/channels.cpp | 6 | ||||
-rw-r--r-- | src/commands/cmd_who.cpp | 5 | ||||
-rw-r--r-- | src/commands/cmd_whois.cpp | 2 | ||||
-rw-r--r-- | src/modules.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_auditorium.cpp | 18 | ||||
-rw-r--r-- | src/modules/m_channelban.cpp | 10 | ||||
-rw-r--r-- | src/modules/m_check.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_delayjoin.cpp | 16 | ||||
-rw-r--r-- | src/modules/m_hostcycle.cpp | 8 | ||||
-rw-r--r-- | src/modules/m_ircv3.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_nickflood.cpp | 4 | ||||
-rw-r--r-- | src/modules/m_nonicks.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_operprefix.cpp | 2 | ||||
-rw-r--r-- | src/users.cpp | 21 |
18 files changed, 59 insertions, 57 deletions
diff --git a/include/inspircd.h b/include/inspircd.h index 7a8c1fb74..897ae9e18 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -43,6 +43,7 @@ #include <string> #include <vector> +#include "intrusive_list.h" #include "compat.h" #include "typedefs.h" diff --git a/include/membership.h b/include/membership.h index 78af85fde..b0924bef7 100644 --- a/include/membership.h +++ b/include/membership.h @@ -1,6 +1,7 @@ /* * InspIRCd -- Internet Relay Chat Daemon * + * Copyright (C) 2012-2014 Attila Molnar <attilamolnar@hush.com> * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org> * * This file is part of InspIRCd. InspIRCd is free software: you can @@ -19,7 +20,7 @@ #pragma once -class CoreExport Membership : public Extensible +class CoreExport Membership : public Extensible, public intrusive_list_node<Membership> { public: User* const user; diff --git a/include/modules.h b/include/modules.h index 7223f6b9d..d221803ab 100644 --- a/include/modules.h +++ b/include/modules.h @@ -556,7 +556,7 @@ class CoreExport Module : public classbase, public usecountbase * * Set exceptions[user] = true to include, exceptions[user] = false to exclude */ - virtual void OnBuildNeighborList(User* source, UserChanList &include_c, std::map<User*,bool> &exceptions); + virtual void OnBuildNeighborList(User* source, IncludeChanList& include_c, std::map<User*, bool>& exceptions); /** Called before any nickchange, local or remote. This can be used to implement Q-lines etc. * Please note that although you can see remote nickchanges through this function, you should diff --git a/include/typedefs.h b/include/typedefs.h index 3801a48c0..050707e73 100644 --- a/include/typedefs.h +++ b/include/typedefs.h @@ -72,12 +72,16 @@ typedef std::vector<reference<ConnectClass> > ClassVector; /** Typedef for the list of user-channel records for a user */ -typedef std::set<Channel*> UserChanList; +typedef intrusive_list<Membership> UserChanList; /** Shorthand for an iterator into a UserChanList */ typedef UserChanList::iterator UCListIter; +/** List of channels to consider when building the neighbor list of a user + */ +typedef std::vector<Membership*> IncludeChanList; + /** A list of custom modes parameters on a channel */ typedef std::map<char,std::string> CustomModeList; diff --git a/src/channels.cpp b/src/channels.cpp index 5865f6724..7763febd5 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -331,7 +331,7 @@ void Channel::ForceJoin(User* user, const std::string* privs, bool bursting, boo if (!memb) return; // Already on the channel - user->chans.insert(this); + user->chans.push_front(memb); if (privs) { @@ -466,7 +466,7 @@ void Channel::PartUser(User *user, std::string &reason) WriteAllExcept(user, false, 0, except_list, "PART %s%s%s", this->name.c_str(), reason.empty() ? "" : " :", reason.c_str()); // Remove this channel from the user's chanlist - user->chans.erase(this); + user->chans.erase(memb); // Remove the Membership from this channel's userlist and destroy it this->DelUser(membiter); } @@ -520,7 +520,7 @@ void Channel::KickUser(User* src, User* victim, const std::string& reason, Membe WriteAllExcept(src, false, 0, except_list, "KICK %s %s :%s", name.c_str(), victim->nick.c_str(), reason.c_str()); - victim->chans.erase(this); + victim->chans.erase(memb); this->DelUser(victimiter); } diff --git a/src/commands/cmd_who.cpp b/src/commands/cmd_who.cpp index a059a3f9c..37a04af83 100644 --- a/src/commands/cmd_who.cpp +++ b/src/commands/cmd_who.cpp @@ -45,10 +45,9 @@ class CommandWho : public Command Channel* get_first_visible_channel(User *u) { - UCListIter i = u->chans.begin(); - while (i != u->chans.end()) + for (UCListIter i = u->chans.begin(); i != u->chans.end(); ++i) { - Channel* c = *i++; + Channel* c = (*i)->chan; if (!c->IsModeSet(secretmode)) return c; } diff --git a/src/commands/cmd_whois.cpp b/src/commands/cmd_whois.cpp index e8a751fa0..29322f802 100644 --- a/src/commands/cmd_whois.cpp +++ b/src/commands/cmd_whois.cpp @@ -65,7 +65,7 @@ std::string CommandWhois::ChannelList(User* source, User* dest, bool spy) for (UCListIter i = dest->chans.begin(); i != dest->chans.end(); i++) { - Channel* c = *i; + Channel* c = (*i)->chan; /* If the target is the sender, neither +p nor +s is set, or * the channel contains the user, it is not a spy channel */ diff --git a/src/modules.cpp b/src/modules.cpp index c70a99d77..22047ce81 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -147,7 +147,7 @@ ModResult Module::OnChannelPreDelete(Channel*) { DetachEvent(I_OnChannelPreDelet void Module::OnChannelDelete(Channel*) { DetachEvent(I_OnChannelDelete); } ModResult Module::OnSetAway(User*, const std::string &) { DetachEvent(I_OnSetAway); return MOD_RES_PASSTHRU; } ModResult Module::OnWhoisLine(User*, User*, int&, std::string&) { DetachEvent(I_OnWhoisLine); return MOD_RES_PASSTHRU; } -void Module::OnBuildNeighborList(User*, UserChanList&, std::map<User*,bool>&) { DetachEvent(I_OnBuildNeighborList); } +void Module::OnBuildNeighborList(User*, IncludeChanList&, std::map<User*,bool>&) { DetachEvent(I_OnBuildNeighborList); } void Module::OnGarbageCollect() { DetachEvent(I_OnGarbageCollect); } ModResult Module::OnSetConnectClass(LocalUser* user, ConnectClass* myclass) { DetachEvent(I_OnSetConnectClass); return MOD_RES_PASSTHRU; } void Module::OnText(User*, void*, int, const std::string&, char, CUList&) { DetachEvent(I_OnText); } diff --git a/src/modules/m_auditorium.cpp b/src/modules/m_auditorium.cpp index 502a9fb9f..62aa7ec75 100644 --- a/src/modules/m_auditorium.cpp +++ b/src/modules/m_auditorium.cpp @@ -129,19 +129,21 @@ class ModuleAuditorium : public Module BuildExcept(memb, excepts); } - void OnBuildNeighborList(User* source, UserChanList &include, std::map<User*,bool> &exception) CXX11_OVERRIDE + void OnBuildNeighborList(User* source, IncludeChanList& include, std::map<User*, bool>& exception) CXX11_OVERRIDE { - UCListIter i = include.begin(); - while (i != include.end()) + for (IncludeChanList::iterator i = include.begin(); i != include.end(); ) { - Channel* c = *i++; - Membership* memb = c->GetUser(source); - if (!memb || IsVisible(memb)) + Membership* memb = *i; + if (IsVisible(memb)) + { + ++i; continue; + } + // this channel should not be considered when listing my neighbors - include.erase(c); + i = include.erase(i); // however, that might hide me from ops that can see me... - const UserMembList* users = c->GetUsers(); + const UserMembList* users = memb->chan->GetUsers(); for(UserMembCIter j = users->begin(); j != users->end(); j++) { if (IS_LOCAL(j->first) && CanSee(j->first, memb)) diff --git a/src/modules/m_channelban.cpp b/src/modules/m_channelban.cpp index 3260c0fa4..300caa123 100644 --- a/src/modules/m_channelban.cpp +++ b/src/modules/m_channelban.cpp @@ -42,15 +42,9 @@ class ModuleBadChannelExtban : public Module } for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) { - if (InspIRCd::Match((**i).name, rm)) + if (InspIRCd::Match((*i)->chan->name, rm)) { - if (status) - { - Membership* memb = (**i).GetUser(user); - if (memb && memb->hasMode(status)) - return MOD_RES_DENY; - } - else + if (!status || (*i)->hasMode(status)) return MOD_RES_DENY; } } diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp index d12d2728d..c72f88faa 100644 --- a/src/modules/m_check.cpp +++ b/src/modules/m_check.cpp @@ -192,7 +192,7 @@ class CommandCheck : public Command for (UCListIter i = targuser->chans.begin(); i != targuser->chans.end(); i++) { - Channel* c = *i; + Channel* c = (*i)->chan; chliststr.append(c->GetPrefixChar(targuser)).append(c->name).append(" "); } diff --git a/src/modules/m_delayjoin.cpp b/src/modules/m_delayjoin.cpp index 70c6b8717..e183fbe46 100644 --- a/src/modules/m_delayjoin.cpp +++ b/src/modules/m_delayjoin.cpp @@ -50,7 +50,7 @@ class ModuleDelayJoin : public Module void CleanUser(User* user); void OnUserPart(Membership*, std::string &partmessage, CUList&) CXX11_OVERRIDE; void OnUserKick(User* source, Membership*, const std::string &reason, CUList&) CXX11_OVERRIDE; - void OnBuildNeighborList(User* source, UserChanList &include, std::map<User*,bool> &exception) CXX11_OVERRIDE; + void OnBuildNeighborList(User* source, IncludeChanList& include, std::map<User*, bool>& exception) CXX11_OVERRIDE; void OnText(User* user, void* dest, int target_type, const std::string &text, char status, CUList &exempt_list) CXX11_OVERRIDE; ModResult OnRawMode(User* user, Channel* channel, const char mode, const std::string ¶m, bool adding, int pcnt) CXX11_OVERRIDE; }; @@ -123,15 +123,15 @@ void ModuleDelayJoin::OnUserKick(User* source, Membership* memb, const std::stri populate(except, memb); } -void ModuleDelayJoin::OnBuildNeighborList(User* source, UserChanList &include, std::map<User*,bool> &exception) +void ModuleDelayJoin::OnBuildNeighborList(User* source, IncludeChanList& include, std::map<User*, bool>& exception) { - UCListIter i = include.begin(); - while (i != include.end()) + for (IncludeChanList::iterator i = include.begin(); i != include.end(); ) { - Channel* c = *i++; - Membership* memb = c->GetUser(source); - if (memb && unjoined.get(memb)) - include.erase(c); + Membership* memb = *i; + if (unjoined.get(memb)) + i = include.erase(i); + else + ++i; } } diff --git a/src/modules/m_hostcycle.cpp b/src/modules/m_hostcycle.cpp index 79b4169ec..d3646e899 100644 --- a/src/modules/m_hostcycle.cpp +++ b/src/modules/m_hostcycle.cpp @@ -32,7 +32,7 @@ class ModuleHostCycle : public Module already_sent_t silent_id = ++LocalUser::already_sent_id; already_sent_t seen_id = ++LocalUser::already_sent_id; - UserChanList include_chans(user->chans); + IncludeChanList include_chans(user->chans.begin(), user->chans.end()); std::map<User*,bool> exceptions; FOREACH_MOD(OnBuildNeighborList, (user, include_chans, exceptions)); @@ -56,10 +56,10 @@ class ModuleHostCycle : public Module std::string newfullhost = user->nick + "!" + newident + "@" + newhost; - for (UCListIter i = include_chans.begin(); i != include_chans.end(); ++i) + for (IncludeChanList::const_iterator i = include_chans.begin(); i != include_chans.end(); ++i) { - Channel* c = *i; - Membership* memb = c->GetUser(user); + Membership* memb = *i; + Channel* c = memb->chan; const std::string joinline = ":" + newfullhost + " JOIN " + c->name; std::string modeline; diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp index e8018aea6..5cb2ab6b1 100644 --- a/src/modules/m_ircv3.cpp +++ b/src/modules/m_ircv3.cpp @@ -33,7 +33,7 @@ class ModuleIRCv3 : public Module void WriteNeighboursWithExt(User* user, const std::string& line, const LocalIntExt& ext) { - UserChanList chans(user->chans); + IncludeChanList chans(user->chans.begin(), user->chans.end()); std::map<User*, bool> exceptions; FOREACH_MOD(OnBuildNeighborList, (user, chans, exceptions)); @@ -48,9 +48,9 @@ class ModuleIRCv3 : public Module // Now consider sending it to all other users who has at least a common channel with the user std::set<User*> already_sent; - for (UCListIter i = chans.begin(); i != chans.end(); ++i) + for (IncludeChanList::const_iterator i = chans.begin(); i != chans.end(); ++i) { - const UserMembList* userlist = (*i)->GetUsers(); + const UserMembList* userlist = (*i)->chan->GetUsers(); for (UserMembList::const_iterator m = userlist->begin(); m != userlist->end(); ++m) { /* diff --git a/src/modules/m_nickflood.cpp b/src/modules/m_nickflood.cpp index c3cff2cd1..93fbbfaaa 100644 --- a/src/modules/m_nickflood.cpp +++ b/src/modules/m_nickflood.cpp @@ -140,7 +140,7 @@ class ModuleNickFlood : public Module { for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) { - Channel *channel = *i; + Channel* channel = (*i)->chan; ModResult res; nickfloodsettings *f = nf.ext.get(channel); @@ -179,7 +179,7 @@ class ModuleNickFlood : public Module for (UCListIter i = user->chans.begin(); i != user->chans.end(); ++i) { - Channel *channel = *i; + Channel* channel = (*i)->chan; ModResult res; nickfloodsettings *f = nf.ext.get(channel); diff --git a/src/modules/m_nonicks.cpp b/src/modules/m_nonicks.cpp index a41f50901..15ee4e7f8 100644 --- a/src/modules/m_nonicks.cpp +++ b/src/modules/m_nonicks.cpp @@ -53,7 +53,7 @@ class ModuleNoNickChange : public Module for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++) { - Channel* curr = *i; + Channel* curr = (*i)->chan; ModResult res = ServerInstance->OnCheckExemption(user,curr,"nonick"); diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp index c84e74892..4fb4ae942 100644 --- a/src/modules/m_operprefix.cpp +++ b/src/modules/m_operprefix.cpp @@ -81,7 +81,7 @@ class ModuleOperPrefixMode : public Module modechange.push_back(user->nick); for (UCListIter v = user->chans.begin(); v != user->chans.end(); v++) { - modechange[0] = (*v)->name; + modechange[0] = (*v)->chan->name; ServerInstance->Modes->Process(modechange, ServerInstance->FakeClient); } } diff --git a/src/users.cpp b/src/users.cpp index c855dcad0..df42d2a9c 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -682,7 +682,7 @@ bool User::ChangeNick(const std::string& newnick, bool force) { for (UCListIter i = this->chans.begin(); i != this->chans.end(); i++) { - Channel *chan = *i; + Channel* chan = (*i)->chan; if (chan->GetPrefixValue(this) < VOICE_VALUE && chan->IsBanned(this)) { this->WriteNumeric(ERR_CANNOTSENDTOCHAN, "%s :Cannot send to channel (you're banned)", chan->name.c_str()); @@ -962,7 +962,7 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) LocalUser::already_sent_id++; - UserChanList include_c(chans); + IncludeChanList include_c(chans.begin(), chans.end()); std::map<User*,bool> exceptions; exceptions[this] = include_self; @@ -979,9 +979,9 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) u->Write(line); } } - for (UCListIter v = include_c.begin(); v != include_c.end(); ++v) + for (IncludeChanList::const_iterator v = include_c.begin(); v != include_c.end(); ++v) { - Channel* c = *v; + Channel* c = (*v)->chan; const UserMembList* ulist = c->GetUsers(); for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { @@ -1005,7 +1005,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op const std::string normalMessage = ":" + this->GetFullHost() + " QUIT :" + normal_text; const std::string operMessage = ":" + this->GetFullHost() + " QUIT :" + oper_text; - UserChanList include_c(chans); + IncludeChanList include_c(chans.begin(), chans.end()); std::map<User*,bool> exceptions; FOREACH_MOD(OnBuildNeighborList, (this, include_c, exceptions)); @@ -1020,9 +1020,9 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op u->Write(u->IsOper() ? operMessage : normalMessage); } } - for (UCListIter v = include_c.begin(); v != include_c.end(); ++v) + for (IncludeChanList::const_iterator v = include_c.begin(); v != include_c.end(); ++v) { - const UserMembList* ulist = (*v)->GetUsers(); + const UserMembList* ulist = (*v)->chan->GetUsers(); for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { LocalUser* u = IS_LOCAL(i->first); @@ -1096,7 +1096,7 @@ bool User::SharesChannelWith(User *other) /* 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 */ - if ((*i)->HasUser(other)) + if ((*i)->chan->HasUser(other)) return true; } return false; @@ -1277,9 +1277,10 @@ void LocalUser::SetClass(const std::string &explicit_name) void User::PurgeEmptyChannels() { // firstly decrement the count on each channel - for (UCListIter f = this->chans.begin(); f != this->chans.end(); f++) + for (UCListIter i = this->chans.begin(); i != this->chans.end(); ) { - Channel* c = *f; + Channel* c = (*i)->chan; + ++i; c->DelUser(this); } |