[mapguide-commits] r1101 - in trunk/MgDev: Common/MapGuideCommon/System Server/src/Core Server/src/Services/Tile

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Fri Feb 9 18:31:25 EST 2007


Author: chrisclaydon
Date: 2007-02-09 18:31:24 -0500 (Fri, 09 Feb 2007)
New Revision: 1101

Modified:
   trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp
   trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h
   trunk/MgDev/Server/src/Core/serverconfig.ini
   trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp
   trunk/MgDev/Server/src/Services/Tile/TileCache.cpp
   trunk/MgDev/Server/src/Services/Tile/TileCache.h
Log:
Group cached tile images in subfolders to improve file access performance and avoid problems associated with storing very large numbers of files in a single folder.

Modified: trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp	2007-02-09 22:59:13 UTC (rev 1100)
+++ trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.cpp	2007-02-09 23:31:24 UTC (rev 1101)
@@ -310,14 +310,16 @@
 const STRING MgConfigProperties::DefaultTileServicePropertyTileCachePath                    = L"Repositories/TileCache/";
 const STRING MgConfigProperties::TileServicePropertyCreationCutoffTime                      = L"CreationCutoffTime";
 const INT32  MgConfigProperties::DefaultTileServicePropertyCreationCutoffTime               = 120;
-const STRING MgConfigProperties::TileServicePropertyLockFolderName                          = L"LockFolderName";
-const STRING MgConfigProperties::DefaultTileServicePropertyLockFolderName                   = L"Lock";
 const STRING MgConfigProperties::TileServicePropertyPollingInterval                         = L"PollingInterval";
 const INT32  MgConfigProperties::DefaultTileServicePropertyPollingInterval                  = 1;
 const STRING MgConfigProperties::TileServicePropertyRenderOnly                              = L"RenderOnly";
 const bool   MgConfigProperties::DefaultTileServicePropertyRenderOnly                       = false;
 const STRING MgConfigProperties::TileServicePropertyTiledMapCacheSize                       = L"TiledMapCacheSize";
 const INT32  MgConfigProperties::DefaultTileServicePropertyTiledMapCacheSize                = 10;
+const STRING MgConfigProperties::TileServicePropertyTileRowsPerFolder                       = L"TileRowsPerFolder";
+const INT32 MgConfigProperties::DefaultTileServicePropertyTileRowsPerFolder                 = 30;
+const STRING MgConfigProperties::TileServicePropertyTileColumnsPerFolder                    = L"TileColumnsPerFolder";
+const INT32 MgConfigProperties::DefaultTileServicePropertyTileColumnsPerFolder              = 30;
 
 // ******************************************************************
 // Access Log Properties
@@ -548,7 +550,8 @@
 {
     { MgConfigProperties::TileServicePropertyTileCachePath                          , MgPropertyType::String    , MG_CONFIG_MIN_PATH_LENGTH             , MG_CONFIG_MAX_PATH_LENGTH             , MG_CONFIG_PATH_RESERVED_CHARACTERS        },
     { MgConfigProperties::TileServicePropertyCreationCutoffTime                     , MgPropertyType::Int32     , 1                                     , 600                                   , L""                                       },
-    { MgConfigProperties::TileServicePropertyLockFolderName                         , MgPropertyType::String    , MG_CONFIG_MIN_FOLDER_NAME_LENGTH      , MG_CONFIG_MAX_FOLDER_NAME_LENGTH      , MG_CONFIG_FOLDER_NAME_RESERVED_CHARACTERS },
+    { MgConfigProperties::TileServicePropertyTileRowsPerFolder                      , MgPropertyType::Int32     , 1                                     , 1000                                  , L""                                       },
+    { MgConfigProperties::TileServicePropertyTileColumnsPerFolder                   , MgPropertyType::Int32     , 1                                     , 1000                                  , L""                                       },
     { MgConfigProperties::TileServicePropertyPollingInterval                        , MgPropertyType::Int32     , 1                                     , 60                                    , L""                                       },
     { MgConfigProperties::TileServicePropertyRenderOnly                             , MgPropertyType::Boolean   , 0                                     , 1                                     , L""                                       },
     { MgConfigProperties::TileServicePropertyTiledMapCacheSize                      , MgPropertyType::Int32     , MG_CONFIG_MIN_CACHE_SIZE              , MG_CONFIG_MAX_CACHE_SIZE              , L""                                       },

Modified: trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h
===================================================================
--- trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h	2007-02-09 22:59:13 UTC (rev 1100)
+++ trunk/MgDev/Common/MapGuideCommon/System/ConfigProperties.h	2007-02-09 23:31:24 UTC (rev 1101)
@@ -396,24 +396,28 @@
     static const STRING TileServicePropertyTileCachePath;               /// value("TileCachePath")
     static const STRING DefaultTileServicePropertyTileCachePath;        /// value("Repositories/TileCache/")
 
+    /// Specifies whether the tile is only rendered
+    static const STRING TileServicePropertyRenderOnly;                  /// value("RenderOnly")
+    static const bool DefaultTileServicePropertyRenderOnly;             /// value(true)
+
+    // Sets the number of rows of tiles per folder
+    static const STRING TileServicePropertyTileRowsPerFolder;          /// value("TileRowsPerFolder")
+    static const INT32 DefaultTileServicePropertyTileRowsPerFolder;    /// value(30)
+    
+    // Sets the number of columns of tiles per folder
+    static const STRING TileServicePropertyTileColumnsPerFolder;       /// value("TileColumnsPerFolder")
+    static const INT32 DefaultTileServicePropertyTileColumnsPerFolder; /// value(30)
+
 INTERNAL_API:
 
     /// Sets the maximum amount of time (in seconds) to create a tile
     static const STRING TileServicePropertyCreationCutoffTime;          /// value("CreationCutoffTime")
     static const INT32 DefaultTileServicePropertyCreationCutoffTime;    /// value(120)
 
-    /// Sets the folder name for locks
-    static const STRING TileServicePropertyLockFolderName;              /// value("LockFolderName")
-    static const STRING DefaultTileServicePropertyLockFolderName;       /// value("Lock")
-
     /// Sets the time duration (in seconds) between lock checks
     static const STRING TileServicePropertyPollingInterval;             /// value("PollingInterval")
     static const INT32 DefaultTileServicePropertyPollingInterval;       /// value(1)
 
-    /// Specifies whether the tile is only rendered
-    static const STRING TileServicePropertyRenderOnly;                  /// value("RenderOnly")
-    static const bool DefaultTileServicePropertyRenderOnly;             /// value(true)
-
     /// Sets the limit on the number of cached MgMap objects used for tile generation
     static const STRING TileServicePropertyTiledMapCacheSize;           /// value("TiledMapCacheSize")
     static const INT32 DefaultTileServicePropertyTiledMapCacheSize;     /// value(10)

Modified: trunk/MgDev/Server/src/Core/serverconfig.ini
===================================================================
--- trunk/MgDev/Server/src/Core/serverconfig.ini	2007-02-09 22:59:13 UTC (rev 1100)
+++ trunk/MgDev/Server/src/Core/serverconfig.ini	2007-02-09 23:31:24 UTC (rev 1101)
@@ -342,6 +342,9 @@
 # TileCachePath                    Root path of the image tile cache
 # *****************************************************************************
 TileCachePath                      = Repositories/TileCache/
+RenderOnly                         = 0
+TileRowsPerFolder                  = 30
+TileColumnsPerFolder               = 30
 
 [AccessLogProperties]
 # *****************************************************************************

Modified: trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp	2007-02-09 22:59:13 UTC (rev 1100)
+++ trunk/MgDev/Server/src/Services/Tile/ServerTileService.cpp	2007-02-09 23:31:24 UTC (rev 1101)
@@ -200,7 +200,7 @@
             }
 
             // Create the lock file and close it right away.
-            m_tileCache->CreateFullPath(mapDefinition, scaleIndex, baseMapLayerGroupName);
+            m_tileCache->CreateFullPath(mapDefinition, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
             lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(lockPathname), ACE_TEXT("wb"));
 
             if (NULL == lockFile)
@@ -335,7 +335,7 @@
             }
 
             // Create the lock file and close it right away.
-            m_tileCache->CreateFullPath(map, scaleIndex, baseMapLayerGroupName);
+            m_tileCache->CreateFullPath(map, scaleIndex, baseMapLayerGroupName, tileColumn, tileRow);
             lockFile = ACE_OS::fopen(MG_WCHAR_TO_TCHAR(lockPathname), ACE_TEXT("wb"));
 
             if (NULL == lockFile)

Modified: trunk/MgDev/Server/src/Services/Tile/TileCache.cpp
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCache.cpp	2007-02-09 22:59:13 UTC (rev 1100)
+++ trunk/MgDev/Server/src/Services/Tile/TileCache.cpp	2007-02-09 23:31:24 UTC (rev 1101)
@@ -18,8 +18,13 @@
 #include "MapGuideCommon.h"
 #include "TileCache.h"
 
-STRING MgTileCache::sm_lockFolderName = L"Lock";    // name of file folder for locks
+const STRING SCALE_INDEX_PREFIX = L"S";
+const STRING ROW_PREFIX = L"R";
+const STRING COLUMN_PREFIX = L"C";
+
 STRING MgTileCache::sm_path = L"";
+INT32 MgTileCache::sm_tileColumnsPerFolder = 30;
+INT32 MgTileCache::sm_tileRowsPerFolder = 30;
 
 // default constructor
 MgTileCache::MgTileCache()
@@ -33,16 +38,20 @@
 
         pConf->GetStringValue(
             MgConfigProperties::TileServicePropertiesSection,
-            MgConfigProperties::TileServicePropertyLockFolderName,
-            sm_lockFolderName,
-            MgConfigProperties::DefaultTileServicePropertyLockFolderName);
-
-        pConf->GetStringValue(
-            MgConfigProperties::TileServicePropertiesSection,
             MgConfigProperties::TileServicePropertyTileCachePath,
             sm_path,
             MgConfigProperties::DefaultTileServicePropertyTileCachePath);
 
+        pConf->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
+            MgConfigProperties::TileServicePropertyTileRowsPerFolder,
+            sm_tileRowsPerFolder,
+            MgConfigProperties::DefaultTileServicePropertyTileRowsPerFolder);
+
+        pConf->GetIntValue(MgConfigProperties::TileServicePropertiesSection,
+            MgConfigProperties::TileServicePropertyTileColumnsPerFolder,
+            sm_tileColumnsPerFolder,
+            MgConfigProperties::DefaultTileServicePropertyTileColumnsPerFolder);
+
         // generate directory location for tile cache
         MgFileUtil::AppendSlashToEndOfPath(sm_path);
 
@@ -60,31 +69,24 @@
     CREFSTRING group, int tileColumn, int tileRow,
     STRING& tilePathname, STRING& lockPathname, bool createFullPath)
 {
-    wchar_t fileName[MAXPATHLEN] = { 0 };
-    ::swprintf(fileName, MAXPATHLEN, L"/%d_%d.", tileRow, tileColumn);
+    STRING fileName = L"/" + GetTileName(tileRow, tileColumn) + L".";
+    STRING basePath = GetBasePath(mapDef);
 
-    lockPathname = GetBasePath(mapDef);
-    tilePathname;
-
     if (createFullPath)
     {
-        tilePathname = CreateFullPath(lockPathname, scaleIndex, group);
+        tilePathname = CreateFullPath(basePath, scaleIndex, group, tileColumn, tileRow);
     }
     else
     {
-        tilePathname = GetFullPath(lockPathname, scaleIndex, group);
+        tilePathname = GetFullPath(basePath, scaleIndex, group, tileColumn, tileRow);
     }
 
-    // Generate the tile pathname using format "%ls/%d_%d.png":
+    // Generate the tile and lock pathnames
     //     <tilePathname> = <fullPath>/<row>_<column>.png
+    //     <lockPathname> = <fullPath>/<row>_<column>.lck
     tilePathname += fileName;
+    lockPathname = tilePathname;
     tilePathname += L"png";
-
-    // Generate the lock pathname using format "%ls/%d_%d.lck":
-    //     <lockPathname> = <basePath>/<row>_<column>.lck
-    lockPathname += L"/";
-    lockPathname += sm_lockFolderName;
-    lockPathname += fileName;
     lockPathname += L"lck";
 }
 
@@ -227,57 +229,53 @@
 }
 
 // gets the full path to use with the tile cache for the given base path / scale index / group
-STRING MgTileCache::GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group)
+STRING MgTileCache::GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
 {
-    // Build full path using format "%ls/%d/%ls":
-    //     <fullPath> = <basePath>/<scaleIndex>/<group>
+    // Build full path
+    //     <fullPath> = <basePath>/<scaleIndex>/<group>/<rowFolder>/<columnFolder>
     assert(!basePath.empty());
     STRING fullPath = basePath;
-    STRING buffer;
-    MgUtil::Int32ToString(scaleIndex, buffer);
 
     fullPath += L"/";
-    fullPath += buffer;
+    fullPath += GetScaleIndexFolder(scaleIndex);
+    
     fullPath += L"/";
     fullPath += group;
 
+    fullPath += L"/";
+    fullPath += GetRowFolder(tileRow);
+
+    fullPath += L"/";
+    fullPath += GetColumnFolder(tileColumn);
+
     return fullPath;
 }
 
 // gets the full path to use with the tile cache for the given map definition / scale index / group
-STRING MgTileCache::GetFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group)
+STRING MgTileCache::GetFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
 {
-    return GetFullPath(GetBasePath(mapDef), scaleIndex, group);
+    return GetFullPath(GetBasePath(mapDef), scaleIndex, group, tileColumn, tileRow);
 }
 
 // gets the full path to use with the tile cache for the given map / scale index / group
-STRING MgTileCache::GetFullPath(MgMap* map, int scaleIndex, CREFSTRING group)
+STRING MgTileCache::GetFullPath(MgMap* map, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
 {
     assert(NULL != map);
     Ptr<MgResourceIdentifier> mapDef = map->GetMapDefinition();
-    return GetFullPath(mapDef, scaleIndex, group);
+    return GetFullPath(mapDef, scaleIndex, group, tileColumn, tileRow);
 }
 
-STRING MgTileCache::CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group)
+STRING MgTileCache::CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
 {
     assert(!basePath.empty());
     STRING fullPath = basePath;
 
     // Create base directory if it does not exist.
     MgFileUtil::CreateDirectory(fullPath, false);
-    fullPath += L"/";
 
-    // Create lock directory if it does not exist.
-    STRING lockPath = fullPath;
-
-    lockPath += sm_lockFolderName;
-    MgFileUtil::CreateDirectory(lockPath, false);
-
     // Create scale directory if it does not exist.
-    STRING buffer;
-    MgUtil::Int32ToString(scaleIndex, buffer);
-
-    fullPath += buffer;
+    fullPath += L"/";
+    fullPath += GetScaleIndexFolder(scaleIndex);
     MgFileUtil::CreateDirectory(fullPath, false);
 
     // Create group directory if it does not exist.
@@ -285,15 +283,97 @@
     fullPath += group;
     MgFileUtil::CreateDirectory(fullPath, false);
 
+    // Create row directory if it does not exist.
+    fullPath += L"/";
+    fullPath += GetRowFolder(tileRow);
+    MgFileUtil::CreateDirectory(fullPath, false);
+    
+    // Create column directory if it does not exist.
+    fullPath += L"/";
+    fullPath += GetColumnFolder(tileColumn);
+    MgFileUtil::CreateDirectory(fullPath, false);
+
     return fullPath;
 }
 
-STRING MgTileCache::CreateFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group)
+STRING MgTileCache::CreateFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
 {
-    return CreateFullPath(GetBasePath(mapDef), scaleIndex, group); 
+    return CreateFullPath(GetBasePath(mapDef), scaleIndex, group, tileColumn, tileRow); 
 }
 
-STRING MgTileCache::CreateFullPath(MgMap* map, int scaleIndex, CREFSTRING group)
+STRING MgTileCache::CreateFullPath(MgMap* map, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow)
 {
-    return CreateFullPath(GetBasePath(map), scaleIndex, group); 
+    return CreateFullPath(GetBasePath(map), scaleIndex, group, tileColumn, tileRow); 
 }
+
+// Get the folder name corresponding to the specified scale index
+STRING MgTileCache::GetScaleIndexFolder(int scaleIndex)
+{
+    STRING scaleIndexString;
+    MgUtil::Int32ToString(scaleIndex, scaleIndexString);
+    return SCALE_INDEX_PREFIX + scaleIndexString;
+}
+
+// Get the folder name corresponding to the specified tile row
+STRING MgTileCache::GetRowFolder(int tileRow)
+{
+    return GetFolder(ROW_PREFIX, tileRow, sm_tileRowsPerFolder);
+}
+
+// Get the folder name corresponding to the specified tile column
+STRING MgTileCache::GetColumnFolder(int tileColumn)
+{
+    return GetFolder(COLUMN_PREFIX, tileColumn, sm_tileColumnsPerFolder);
+}
+
+// Get the parent folder for a given row or column
+STRING MgTileCache::GetFolder(STRING prefix, int tileIndex, int tilesPerFolder)
+{
+    STRING folder;    
+    
+    // Determine which folder contains this tile
+    int folderIndex = tileIndex / tilesPerFolder;
+    int firstTileIndex = folderIndex * tilesPerFolder;
+    if(tileIndex < 0 && firstTileIndex == 0)
+    {
+        folder = L"-0";
+    }
+    else
+    {
+        MgUtil::Int32ToString(firstTileIndex, folder);
+    }
+    return prefix + folder;
+}
+
+// Get the filename corresponding to the specified row and column.
+// No file extension is added.
+STRING MgTileCache::GetTileName(int tileRow, int tileColumn)
+{
+    return GetTileIndexString(tileRow, sm_tileRowsPerFolder) + L"_" +
+        GetTileIndexString(tileColumn, sm_tileColumnsPerFolder);
+}
+
+// When a tile is stored in a folder, the index value of the parent folder
+// is subtracted from the overall tile index.
+// e.g. If we store 30 rows of tiles per folder, a tile with overall row 
+// index 73 will be stored in the row folder "R60" with a row index of 13.
+// Note: Negative values are maintained even near the origin, so a tile with
+// an overall row index of -13 would be stored in row folder "R-0" with a 
+// row index of -13.
+STRING MgTileCache::GetTileIndexString(int tileIndex, int tilesPerFolder)
+{
+    STRING name;
+    
+    // Determine the offset of this tile within the folder
+    int tileNameIndex = tileIndex % tilesPerFolder;
+    if(tileIndex < 0 && tileNameIndex == 0)
+    {
+        name = L"-0";
+    }
+    else
+    {
+        MgUtil::Int32ToString(tileNameIndex, name);
+    }
+    return name;
+}
+

Modified: trunk/MgDev/Server/src/Services/Tile/TileCache.h
===================================================================
--- trunk/MgDev/Server/src/Services/Tile/TileCache.h	2007-02-09 22:59:13 UTC (rev 1100)
+++ trunk/MgDev/Server/src/Services/Tile/TileCache.h	2007-02-09 23:31:24 UTC (rev 1101)
@@ -33,8 +33,8 @@
         CREFSTRING group, int tileColumn, int tileRow,
         STRING& tilePathname, STRING& lockPathname, bool createFullPath);
 
-    STRING CreateFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group);
-    STRING CreateFullPath(MgMap* map, int scaleIndex, CREFSTRING group);
+    STRING CreateFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+    STRING CreateFullPath(MgMap* map, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
 
     MgByteReader* Get(CREFSTRING tilePathname);
     void Set(MgByteReader* img, CREFSTRING tilePathname);
@@ -56,15 +56,24 @@
     STRING GetBasePath(MgResourceIdentifier* mapDef);
     STRING GetBasePath(MgMap* map);
 
-    STRING GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group);
-    STRING GetFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group);
-    STRING GetFullPath(MgMap* map, int scaleIndex, CREFSTRING group);
+    STRING GetFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+    STRING GetFullPath(MgResourceIdentifier* mapDef, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+    STRING GetFullPath(MgMap* map, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
 
-    STRING CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group);
-
+    STRING CreateFullPath(CREFSTRING basePath, int scaleIndex, CREFSTRING group, int tileColumn, int tileRow);
+    
+    STRING GetScaleIndexFolder(int scaleIndex);
+    STRING GetRowFolder(int tileRow);
+    STRING GetColumnFolder(int tileColumn);
+    STRING GetFolder(STRING prefix, int tileIndex, int tilesPerFolder);
+    
+    STRING GetTileName(int tileRow, int tileColumn);
+    STRING GetTileIndexString(int tileIndex, int tilesPerFolder);
+    
     ACE_RW_Thread_Mutex m_rwMutex;
     static STRING sm_path;
-    static STRING sm_lockFolderName;
+    static INT32 sm_tileColumnsPerFolder;
+    static INT32 sm_tileRowsPerFolder;
 };
 
 #endif



More information about the mapguide-commits mailing list