From 655151d88a6ab948949b73682c3a76a0274eb10c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?louiz=E2=80=99?= <louiz@louiz.org>
Date: Sat, 26 Aug 2017 13:51:15 +0200
Subject: Cache the encoding_in database value, to avoid doing a query for each
 message

---
 src/bridge/bridge.cpp               |  7 ++-----
 src/database/database.cpp           |  1 +
 src/database/database.hpp           | 35 +++++++++++++++++++++++++++++++++++
 src/xmpp/biboumi_adhoc_commands.cpp |  4 ++--
 4 files changed, 40 insertions(+), 7 deletions(-)

(limited to 'src')

diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp
index e0cb36d..9fd0a5b 100644
--- a/src/bridge/bridge.cpp
+++ b/src/bridge/bridge.cpp
@@ -22,15 +22,12 @@ static std::string in_encoding_for(const Bridge& bridge, const Iid& iid)
 {
 #ifdef USE_DATABASE
   const auto jid = bridge.get_bare_jid();
-  auto options = Database::get_irc_channel_options_with_server_default(jid, iid.get_server(), iid.get_local());
-  auto result = options.col<Database::EncodingIn>();
-  if (!result.empty())
-    return result;
+  return Database::get_encoding_in(jid, iid.get_server(), iid.get_local());
 #else
   (void)bridge;
   (void)iid;
-#endif
   return {"ISO-8859-1"};
+#endif
 }
 
 Bridge::Bridge(std::string user_jid, BiboumiComponent& xmpp, std::shared_ptr<Poller>& poller):
diff --git a/src/database/database.cpp b/src/database/database.cpp
index 266b17e..0f2349d 100644
--- a/src/database/database.cpp
+++ b/src/database/database.cpp
@@ -14,6 +14,7 @@ Database::GlobalOptionsTable Database::global_options("GlobalOptions_");
 Database::IrcServerOptionsTable Database::irc_server_options("IrcServerOptions_");
 Database::IrcChannelOptionsTable Database::irc_channel_options("IrcChannelOptions_");
 Database::RosterTable Database::roster("roster");
+std::map<Database::CacheKey, Database::EncodingIn::real_type> Database::encoding_in_cache{};
 
 
 void Database::open(const std::string& filename)
diff --git a/src/database/database.hpp b/src/database/database.hpp
index c00c938..f4b2ecd 100644
--- a/src/database/database.hpp
+++ b/src/database/database.hpp
@@ -13,6 +13,7 @@
 #include <string>
 
 #include <memory>
+#include <map>
 
 
 class Database
@@ -140,7 +141,41 @@ class Database
   static RosterTable roster;
   static sqlite3* db;
 
+  /**
+   * Some caches, to avoid doing very frequent query requests for a few options.
+   */
+  using CacheKey = std::tuple<std::string, std::string, std::string>;
+
+  static EncodingIn::real_type get_encoding_in(const std::string& owner,
+                                        const std::string& server,
+                                        const std::string& channel)
+  {
+    CacheKey channel_key{owner, server, channel};
+    auto it = Database::encoding_in_cache.find(channel_key);
+    if (it == Database::encoding_in_cache.end())
+      {
+        auto options = Database::get_irc_channel_options_with_server_default(owner, server, channel);
+        EncodingIn::real_type result = options.col<Database::EncodingIn>();
+        if (result.empty())
+          result = "ISO-8859-1";
+        it = Database::encoding_in_cache.insert(std::make_pair(channel_key, result)).first;
+      }
+    return it->second;
+  }
+  static void invalidate_encoding_in_cache(const std::string& owner,
+                                           const std::string& server,
+                                           const std::string& channel)
+  {
+    CacheKey channel_key{owner, server, channel};
+    Database::encoding_in_cache.erase(channel_key);
+  }
+  static void invalidate_encoding_in_cache()
+  {
+    Database::encoding_in_cache.clear();
+  }
+
  private:
   static std::string gen_uuid();
+  static std::map<CacheKey, EncodingIn::real_type> encoding_in_cache;
 };
 #endif /* USE_DATABASE */
diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp
index 65f9966..d78dc98 100644
--- a/src/xmpp/biboumi_adhoc_commands.cpp
+++ b/src/xmpp/biboumi_adhoc_commands.cpp
@@ -430,7 +430,7 @@ void ConfigureIrcServerStep2(XmppComponent&, AdhocSession& session, XmlNode& com
             options.col<Database::EncodingIn>() = value->get_inner();
 
         }
-
+      Database::invalidate_encoding_in_cache();
       options.save(Database::db);
 
       command_node.delete_all_children();
@@ -599,7 +599,7 @@ bool handle_irc_channel_configuration_form(XmppComponent& xmpp_component, const
                 }
 
             }
-
+          Database::invalidate_encoding_in_cache(requester.bare(), iid.get_server(), iid.get_local());
           options.save(Database::db);
         }
       return true;
-- 
cgit v1.2.3