]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Convert InviteBase::invites to an intrusively linked list
authorAttila Molnar <attilamolnar@hush.com>
Fri, 24 Jan 2014 12:20:11 +0000 (13:20 +0100)
committerAttila Molnar <attilamolnar@hush.com>
Fri, 24 Jan 2014 12:20:11 +0000 (13:20 +0100)
include/channels.h
include/membership.h
include/typedefs.h
include/users.h
src/channels.cpp

index 4f61e15e40edfed741d208af60d63f0888cd659e..5109c046318f216168d279632d32c3e5ea1dfbb9 100644 (file)
@@ -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
         */
index 723449419727be15c66f55633c3fc5594d2943ea..d98b54731884cd31d12f641e9ddd42c6a6be0a5f 100644 (file)
@@ -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;
+       }
+}
index 067768db4e2d703f3aea955ee4de1e11a11e8de1..77a45ce4e4f1c2b7ffd01099051af716b28bf8b4 100644 (file)
@@ -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;
index db2d538785c9378a6367642f5adf22a680ea5c27..6a61b2bc1b5015eca081fa3caf774e7f92d20b0b 100644 (file)
@@ -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);
index 51a8f5625c920928c862c3b845718449438a1e83..39265764738e7b35aa8c39b9778d1e60c7fdb259 100644 (file)
@@ -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);
 }