[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