glom r1914 - in trunk: . glom glom/libglom glom/libglom/document



Author: murrayc
Date: Fri Feb 20 13:40:45 2009
New Revision: 1914
URL: http://svn.gnome.org/viewvc/glom?rev=1914&view=rev

Log:
2009-02-20  Murray Cumming  <murrayc murrayc com>

* glom/glom_privs[h|cc]: get_current_privs(): Cache the priviliges 
for each table for 30 seconds, to avoid unnecessary repetitive groups 
queries to the database. This seems to avoid about 5 out of 6 
requests, so it should be faster.
Bug #567473

Modified:
   trunk/ChangeLog
   trunk/glom/glom_privs.cc
   trunk/glom/glom_privs.h
   trunk/glom/libglom/connectionpool.cc
   trunk/glom/libglom/document/document_glom.cc

Modified: trunk/glom/glom_privs.cc
==============================================================================
--- trunk/glom/glom_privs.cc	(original)
+++ trunk/glom/glom_privs.cc	Fri Feb 20 13:40:45 2009
@@ -25,6 +25,10 @@
 namespace Glom
 {
 
+Privs::type_map_privileges Privs::m_privileges_cache;
+
+Privs::type_map_cache_timeouts Privs::m_map_cache_timeouts;
+
 Privs::type_vecStrings Privs::get_database_groups()
 {
   type_vecStrings result;
@@ -317,6 +321,21 @@
   return (iterFind != users.end());
 }
 
+bool Privs::on_privs_privileges_cache_timeout(const Glib::ustring& table_name)
+{
+  std::cout << "DEBUG: Privs::on_privs_privileges_cache_timeou(): table=" << table_name << std::endl;  
+      
+  //Forget the cached privileges after a few seconds:
+  type_map_privileges::iterator iter = m_privileges_cache.find(table_name);
+  if(iter != m_privileges_cache.end())
+  {
+    std::cout << "  DEBUG: Privs::on_privs_privileges_cache_timeou(): Cleared cache for table=" << table_name << std::endl;
+    m_privileges_cache.erase(iter);
+  }
+
+  return false; //Don't call this again.
+}
+
 Privileges Privs::get_current_privs(const Glib::ustring& table_name)
 {
   //TODO_Performance: There's lots of database access here.
@@ -324,8 +343,21 @@
 
   Bakery::BusyCursor cursor(App_Glom::get_application());
 
+  //Return a cached value if possible.
+  //(If it is in the cache then it's fairly recent)
+  type_map_privileges::const_iterator iter = m_privileges_cache.find(table_name);
+  if(iter != m_privileges_cache.end())
+  {
+    std::cout << "DEBUG: Privs::get_current_privs(): Returning cache." << std::endl;
+    return iter->second;
+  }
+
+   
+  //Get the up-to-date privileges from the database:
   Privileges result;
 
+  std::cout << "DEBUG: Privs::get_current_privs(): Getting non-cached." << std::endl;  
+
   ConnectionPool* connection_pool = ConnectionPool::get_instance();
   const Glib::ustring current_user = connection_pool->get_user();
 
@@ -370,6 +402,24 @@
     result.m_delete = true;
   }
 
+  m_privileges_cache[table_name] = result;
+
+
+  //Connect a timeout to invalidate the cache after a short time:
+  //In theory, the privileges could change (via another client)
+  //during this time, but it is fairly unlikely.
+  //TODO: Make sure we handle the failure well in that unlikely case.
+
+  //Stop the existing timeout if it has not run yet.
+  type_map_cache_timeouts::iterator iter_connection = m_map_cache_timeouts.find(table_name);
+  if(iter_connection != m_map_cache_timeouts.end())
+    iter_connection->second.disconnect();
+
+  m_map_cache_timeouts[table_name] = 
+    Glib::signal_timeout().connect_seconds(
+      sigc::bind( sigc::ptr_fun(&Privs::on_privs_privileges_cache_timeout), table_name ), 
+      30 /* seconds */);
+
   return result;
 }
 

Modified: trunk/glom/glom_privs.h
==============================================================================
--- trunk/glom/glom_privs.h	(original)
+++ trunk/glom/glom_privs.h	Fri Feb 20 13:40:45 2009
@@ -28,6 +28,8 @@
 namespace Glom
 {
 
+/** A class to get user/group information for a database.
+ */
 class Privs : public GlomPostgres
 {
 public:
@@ -41,6 +43,20 @@
   static type_vecStrings get_groups_of_user(const Glib::ustring& user);
   static bool get_user_is_in_group(const Glib::ustring& user, const Glib::ustring& group);
   static Privileges get_current_privs(const Glib::ustring& table_name);
+
+protected:
+  static bool on_privs_privileges_cache_timeout(const Glib::ustring& table_name);
+
+  typedef std::map<Glib::ustring, Privileges> type_map_privileges;
+
+  //A map of table names to cached privileges: 
+  static type_map_privileges m_privileges_cache;
+
+  // Store the cache for a few seconds in case it 
+  // is immediately requested again, to avoid 
+  // introspecting again, which is slow. 
+  typedef std::map<Glib::ustring, sigc::connection> type_map_cache_timeouts;
+  static type_map_cache_timeouts m_map_cache_timeouts;
 };
 
 } //namespace Glom

Modified: trunk/glom/libglom/connectionpool.cc
==============================================================================
--- trunk/glom/libglom/connectionpool.cc	(original)
+++ trunk/glom/libglom/connectionpool.cc	Fri Feb 20 13:40:45 2009
@@ -546,7 +546,7 @@
 static sharedptr<SharedConnection> connection_cached;
 static sigc::connection connection_cached_timeout_connection;
 
-bool on_connection_pool_cache_timeout()
+static bool on_connection_pool_cache_timeout()
 {
   //std::cout << "DEBUG: Clearing connection cache." << std::endl;
       

Modified: trunk/glom/libglom/document/document_glom.cc
==============================================================================
--- trunk/glom/libglom/document/document_glom.cc	(original)
+++ trunk/glom/libglom/document/document_glom.cc	Fri Feb 20 13:40:45 2009
@@ -2697,6 +2697,7 @@
 
 
           //Groups:
+          //These are only used when recreating the database, for instance from an example file.
           m_groups.clear();
 
           const xmlpp::Element* nodeGroups = get_node_child_named(nodeRoot, GLOM_NODE_GROUPS);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]