瀏覽代碼

Eliminate use of slow HashTable.each

Bryan Drewery 7 年之前
父節點
當前提交
2f0d7f048a
共有 2 個文件被更改,包括 62 次插入48 次删除
  1. 56 46
      src/auth.cc
  2. 6 2
      src/auth.h

+ 56 - 46
src/auth.cc

@@ -81,7 +81,7 @@ void Auth::Done() noexcept
 void Auth::NewNick(const char *newnick) noexcept
 {
   if (ht_nick.contains(nick)) {
-    Auth::ht_nick.remove(nick);
+    ht_nick.remove(nick);
   }
   strlcpy(nick, newnick, NICKLEN);
   ht_nick[newnick] = this;
@@ -99,7 +99,7 @@ Auth *Auth::Find(const char *_host) noexcept
   return NULL;
 }
 
-static void auth_clear_users_block(const bd::String key, Auth* auth, void *param)
+static void auth_clear_users_block(const bd::String& key, Auth* auth)
 {
   if (auth->user) {
     sdprintf(STR("Clearing USER for auth: (%s!%s) [%s]"), auth->nick,
@@ -111,16 +111,16 @@ static void auth_clear_users_block(const bd::String key, Auth* auth, void *param
 void Auth::NullUsers(const char *nick) noexcept
 {
   if (nick == NULL) {
-    ht_host.each(auth_clear_users_block);
-  } else {
-    if (ht_nick.contains(nick)) {
-      Auth *auth = ht_nick[nick];
-      auth_clear_users_block(nick, auth, NULL);
+    for (auto& kv : ht_host) {
+      auth_clear_users_block(kv.first, kv.second);
     }
+  } else if (ht_nick.contains(nick)) {
+    Auth* auth = ht_nick[nick];
+    auth_clear_users_block(nick, auth);
   }
 }
 
-static void auth_fill_users_block(const bd::String key, Auth* auth, void* param)
+static void auth_fill_users_block(const bd::String& key, Auth* auth)
 {
   char from[NICKLEN + UHOSTLEN];
 
@@ -133,47 +133,61 @@ static void auth_fill_users_block(const bd::String key, Auth* auth, void* param)
 void Auth::FillUsers(const char *nick) noexcept
 {
   if (nick == NULL) {
-    ht_host.each(auth_fill_users_block);
-  } else {
-    if (ht_nick.contains(nick)) {
-      Auth *auth = ht_nick[nick];
-      auth_fill_users_block(nick, auth, NULL);
+    for (auto& kv : ht_host) {
+      auth_fill_users_block(kv.first, kv.second);
     }
+  } else if (ht_nick.contains(nick)) {
+    Auth *auth = ht_nick[nick];
+    auth_fill_users_block(nick, auth);
   }
 }
 
 
-static void auth_expire_block(const bd::String key, Auth* auth, void* param)
+void Auth::ExpireAuths() noexcept
 {
-  if (auth->Authed() && ((now - auth->atime) >= (60 * 60))) {
-    Auth::ht_host.remove(key);
-    Auth::ht_nick.remove(auth->nick);
+  if (!ischanhub() || ht_host.size() == 0)
+    return;
+  std::vector<bd::String> expired_hosts;
+  expired_hosts.reserve(ht_host.size());
+  std::vector<const Auth*> delete_auths;
+  delete_auths.reserve(ht_host.size());
+
+  for (const auto& kv : ht_host) {
+    const bd::String& host = kv.first;
+    const auto& auth = kv.second;
+    if (auth->Authed() && ((now - auth->atime) >= (60 * 60))) {
+      putlog(LOG_DEBUG, "*", STR("Auth (%s!%s) [%s] expired."),
+          auth->nick, auth->host, auth->user ? auth->user->handle : "*");
+      expired_hosts.push_back(host);
+      ht_nick.remove(auth->nick);
+      delete_auths.push_back(auth);
+    }
+  }
+  for (const auto& host : expired_hosts) {
+    ht_host.remove(host);
+  }
+  for (const auto& auth : delete_auths) {
     delete auth;
   }
 }
 
-void Auth::ExpireAuths() noexcept
+void Auth::DeleteAll() noexcept
 {
   if (!ischanhub())
     return;
-
-  ht_host.each(auth_expire_block);
-}
-
-static void auth_delete_all_block(const bd::String, Auth* auth, void* param)
-{
-  putlog(LOG_DEBUG, "*", STR("Removing (%s!%s) [%s], from auth list."),
-      auth->nick, auth->host, auth->user ? auth->user->handle : "*");
-  delete auth;
-}
-
-void Auth::DeleteAll() noexcept
-{
-  if (ischanhub()) {
-    putlog(LOG_DEBUG, "*", STR("Removing auth entries."));
-    ht_host.each(auth_delete_all_block);
-    ht_host.clear();
-    ht_nick.clear();
+  putlog(LOG_DEBUG, "*", STR("Removing auth entries."));
+  std::vector<const Auth*> delete_auths;
+  delete_auths.reserve(ht_host.size());
+  for (const auto& kv : ht_host) {
+    const auto& auth = kv.second;
+    putlog(LOG_DEBUG, "*", STR("Removing (%s!%s) [%s], from auth list."),
+        auth->nick, auth->host, auth->user ? auth->user->handle : "*");
+    delete_auths.push_back(auth);
+  }
+  ht_host.clear();
+  ht_nick.clear();
+  for (const auto& auth : delete_auths) {
+    delete auth;
   }
 }
 
@@ -243,19 +257,15 @@ sdprintf(STR("GETIDX: auth: %s, idx: %d"), nick, idx);
   return 0;
 }
 
-static void auth_tell_block(const bd::String key, Auth* auth, void* param)
+void Auth::TellAuthed(int idx) noexcept
 {
-  long lparam = (long) param;
-  int idx = (int) lparam;
-
-  dprintf(idx, "(%s!%s) [%s] authtime: %li, atime: %li, Status: %d\n", auth->nick, 
+  for (const auto& kv : ht_host) {
+    const Auth* auth = kv.second;
+    dprintf(idx, "(%s!%s) [%s] authtime: %li, atime: %li, Status: %d\n",
+        auth->nick,
         auth->host, auth->user ? auth->user->handle : "*",
         (long)auth->authtime, (long)auth->atime, auth->Status());
-}
-
-void Auth::TellAuthed(int idx) noexcept
-{
-  ht_host.each(auth_tell_block, (void *) (long) idx);
+  }
 }
 
 void makehash(struct userrec *u, const char *randstring, char *out, size_t out_size)

+ 6 - 2
src/auth.h

@@ -17,8 +17,12 @@ class Auth {
   Auth(const char *, const char *, struct userrec * = NULL);
   ~Auth();
 
-  int Status(int newstat = -1) noexcept {
-    if (newstat >= 0) { status = newstat; } return status;
+  inline int Status(void) const noexcept __attribute__((pure)) {
+    return status;
+  }
+  int Status(int newstat) noexcept {
+    status = newstat;
+    return Status();
   }
   void MakeHash() noexcept;
   bool Authed() const noexcept __attribute__((pure)) {