Quellcode durchsuchen

Store members in a hash for quicker ismember() lookup

Bryan Drewery vor 7 Jahren
Ursprung
Commit
9f51b1fe7b
6 geänderte Dateien mit 26 neuen und 14 gelöschten Zeilen
  1. 3 0
      src/chan.h
  2. 0 13
      src/chanprog.cc
  3. 15 1
      src/chanprog.h
  4. 3 0
      src/mod/channels.mod/chanmisc.cc
  5. 3 0
      src/mod/irc.mod/chan.cc
  6. 2 0
      src/mod/irc.mod/irc.cc

+ 3 - 0
src/chan.h

@@ -12,6 +12,7 @@
 #include <lib/bdlib/src/Array.h>
 #include <lib/bdlib/src/HashTable.h>
 #include <lib/bdlib/src/String.h>
+#include "RfcString.h"
 
 /* chan & global */
 enum flood_t {
@@ -176,6 +177,8 @@ struct chan_t {
 
   // Member caching to cache cyclers
   bd::HashTable<bd::String, memberlist*> *cached_members;
+
+  bd::HashTable<RfcString, memberlist*> *hashed_members;
 };
 
 #define CHANINV    BIT0		/* +i					*/

+ 0 - 13
src/chanprog.cc

@@ -95,19 +95,6 @@ void rmspace(char *s)
     memmove(s, p, q - p + 2);
 }
 
-/* Returns memberfields if the nick is in the member list.
- */
-memberlist *ismember(const struct chanset_t *chan, const char *nick)
-{
-  memberlist	*x = NULL;
-
-  if (chan && nick && nick[0])
-    for (x = chan->channel.member; x && x->nick[0]; x = x->next)
-      if (!rfc_casecmp(x->nick, nick))
-        return x;
-  return NULL;
-}
-
 /* Find a chanset by channel name as the server knows it (ie !ABCDEchannel)
  */
 struct chanset_t *findchan(const char *name)

+ 15 - 1
src/chanprog.h

@@ -40,7 +40,21 @@ void keyx(const bd::String& target, const char *);
 void set_fish_key(char *, bd::String);
 struct userrec *check_chanlist(const char *);
 struct userrec *check_chanlist_hand(const char *);
-memberlist *ismember(const struct chanset_t *, const char *);
+/*
+ * Returns memberfields if the nick is in the member list.
+ */
+static inline memberlist *
+ismember(const struct chanset_t *chan, const RfcString nick) {
+  if (!chan || !nick)
+    return NULL;
+  return (*chan->channel.hashed_members)[nick];
+}
+static inline memberlist *
+ismember(const struct chanset_t *chan, const char *nick) {
+  if (!chan || !nick || !nick[0])
+    return NULL;
+  return ismember(chan, RfcString(nick));
+}
 struct chanset_t *findchan(const char *name);
 /*
  * Find a chanset by display name (ie !channel)

+ 3 - 0
src/mod/channels.mod/chanmisc.cc

@@ -985,6 +985,7 @@ static void init_channel(struct chanset_t *chan, bool reset)
   chan->channel.floodtime = new bd::HashTable<bd::String, bd::HashTable<flood_t, time_t> >;
   chan->channel.floodnum  = new bd::HashTable<bd::String, bd::HashTable<flood_t, int> >;
   chan->channel.cached_members = new bd::HashTable<bd::String, memberlist*>;
+  chan->channel.hashed_members = new bd::HashTable<RfcString, memberlist*>;
   /* Don't clear out existing roles, keep them until rebalancing
    * to not create a window of missing roles. */
   if (!chan->bot_roles) {
@@ -1061,6 +1062,8 @@ void clear_channel(struct chanset_t *chan, bool reset)
     delete chan->channel.cached_members;
     chan->channel.cached_members = NULL;
   }
+  delete chan->channel.hashed_members;
+  chan->channel.hashed_members = NULL;
 
   if (reset)
     init_channel(chan, 1);

+ 3 - 0
src/mod/irc.mod/chan.cc

@@ -290,6 +290,7 @@ static memberlist *newmember(struct chanset_t *chan, char *nick)
   ++(chan->channel.members);
   n->floodtime = new bd::HashTable<flood_t, time_t>;
   n->floodnum  = new bd::HashTable<flood_t, int>;
+  (*chan->channel.hashed_members)[nick] = n;
   return n;
 }
 
@@ -3103,7 +3104,9 @@ static int gotnick(char *from, char *msg)
 	  killmember(chan, mm->nick, false);
       }
 
+      chan->channel.hashed_members->remove(nick);
       strlcpy(m->nick, msg, sizeof(m->nick));
+      (*chan->channel.hashed_members)[msg] = m;
       strlcpy(m->from, s1, sizeof(m->from));
 
       /*

+ 2 - 0
src/mod/irc.mod/irc.cc

@@ -1172,6 +1172,8 @@ killmember(struct chanset_t *chan, char *nick, bool cacheMember)
   else
     chan->channel.member = x->next;
 
+  chan->channel.hashed_members->remove(x->nick);
+
   if (cacheMember) {
     x->last = now;
     x->user = NULL;