diff options
author | Attila Molnar <attilamolnar@hush.com> | 2014-01-24 13:20:11 +0100 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2014-01-24 13:20:11 +0100 |
commit | 458168b575663dc7bdb71c651c30320752f22e41 (patch) | |
tree | 7946216adbf9bdf252171efde9a7b9dbbe8dae3e | |
parent | 8537a54950a3767e54c0119a819e1ba8f8bced9e (diff) |
Convert InviteBase::invites to an intrusively linked list
-rw-r--r-- | include/channels.h | 2 | ||||
-rw-r--r-- | include/membership.h | 20 | ||||
-rw-r--r-- | include/typedefs.h | 5 | ||||
-rw-r--r-- | include/users.h | 2 | ||||
-rw-r--r-- | src/channels.cpp | 34 |
5 files changed, 27 insertions, 36 deletions
diff --git a/include/channels.h b/include/channels.h index 4f61e15e4..5109c0463 100644 --- a/include/channels.h +++ b/include/channels.h @@ -33,7 +33,7 @@ * This class represents a channel, and contains its name, modes, topic, topic set time, * etc, and an instance of the BanList type. */ -class CoreExport Channel : public Extensible, public InviteBase +class CoreExport Channel : public Extensible, public InviteBase<Channel> { /** Set default modes for the channel on creation */ diff --git a/include/membership.h b/include/membership.h index 723449419..d98b54731 100644 --- a/include/membership.h +++ b/include/membership.h @@ -45,10 +45,11 @@ class CoreExport Membership : public Extensible, public intrusive_list_node<Memb bool SetPrefix(PrefixMode* mh, bool adding); }; -class CoreExport InviteBase +template <typename T> +class InviteBase { protected: - InviteList invites; + intrusive_list<Invitation, T> invites; public: void ClearInvites(); @@ -56,7 +57,7 @@ class CoreExport InviteBase friend class Invitation; }; -class CoreExport Invitation +class CoreExport Invitation : public intrusive_list_node<Invitation, Channel>, public intrusive_list_node<Invitation, LocalUser> { Invitation(Channel* c, LocalUser* u, time_t timeout) : user(u), chan(c), expiry(timeout) {} @@ -69,3 +70,16 @@ class CoreExport Invitation static void Create(Channel* c, LocalUser* u, time_t timeout); static Invitation* Find(Channel* c, LocalUser* u, bool check_expired = true); }; + +typedef intrusive_list<Invitation, LocalUser> InviteList; + +template<typename T> +inline void InviteBase<T>::ClearInvites() +{ + for (typename intrusive_list<Invitation, T>::iterator i = invites.begin(); i != invites.end(); ) + { + Invitation* inv = *i; + ++i; + delete inv; + } +} diff --git a/include/typedefs.h b/include/typedefs.h index 067768db4..77a45ce4e 100644 --- a/include/typedefs.h +++ b/include/typedefs.h @@ -31,7 +31,6 @@ class Extensible; class FakeUser; class InspIRCd; class Invitation; -class InviteBase; class LocalUser; class Membership; class Module; @@ -62,10 +61,6 @@ typedef intrusive_list<LocalUser> LocalUserList; /** A list of failed port bindings, used for informational purposes on startup */ typedef std::vector<std::pair<std::string, std::string> > FailedPortList; -/** Holds a complete list of all channels to which a user has been invited and has not yet joined, and the time at which they'll expire. - */ -typedef std::vector<Invitation*> InviteList; - /** Holds a complete list of all allow and deny tags from the configuration file (connection classes) */ typedef std::vector<reference<ConnectClass> > ClassVector; diff --git a/include/users.h b/include/users.h index db2d53878..6a61b2bc1 100644 --- a/include/users.h +++ b/include/users.h @@ -655,7 +655,7 @@ class CoreExport UserIOHandler : public StreamSocket typedef unsigned int already_sent_t; -class CoreExport LocalUser : public User, public InviteBase, public intrusive_list_node<LocalUser> +class CoreExport LocalUser : public User, public InviteBase<LocalUser>, public intrusive_list_node<LocalUser> { public: LocalUser(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server); diff --git a/src/channels.cpp b/src/channels.cpp index 51a8f5625..392657647 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -828,8 +828,8 @@ void Invitation::Create(Channel* c, LocalUser* u, time_t timeout) else { inv = new Invitation(c, u, timeout); - c->invites.push_back(inv); - u->invites.push_back(inv); + c->invites.push_front(inv); + u->invites.push_front(inv); ServerInstance->Logs->Log("INVITATION", LOG_DEBUG, "Invitation::Create created new invitation %p", (void*) inv); } } @@ -840,19 +840,17 @@ Invitation* Invitation::Find(Channel* c, LocalUser* u, bool check_expired) if (!u || u->invites.empty()) return NULL; - InviteList locallist; - locallist.swap(u->invites); - Invitation* result = NULL; - for (InviteList::iterator i = locallist.begin(); i != locallist.end(); ) + for (InviteList::iterator i = u->invites.begin(); i != u->invites.end(); ) { Invitation* inv = *i; + ++i; + if ((check_expired) && (inv->expiry != 0) && (inv->expiry <= ServerInstance->Time())) { /* Expired invite, remove it. */ std::string expiration = InspIRCd::TimeString(inv->expiry); ServerInstance->Logs->Log("INVITATION", LOG_DEBUG, "Invitation::Find ecountered expired entry: %p expired %s", (void*) inv, expiration.c_str()); - i = locallist.erase(i); delete inv; } else @@ -863,11 +861,9 @@ Invitation* Invitation::Find(Channel* c, LocalUser* u, bool check_expired) result = inv; break; } - ++i; } } - locallist.swap(u->invites); ServerInstance->Logs->Log("INVITATION", LOG_DEBUG, "Invitation::Find result=%p", (void*) result); return result; } @@ -875,21 +871,7 @@ Invitation* Invitation::Find(Channel* c, LocalUser* u, bool check_expired) Invitation::~Invitation() { // Remove this entry from both lists - InviteList::iterator it = std::find(chan->invites.begin(), chan->invites.end(), this); - if (it != chan->invites.end()) - chan->invites.erase(it); - it = std::find(user->invites.begin(), user->invites.end(), this); - if (it != user->invites.end()) - user->invites.erase(it); -} - -void InviteBase::ClearInvites() -{ - ServerInstance->Logs->Log("INVITEBASE", LOG_DEBUG, "InviteBase::ClearInvites %p", (void*) this); - InviteList locallist; - locallist.swap(invites); - for (InviteList::const_iterator i = locallist.begin(); i != locallist.end(); ++i) - { - delete *i; - } + chan->invites.erase(this); + user->invites.erase(this); + ServerInstance->Logs->Log("INVITEBASE", LOG_DEBUG, "Invitation::~ %p", (void*) this); } |