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/
_______________________________________________
Mahogany-cvsupdates mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates