Revision: 7272
http://svn.sourceforge.net/mahogany/?rev=7272&view=rev
Author: vadz
Date: 2007-05-18 05:21:41 -0700 (Fri, 18 May 2007)
Log Message:
-----------
speed up filter creation by caching their internal representation
Modified Paths:
--------------
trunk/M/src/classes/MFilter.cpp
trunk/M/src/classes/MFolder.cpp
Modified: trunk/M/src/classes/MFilter.cpp
===================================================================
--- trunk/M/src/classes/MFilter.cpp 2007-05-18 12:21:26 UTC (rev 7271)
+++ trunk/M/src/classes/MFilter.cpp 2007-05-18 12:21:41 UTC (rev 7272)
@@ -35,6 +35,7 @@
#include "MFilter.h"
#include "MFolder.h"
+#include "MAtExit.h"
#include "modules/Filters.h"
// ----------------------------------------------------------------------------
@@ -49,6 +50,30 @@
#define MP_FILTER_GUIDESC _T("Settings")
// ----------------------------------------------------------------------------
+// private functions
+// ----------------------------------------------------------------------------
+
+// free the folder filters cache defined below
+static void CleanupFilterCache();
+
+// invalidate the cached representation of the given filter
+static void InvalidateFilter(const MFilter *filter);
+
+// ----------------------------------------------------------------------------
+// globals
+// ----------------------------------------------------------------------------
+
+// filter rules are relatively expensive to construct, so we cache them once we
+// created them in this hash map (its keys are the folder names)
+#include "wx/hashmap.h"
+WX_DECLARE_STRING_HASH_MAP(FilterRule *, FolderFiltersMap);
+
+static FolderFiltersMap gs_folderFilters;
+
+// ensure that filter rules are deleted on exit
+static MRunFunctionAtExit gs_runFilterCacheCleanup(CleanupFilterCache);
+
+// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
@@ -816,6 +841,8 @@
{
if ( m_dirty )
{
+ InvalidateFilter(this);
+
// write the values to the profile
m_Profile->writeEntry(MP_FILTER_NAME, m_Name);
if ( m_Settings )
@@ -956,6 +983,9 @@
return false;
}
+ // invalidating just one filter isn't enough
+ CleanupFilterCache();
+
return true;
}
@@ -983,11 +1013,56 @@
// global functions
// ----------------------------------------------------------------------------
+static void
+CleanupFilterCache()
+{
+ for ( FolderFiltersMap::const_iterator i = gs_folderFilters.begin();
+ i != gs_folderFilters.end();
+ ++i )
+ {
+ FilterRule * const rule = i->second;
+ if ( rule )
+ rule->DecRef();
+ }
+
+ gs_folderFilters.clear();
+}
+
+// this is used by MFolderFromProfile::SetFilter(): when a folders filter is
+// changed, it only affects this folder
+extern void
+InvalidateFilterForFolder(const MFolder *folder)
+{
+ CHECK_RET( folder, _T("InvalidateFilter: NULL parameter") );
+
+ gs_folderFilters.erase(folder->GetFullName());
+}
+
+// this is used by the code in this file when modifying individual filters, as
+// we don't know which folders use them, we simply invalidate the entire cache
+static void
+InvalidateFilter(const MFilter * /* filter */)
+{
+ CleanupFilterCache();
+}
+
extern FilterRule *
GetFilterForFolder(const MFolder *folder)
{
CHECK( folder, NULL, _T("GetFilterForFolder: NULL parameter") );
+ // check if we already have it in the cache
+ const String folderName = folder->GetFullName();
+ const FolderFiltersMap::iterator i = gs_folderFilters.find(folderName);
+ if ( i != gs_folderFilters.end() )
+ {
+ FilterRule * const rule = i->second;
+ if ( rule )
+ rule->IncRef();
+
+ return rule;
+ }
+
// build a single program from all filter rules:
String filterString;
wxArrayString filters = folder->GetFilters();
@@ -1003,6 +1078,8 @@
if ( filterString.empty() )
{
// no, nothing to do
+ gs_folderFilters[folderName] = NULL;
+
return NULL;
}
@@ -1011,6 +1088,8 @@
{
wxLogWarning(_("Filter module couldn't be loaded."));
+ // don't cache this failure: maybe we'll be able to load the module the
+ // next time
return NULL;
}
@@ -1027,5 +1106,11 @@
filterString.c_str(), folder->GetFullName().c_str());
}
+ // cache the newly created rule and make sure it doesn't go away
+ gs_folderFilters[folderName] = filterRule;
+ if ( filterRule )
+ filterRule->IncRef();
+
return filterRule;
}
+
Modified: trunk/M/src/classes/MFolder.cpp
===================================================================
--- trunk/M/src/classes/MFolder.cpp 2007-05-18 12:21:26 UTC (rev 7271)
+++ trunk/M/src/classes/MFolder.cpp 2007-05-18 12:21:41 UTC (rev 7272)
@@ -951,6 +951,13 @@
void MFolderFromProfile::SetFilters(const wxArrayString& filters)
{
+ // this function is in MFilter.cpp but we only use it here so it's not in
+ // any header
+ extern void InvalidateFilterForFolder(const MFolder *);
+
+ // forget the cached filter representation
+ InvalidateFilterForFolder(this);
+
m_profile->writeEntry(MP_FOLDER_FILTERS, strutil_flatten_array(filters));
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.