Changes between Initial Version and Version 1 of MapGuideRfc151


Ignore:
Timestamp:
09/20/15 19:27:51 (9 years ago)
Author:
zhanga
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • MapGuideRfc151

    v1 v1  
     1= !MapGuide RFC # 151 - Add Layer Definition Cache =
     2
     3This page contains a change request (RFC) for the !MapGuide Open Source project.
     4More !MapGuide RFCs can be found on the [wiki:MapGuideRfcs RFCs] page.
     5
     6== Status ==
     7
     8||RFC Template Version||(1.0)||
     9||Submission Date||20 Sep. 2015||
     10||Last Modified||20 Sep. 2015||
     11||Author||Andy Zhang||
     12||RFC Status||draft||
     13||Implementation Status||under development||
     14||Proposed Milestone||3.1||
     15||Assigned PSC guide(s)||(when determined)||
     16||'''Voting History'''||(vote date)||
     17||+1|| ||
     18||+0|| ||
     19||-0|| ||
     20||-1|| ||
     21||no vote|| ||
     22
     23== Overview ==
     24
     25This RFC proposed to add layer definition cache. The performance of rendering map can be improved a lot by caching layer definitions.
     26
     27== Motivation ==
     28
     29When stylizing layers, MapGuide Server gets the XML document of the layer from XML database and converts the XML document to MdfModel::LayerDefinition for each layer. It is an expensive operation especially for complicate layers. For a map which has a lot of complicate layers, this operation accounts for about 5~10% of total time of stylizing layers. If we can cache the layer definitions, the performance of rendering map can be improved a lot. 
     30
     31== Proposed Solution ==
     32
     33The solution is similar as current feature service cache. New classes MgResourceServiceCache, MgResourceServiceCacheEntry, MgResourceLayerDefinitionCacheItem and MgResourceServiceCacheTimeLimitEventHandler are added.
     34
     35{{{
     36class MG_SERVER_CACHE_API MgResourceServiceCache : public MgServerCache
     37{
     38    DECLARE_CLASSNAME(MgResourceServiceCache)
     39
     40/// Constructors/Destructor
     41
     42public:
     43    MgResourceServiceCache(void);
     44    ~MgResourceServiceCache(void);
     45
     46private:
     47
     48    // Unimplemented copy constructor and assignment operator.
     49    MgResourceServiceCache(const MgResourceServiceCache&);
     50    MgResourceServiceCache& operator=(const MgResourceServiceCache&);
     51
     52/// Methods
     53
     54public:
     55
     56    virtual void Clear();
     57
     58    void RemoveEntry(CREFSTRING resource);
     59    void RemoveEntry(MgResourceIdentifier* resource);
     60    void RemoveExpiredEntries();
     61
     62    // gets/sets layer definitions
     63    void SetLayerDefinition(MgResourceIdentifier* resource, MgResourceLayerDefinitionCacheItem* layerDefinition);
     64    MgResourceLayerDefinitionCacheItem* GetLayerDefinition(MgResourceIdentifier* source);
     65
     66    INT32 GetCacheSize();
     67    INT32 GetDroppedEntriesCount();
     68
     69protected:
     70
     71    void Compact();
     72
     73    MgResourceServiceCacheEntry* SetEntry(MgResourceIdentifier* resource);
     74    MgResourceServiceCacheEntry* GetEntry(MgResourceIdentifier* resource);
     75    void RemoveOldEntry();
     76
     77/// Data Members
     78
     79private:
     80
     81    friend class MgCacheManager;
     82
     83    typedef std::map<STRING, MgResourceServiceCacheEntry*> MgResourceServiceCacheEntries;
     84    MgResourceServiceCacheEntries m_resourceServiceCacheEntries;
     85    INT32 m_nDroppedEntries;
     86};
     87}}}
     88
     89
     90{{{
     91class MG_SERVER_CACHE_API MgResourceServiceCacheEntry : public MgServerCacheEntry
     92{
     93/// Constructors/Destructor
     94public:
     95    MgResourceServiceCacheEntry(void);
     96    virtual ~MgResourceServiceCacheEntry(void);
     97
     98private:
     99
     100    // Unimplemented copy constructor and assignment operator.
     101    MgResourceServiceCacheEntry(const MgResourceServiceCacheEntry&);
     102    MgResourceServiceCacheEntry& operator=(const MgResourceServiceCacheEntry&);
     103
     104/// Methods
     105
     106public:
     107    void SetLayerDefinition(MgResourceLayerDefinitionCacheItem* layerDefinition);
     108    MgResourceLayerDefinitionCacheItem* GetLayerDefinition();
     109
     110private:
     111    Ptr<MgResourceLayerDefinitionCacheItem> m_layerDefinition;
     112};
     113}}}
     114
     115
     116{{{
     117class MG_SERVER_CACHE_API MgResourceLayerDefinitionCacheItem : public MgServerCacheItem
     118{
     119/// Constructors/Destructor
     120
     121public:
     122    MgResourceLayerDefinitionCacheItem(void);
     123    explicit MgResourceLayerDefinitionCacheItem(MdfModel::LayerDefinition* LayerDefinition);
     124    virtual ~MgResourceLayerDefinitionCacheItem(void);
     125
     126private:
     127
     128    // Unimplemented copy constructor and assignment operator.
     129    MgResourceLayerDefinitionCacheItem(const MgResourceLayerDefinitionCacheItem&);
     130    MgResourceLayerDefinitionCacheItem& operator=(const MgResourceLayerDefinitionCacheItem&);
     131
     132/// Methods
     133
     134public:
     135
     136    MdfModel::LayerDefinition* Get();
     137    void Set(MdfModel::LayerDefinition* layerDefinition);
     138
     139/// Data Members
     140
     141private:
     142    auto_ptr<MdfModel::LayerDefinition> m_layerDefinition;
     143};
     144}}}
     145
     146
     147{{{
     148///////////////////////////////////////////////////////////////////////////////
     149/// \brief
     150/// Derived Event Handler class to clean up inactive resource service cache items.
     151///
     152class MgResourceServiceCacheTimeLimitEventHandler : public MgTimedEventHandler
     153{
     154/// Constructors/Destructor
     155
     156public:
     157
     158    MgResourceServiceCacheTimeLimitEventHandler(MgEventTimer& timer);
     159    virtual ~MgResourceServiceCacheTimeLimitEventHandler();
     160
     161private:
     162
     163    // Unimplemented Constructors/Methods
     164
     165    MgResourceServiceCacheTimeLimitEventHandler();
     166    MgResourceServiceCacheTimeLimitEventHandler(const MgResourceServiceCacheTimeLimitEventHandler&);
     167    MgResourceServiceCacheTimeLimitEventHandler& operator=(const MgResourceServiceCacheTimeLimitEventHandler&);
     168
     169/// Methods
     170
     171protected:
     172
     173    virtual void HandleEvent(long eventId);
     174
     175/// Data Members
     176
     177private:
     178
     179};
     180}}}
     181
     1823 new configuration entries are added to ResourceServiceProperties section.
     183
     184{{{
     185# CacheSize                        Max # of internal data objects (layer definitions) to cache
     186#                                       0 < Value <= 5000
     187# CacheTimeLimit                   Time duration in seconds for how long to
     188#                                  cache the internal data objects
     189#                                       0 < Value <= 2147483647
     190# CacheTimerInterval               Time interval in seconds for when the server
     191#                                  checks for expired cache entries
     192#                                       0 < Value <= 2147483647
     193[ResourceServiceProperties]
     194CacheSize = 1000
     195CacheTimeLimit = 86400
     196CacheTimerInterval = 3600
     197}}}
     198
     199There are also some changes in MgCacheManager. A private variable m_resourceServerCache and 2 methods are added.
     200{{{
     201class MG_SERVER_MANAGER_API MgCacheManager : public MgGuardDisposable
     202{
     203...
     204public:
     205    // get resource service cache
     206    MgResourceServiceCache* GetResourceServiceCache();
     207    MgResourceLayerDefinitionCacheItem* GetResourceLayerDefinitionCacheItem(MgResourceIdentifier* resource);
     208    ...
     209private:
     210    ...
     211    MgResourceServiceCache m_resourceServiceCache;
     212};
     213}}}
     214
     215We get layer definition from the cache first. If it is not found, get the layer definition from XML database.
     216{{{
     217MgResourceLayerDefinitionCacheItem* MgCacheManager::GetResourceLayerDefinitionCacheItem(MgResourceIdentifier* resource)
     218{
     219    Ptr<MgResourceLayerDefinitionCacheItem> cacheItem;
     220
     221    MG_TRY()
     222
     223    cacheItem = m_resourceServiceCache.GetLayerDefinition(resource);
     224
     225    if (NULL == cacheItem.p)
     226    {
     227        // Get the Resource Service.
     228        Ptr<MgResourceService> resourceService = dynamic_cast<MgResourceService*>(
     229            m_serviceManager->RequestService(MgServiceType::ResourceService));
     230        ACE_ASSERT(NULL != resourceService.p);
     231
     232        auto_ptr<MdfModel::LayerDefinition> layerDefinition;
     233        layerDefinition.reset(MgLayerBase::GetLayerDefinition(resourceService, resource));
     234
     235        if (NULL == layerDefinition.get())
     236        {
     237            MgResources* resources = MgResources::GetInstance();
     238            ACE_ASSERT(NULL != resources);
     239            STRING message = resources->GetResourceMessage(MgResources::ResourceService,
     240                L"MgInvalidLayerDefinition", NULL);
     241            MgStringCollection arguments;
     242            arguments.Add(message);
     243
     244            throw new MgInvalidFeatureSourceException(
     245                L"MgCacheManager.GetResourceLayerDefinitionCacheItem",
     246                __LINE__, __WFILE__, &arguments, L"", NULL);
     247        }
     248
     249        cacheItem = new MgResourceLayerDefinitionCacheItem(layerDefinition.release());
     250        m_resourceServiceCache.SetLayerDefinition(resource, cacheItem.p);
     251    }
     252    else
     253    {
     254        CheckPermission(resource, MgResourcePermission::ReadOnly);
     255    }
     256
     257    MG_CATCH_AND_THROW(L"MgCacheManager.GetResourceLayerDefinitionCacheItem")
     258
     259    return cacheItem.Detach();
     260}
     261}}}
     262
     263Now, we get the MdfModel::LayerDefinition of a layer from the cache manager:
     264{{{
     265            //get layer definition
     266            Ptr<MgResourceIdentifier> layerid = mapLayer->GetLayerDefinition();
     267            MgCacheManager* cacheManager = MgCacheManager::GetInstance();
     268            Ptr<MgResourceLayerDefinitionCacheItem> cacheItem = cacheManager->GetResourceLayerDefinitionCacheItem(layerid);
     269            MdfModel::LayerDefinition* layerDefinition = cacheItem->Get();
     270            ...
     271            MdfModel::VectorLayerDefinition* vl = dynamic_cast<MdfModel::VectorLayerDefinition*>(layerDefinition);
     272            ...
     273}}}
     274
     275== Implications ==
     276Now implications are intended as it is an internal implementation change. We just get better performance when rendering maps.
     277
     278== Test Plan ==
     279So far I don’t plan to add new unit tests for this change.
     280
     281== Funding / Resources ==
     282Autodesk