[mapguide-commits] r6948 - in branches/2.4/MgDev/Desktop/MgDesktop: . Services Services/Resource

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Wed Aug 22 22:16:48 PDT 2012


Author: jng
Date: 2012-08-22 22:16:48 -0700 (Wed, 22 Aug 2012)
New Revision: 6948

Added:
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Resource/ResourceContentCache.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/Resource/ResourceContentCache.h
Modified:
   branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
   branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
   branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp
Log:
#2099: Add an in-memory resource content cache to avoid disk reads for every MgResourceService::GetResourceContent call.

Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj	2012-08-21 17:33:07 UTC (rev 6947)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktop.vcproj	2012-08-23 05:16:48 UTC (rev 6948)
@@ -3608,6 +3608,42 @@
 				</FileConfiguration>
 			</File>
 			<File
+				RelativePath=".\Services\Resource\ResourceContentCache.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
 				RelativePath=".\Services\Resource\ResourceDefs.cpp"
 				>
 				<FileConfiguration
@@ -5278,6 +5314,10 @@
 				>
 			</File>
 			<File
+				RelativePath=".\Services\Resource\ResourceContentCache.h"
+				>
+			</File>
+			<File
 				RelativePath=".\Services\Resource\ResourceDefs.h"
 				>
 			</File>

Modified: branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp	2012-08-21 17:33:07 UTC (rev 6947)
+++ branches/2.4/MgDev/Desktop/MgDesktop/MgDesktopBuild.cpp	2012-08-23 05:16:48 UTC (rev 6948)
@@ -117,6 +117,7 @@
 #include "Services/Resource/ByteSourceDwfInputStreamImpl.cpp"
 #include "Services/Resource/OperationInfo.cpp"
 #include "Services/Resource/OperationParameter.cpp"
+#include "Services/Resource/ResourceContentCache.cpp"
 #include "Services/Resource/ResourceDefs.cpp"
 #include "Services/Resource/ResourcePackageHandler.cpp"
 #include "Services/Resource/ResourcePackageLoader.cpp"

Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Resource/ResourceContentCache.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Resource/ResourceContentCache.cpp	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Resource/ResourceContentCache.cpp	2012-08-23 05:16:48 UTC (rev 6948)
@@ -0,0 +1,69 @@
+#include "MgDesktop.h"
+#include "ResourceContentCache.h"
+
+Ptr<MgResourceContentCache> MgResourceContentCache::smInstance = (MgResourceContentCache*)NULL;
+
+MgResourceContentCache::MgResourceContentCache() { }
+
+MgResourceContentCache::~MgResourceContentCache()
+{
+    ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) MgResourceContentCache::~MgResourceContentCache()\n")));
+}
+
+MgResourceContentCache* MgResourceContentCache::GetInstance()
+{
+    if (NULL == MgResourceContentCache::smInstance)
+    {
+        // Perform Double-Checked Locking Optimization.
+        ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, *ACE_Static_Object_Lock::instance (), 0));
+        if (NULL == MgResourceContentCache::smInstance)
+        {
+            MgResourceContentCache::smInstance = new MgResourceContentCache();
+        }
+    }
+    return smInstance;
+}
+
+STRING MgResourceContentCache::GetContentEntry(MgResourceIdentifier* resource)
+{
+    CHECKARGUMENTNULL(resource, L"MgResourceContentCache::PutContentEntry");
+    STRING resId = resource->ToString();
+
+    ACE_MT(ACE_GUARD_RETURN(ACE_Recursive_Thread_Mutex, ace_mon, m_mutex, L""));
+    MgResourceContentCacheEntries::iterator i = m_resourceContentCacheEntries.find(resId);
+
+    STRING ret;
+    if (m_resourceContentCacheEntries.end() != i)
+    {
+        ret = i->second;
+    }
+    return ret;
+}
+
+void MgResourceContentCache::RemoveContentEntry(MgResourceIdentifier* resource)
+{
+    CHECKARGUMENTNULL(resource, L"MgResourceContentCache::PutContentEntry");
+    STRING resId = resource->ToString();
+
+    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, m_mutex));
+    MgResourceContentCacheEntries::iterator i = m_resourceContentCacheEntries.find(resId);
+
+    if (m_resourceContentCacheEntries.end() != i)
+    {
+        m_resourceContentCacheEntries.erase(i);
+    }
+}
+
+void MgResourceContentCache::PutContentEntry(MgResourceIdentifier* resource, CREFSTRING content)
+{
+    CHECKARGUMENTNULL(resource, L"MgResourceContentCache::PutContentEntry");
+    if (content.empty())
+    {
+        throw new MgInvalidArgumentException(L"MgResourceContentCache::PutContentEntry", __LINE__, __WFILE__, NULL, L"", NULL);
+    }
+    STRING resId = resource->ToString();
+    //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) MgResourceContentCache::PutContentEntry - %W\n"), resId.c_str()));
+    
+    ACE_MT(ACE_GUARD(ACE_Recursive_Thread_Mutex, ace_mon, m_mutex));
+    m_resourceContentCacheEntries[resId] = content;
+}
\ No newline at end of file

Added: branches/2.4/MgDev/Desktop/MgDesktop/Services/Resource/ResourceContentCache.h
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/Resource/ResourceContentCache.h	                        (rev 0)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/Resource/ResourceContentCache.h	2012-08-23 05:16:48 UTC (rev 6948)
@@ -0,0 +1,31 @@
+#ifndef DESKTOP_RESOURCE_CONTENT_CACHE_H
+#define DESKTOP_RESOURCE_CONTENT_CACHE_H
+
+#include "MgDesktop.h"
+
+class MgResourceContentCache : public MgGuardDisposable
+{
+private:
+    static Ptr<MgResourceContentCache> smInstance;
+    MgResourceContentCache();
+
+public:
+    static MgResourceContentCache* GetInstance();
+    virtual ~MgResourceContentCache();
+
+    STRING GetContentEntry(MgResourceIdentifier* resource);
+    void RemoveContentEntry(MgResourceIdentifier* resource);
+    void PutContentEntry(MgResourceIdentifier* resource, CREFSTRING content);
+
+protected:
+    virtual void Dispose() { delete this; }
+
+private:
+    /// Needed for thread-safety
+    ACE_Recursive_Thread_Mutex m_mutex;
+
+    typedef std::map<STRING, STRING> MgResourceContentCacheEntries;
+    MgResourceContentCacheEntries m_resourceContentCacheEntries;
+};
+
+#endif
\ No newline at end of file

Modified: branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp
===================================================================
--- branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp	2012-08-21 17:33:07 UTC (rev 6947)
+++ branches/2.4/MgDev/Desktop/MgDesktop/Services/ResourceService.cpp	2012-08-23 05:16:48 UTC (rev 6948)
@@ -1,6 +1,7 @@
 #include "ResourceService.h"
 #include "Foundation.h"
 #include "Services/Feature/FeatureServiceCache.h"
+#include "Services/Resource/ResourceContentCache.h"
 #include "Services/Resource/ResourceDefs.h"
 #include "Services/Resource/ResourcePackageLoader.h"
 #include "Services/Resource/UnmanagedDataManager.h"
@@ -318,11 +319,11 @@
         MgFileUtil::CreateDirectory(dir, false, true);
 
 	STRING path = ResolveContentPath(resource);
-   
+
     if (NULL != content)
     {
-	    Ptr<MgByteSink> sink = new MgByteSink(content);
-
+        //Keep a wide copy
+        Ptr<MgByteSink> sink = new MgByteSink(content);
         std::string xml;
         sink->ToStringUtf8(xml);
 
@@ -449,6 +450,11 @@
     if (ResourceExists(resource))
     {
         ReleasePotentialLocks(resource);
+
+        //Empty cached version
+        MgResourceContentCache* cache = MgResourceContentCache::GetInstance();
+        cache->RemoveContentEntry(resource);
+
         STRING contentPath = ResolveContentPath(resource);
 	    STRING dataPath = ResolveDataPath(resource);
 	    if (MgFileUtil::IsFile(contentPath))
@@ -1516,18 +1522,41 @@
         throw new MgInvalidResourceTypeException(L"MgdResourceService::GetResourceContent", __LINE__, __WFILE__, NULL, L"", NULL);
     }
 
-    STRING path = ResolveContentPath(resource);
-    if (!MgFileUtil::IsFile(path))
+    //Think of the hard disks. Check we have a cached copy and return that, otherwise
+    //stash the content in the cache for future calls on the same resource
+    MgResourceContentCache* cache = MgResourceContentCache::GetInstance();
+    STRING resContent = cache->GetContentEntry(resource);
+    if (resContent.empty())
     {
-        MgStringCollection arguments;
-        arguments.Add(resource->ToString());
-        throw new MgResourceNotFoundException(L"MgdResourceService::GetResourceContent", __LINE__, __WFILE__, &arguments, L"", NULL);
-    }
+        STRING path = ResolveContentPath(resource);
+        if (!MgFileUtil::IsFile(path))
+        {
+            MgStringCollection arguments;
+            arguments.Add(resource->ToString());
+            throw new MgResourceNotFoundException(L"MgdResourceService::GetResourceContent", __LINE__, __WFILE__, &arguments, L"", NULL);
+        }
 
-    Ptr<MgByteSource> source = new MgByteSource(path);
-    source->SetMimeType(MgMimeType::Xml);
-    content = source->GetReader();
+        Ptr<MgByteSource> source = new MgByteSource(path);
+        Ptr<MgByteReader> reader = source->GetReader();
 
+        Ptr<MgByteSink> sink = new MgByteSink(reader);
+        sink->ToString(resContent);
+
+        std::string mbXml = MgUtil::WideCharToMultiByte(resContent);
+        //Stash it for future calls
+        cache->PutContentEntry(resource, resContent);
+
+        Ptr<MgByteSource> source2 = new MgByteSource((BYTE_ARRAY_IN)mbXml.c_str(), mbXml.length());
+        source2->SetMimeType(MgMimeType::Xml);
+        content = source2->GetReader();
+    }
+    else
+    {
+        std::string mbXml = MgUtil::WideCharToMultiByte(resContent);
+        Ptr<MgByteSource> source = new MgByteSource((BYTE_ARRAY_IN)mbXml.c_str(), mbXml.length());
+        source->SetMimeType(MgMimeType::Xml);
+        content = source->GetReader();
+    }
     // Successful operation
     MG_LOG_OPERATION_MESSAGE_ADD_STRING(MgResources::Success.c_str());
 



More information about the mapguide-commits mailing list