From bf864f4fdd873f44ebc16cd95a536e2a8c67cebf Mon Sep 17 00:00:00 2001 From: Wanne Date: Sun, 2 Oct 2011 14:03:02 +0000 Subject: [PATCH] - Improved tactical save code (by tazpn) o After some investigation I determined that the one of the files in the temp folder was being written to repeatedly and on top of that opening and closing over a 1500 times o Instead of writing to in memory arrays before writing to disk its opening many temporary files and appending data to them repeatedly o I rewrote part of the code so that it only opened the files once and wrote to them and would create them fresh when it did. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4665 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/Tactical Save.cpp | 14 +- TileEngine/SaveLoadMap.cpp | 262 ++++++++++++++++++++++++++++++++----- 2 files changed, 242 insertions(+), 34 deletions(-) diff --git a/Tactical/Tactical Save.cpp b/Tactical/Tactical Save.cpp index e7798c6f..05bfbeb8 100644 --- a/Tactical/Tactical Save.cpp +++ b/Tactical/Tactical Save.cpp @@ -921,6 +921,7 @@ BOOLEAN AddItemsToUnLoadedSector( INT16 sMapX, INT16 sMapY, INT8 bMapZ, INT32 sG } extern BOOLEAN gfInMeanwhile; +extern BOOLEAN EnableModifiedFileSetCache(BOOLEAN value); BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) { @@ -942,6 +943,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) return( TRUE ); } + BOOLEAN cacheResetValue = EnableModifiedFileSetCache(TRUE); //Save the Blood, smell and the revealed status for map elements SaveBloodSmellAndRevealedStatesFromMapToTempFile(); @@ -949,12 +951,11 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) // handle all reachable before save HandleAllReachAbleItemsInTheSector( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - - //Save the Items to the the file if( !SaveWorldItemsToTempItemFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, guiNumWorldItems, gWorldItems ) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in SaveWorldItemsToTempItemFile()" ) ); + EnableModifiedFileSetCache(cacheResetValue); return( FALSE ); } @@ -962,6 +963,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) if( !SaveRottingCorpsesToTempCorpseFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in SaveRottingCorpsesToTempCorpseFile()" ) ); + EnableModifiedFileSetCache(cacheResetValue); return( FALSE ); } @@ -969,6 +971,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) if( !SaveDoorTableToDoorTableTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in SaveDoorTableToDoorTableTempFile()" ) ); + EnableModifiedFileSetCache(cacheResetValue); return( FALSE ); } @@ -976,6 +979,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) if( !SaveRevealedStatusArrayToRevealedTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in SaveRevealedStatusArrayToRevealedTempFile()" ) ); + EnableModifiedFileSetCache(cacheResetValue); return( FALSE ); } @@ -983,6 +987,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) if( !SaveDoorStatusArrayToDoorStatusTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in SaveDoorStatusArrayToDoorStatusTempFile()" ) ); + EnableModifiedFileSetCache(cacheResetValue); return( FALSE ); } @@ -990,6 +995,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) if( !NewWayOfSavingEnemyAndCivliansToTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, TRUE, FALSE ) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in NewWayOfSavingEnemyAndCivliansToTempFile( Enemy, Creature Team )" ) ); + EnableModifiedFileSetCache(cacheResetValue); return( FALSE ); } @@ -997,6 +1003,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) if( !NewWayOfSavingEnemyAndCivliansToTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, FALSE, FALSE ) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in NewWayOfSavingEnemyAndCivliansToTempFile( Civ Team )" ) ); + EnableModifiedFileSetCache(cacheResetValue); return( FALSE ); } @@ -1004,6 +1011,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) if( !SaveSmokeEffectsToMapTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in SaveSmokeEffectsToMapTempFile" ) ); + EnableModifiedFileSetCache(cacheResetValue); return( FALSE ); } @@ -1011,6 +1019,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) if( !SaveLightEffectsToMapTempFile( gWorldSectorX, gWorldSectorY, gbWorldSectorZ ) ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("SaveCurrentSectorsInformationToTempItemFile: failed in SaveLightEffectsToMapTempFile" ) ); + EnableModifiedFileSetCache(cacheResetValue); return( FALSE ); } @@ -1026,6 +1035,7 @@ BOOLEAN SaveCurrentSectorsInformationToTempItemFile( ) //Save the time the player was last in the sector SetLastTimePlayerWasInSector(); + EnableModifiedFileSetCache(cacheResetValue); if( fShouldBeInMeanwhile ) { diff --git a/TileEngine/SaveLoadMap.cpp b/TileEngine/SaveLoadMap.cpp index 65831287..987a8e22 100644 --- a/TileEngine/SaveLoadMap.cpp +++ b/TileEngine/SaveLoadMap.cpp @@ -44,9 +44,180 @@ void DamageStructsFromMapTempFile( MODIFY_MAP * pMap ); BOOLEAN ModifyWindowStatus( INT32 uiMapIndex ); //ppp +struct ModifiedMapFile +{ + UINT32 uiType; + INT16 sMapX; + INT16 sMapY; + INT8 bMapZ; + CHAR8 szMapName[128]; + HWFILE hFileHandle; + ModifiedMapFile(UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ) + { + this->uiType = uiType; + this->sMapX = sMapX; + this->sMapY = sMapY; + this->bMapZ = bMapZ; + this->szMapName[0] = 0; + this->hFileHandle = NULL; + } + ModifiedMapFile(UINT32 uiType, STR pMapName, INT16 sMapX, INT16 sMapY, INT8 bMapZ) + { + this->uiType = uiType; + this->sMapX = sMapX; + this->sMapY = sMapY; + this->bMapZ = bMapZ; + strncpy(this->szMapName, pMapName, _countof(this->szMapName)); + this->szMapName[_countof(this->szMapName) - 1] = 0; + this->hFileHandle = NULL; + } + ~ModifiedMapFile() + { + if (this->hFileHandle != NULL) + { + FileClose(this->hFileHandle); + this->hFileHandle = NULL; + } + } + + BOOLEAN IsOpen() const + { + return (this->hFileHandle == NULL) ? FALSE : TRUE; + } + + BOOLEAN Open() + { + if ( hFileHandle == NULL && szMapName[0] != 0) + { + // we assume that we 'own' the file + hFileHandle = FileOpen( szMapName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE ); + + //Move to the end of the file + FileSeek( hFileHandle, 0, FILE_SEEK_FROM_END ); + } + return IsOpen(); + } + + void Delete() + { + Close(); + + if (szMapName[0] != 0) + { + FileDelete(szMapName); + } + } + + BOOLEAN Write( PTR pDest, UINT32 uiBytesToWrite ) + { + UINT32 uiNumBytesWritten = 0; + if (!IsOpen()) return FALSE; + + if ( !FileWrite( this->hFileHandle, pDest, uiBytesToWrite, &uiNumBytesWritten ) ) + { + Close(); + return FALSE; + } + if (uiBytesToWrite != uiNumBytesWritten) + { + Close(); + return FALSE; + } + return TRUE; + } + + void Close() + { + if (this->hFileHandle != NULL) + { + FileClose(this->hFileHandle); + this->hFileHandle = NULL; + } + } +}; + +struct ltMMF +{ + bool compare(const ModifiedMapFile& s1, const ModifiedMapFile& s2) const + { + int diff = s1.uiType - s2.uiType; + if (diff == 0) + { + diff = s1.sMapX - s2.sMapX; + if (diff == 0) + { + diff = s1.sMapY - s2.sMapY; + if (diff == 0) + { + diff = s1.bMapZ - s2.bMapZ; + } + } + } + return diff < 0; + } + bool operator()(const ModifiedMapFile& s1, const ModifiedMapFile& s2) const { return compare(s1, s2); } + bool operator()(const ModifiedMapFile* s1, const ModifiedMapFile* s2) const { return compare(*s1, *s2); } + bool operator()(const ModifiedMapFile& s1, const ModifiedMapFile* s2) const { return compare(s1, *s2); } + bool operator()(const ModifiedMapFile* s1, const ModifiedMapFile& s2) const { return compare(*s1, s2); } +}; + +typedef std::set ModifiedMapFileSet; +ModifiedMapFileSet g_mapFileSet; +BOOLEAN g_useSaveCache; + +void ClearTempFileSets() +{ + //for (ModifiedMapFileSet::iterator itr = g_mapFileSet.begin(), end = g_mapFileSet.end(); itr != end; ++itr ) + //{ + //} + // destructor will close any open file handles + g_mapFileSet.clear(); +} + +BOOLEAN EnableModifiedFileSetCache(BOOLEAN value) +{ + BOOLEAN previousValue = g_useSaveCache; + if (g_useSaveCache != value) + { + ClearTempFileSets(); + } + g_useSaveCache = value; + return previousValue; +} + +bool TryGetModifiedMapFile( UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ, ModifiedMapFile** ppMMF ) +{ + if (ppMMF == NULL) + return false; + + ModifiedMapFile key(uiType, sMapX, sMapY, bMapZ); + ModifiedMapFileSet::iterator itr = g_mapFileSet.find(key); + if (itr == g_mapFileSet.end()) + { + *ppMMF = NULL; + return false; + } + *ppMMF = &(*itr); + return true; +} + +ModifiedMapFile& GetOrCreateModifiedMapFile(UINT32 uiType, INT16 sMapX, INT16 sMapY, INT8 bMapZ) +{ + ModifiedMapFile* pResult = NULL; + if ( TryGetModifiedMapFile(uiType, sMapX, sMapY, bMapZ, &pResult) ) + return *pResult; + + ModifiedMapFile key(uiType, sMapX, sMapY, bMapZ); + ModifiedMapFileSet::iterator itr = g_mapFileSet.insert(g_mapFileSet.end(), key); + pResult = &(*itr); + + GetMapTempFileName( pResult->uiType, pResult->szMapName, pResult->sMapX, pResult->sMapY, pResult->bMapZ ); + + return *pResult; +} void ApplyMapChangesToMapTempFile( BOOLEAN fAddToMap ) { @@ -56,43 +227,64 @@ void ApplyMapChangesToMapTempFile( BOOLEAN fAddToMap ) BOOLEAN SaveModifiedMapStructToMapTempFile( MODIFY_MAP *pMap, INT16 sSectorX, INT16 sSectorY, INT8 bSectorZ ) { - CHAR8 zMapName[ 128 ]; - HWFILE hFile; - UINT32 uiNumBytesWritten; - - //Convert the current sector location into a file name -// GetMapFileName( sSectorX, sSectorY, bSectorZ, zTempName, FALSE ); - - //add the 'm' for 'Modifed Map' to the front of the map name -// sprintf( zMapName, "%s\\m_%s", MAPS_DIR, zTempName); - - GetMapTempFileName( SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS, zMapName, sSectorX, sSectorY, bSectorZ ); - - //Open the file for writing, Create it if it doesnt exist - hFile = FileOpen( zMapName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE ); - if( hFile == 0 ) + if (g_useSaveCache) { - //Error opening map modification file - return( FALSE ); + ModifiedMapFile& rMMF = GetOrCreateModifiedMapFile(SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS, sSectorX, sSectorY, bSectorZ); + if( !rMMF.Open() ) + { + //Error opening map modification file + return( FALSE ); + } + + if ( !rMMF.Write( pMap, sizeof( MODIFY_MAP ) ) ) + { + return( FALSE ); + } + + SetSectorFlag( sSectorX, sSectorY, bSectorZ, SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS ); + + return( TRUE ); } - - //Move to the end of the file - FileSeek( hFile, 0, FILE_SEEK_FROM_END ); - - - FileWrite( hFile, pMap, sizeof( MODIFY_MAP ), &uiNumBytesWritten ); - if( uiNumBytesWritten != sizeof( MODIFY_MAP ) ) + else { - //Error Writing size of array to disk + CHAR8 zMapName[ 128 ]; + HWFILE hFile; + UINT32 uiNumBytesWritten; + + //Convert the current sector location into a file name + // GetMapFileName( sSectorX, sSectorY, bSectorZ, zTempName, FALSE ); + + //add the 'm' for 'Modifed Map' to the front of the map name + // sprintf( zMapName, "%s\\m_%s", MAPS_DIR, zTempName); + + GetMapTempFileName( SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS, zMapName, sSectorX, sSectorY, bSectorZ ); + + //Open the file for writing, Create it if it doesnt exist + hFile = FileOpen( zMapName, FILE_ACCESS_WRITE | FILE_OPEN_ALWAYS, FALSE ); + if( hFile == 0 ) + { + //Error opening map modification file + return( FALSE ); + } + + //Move to the end of the file + FileSeek( hFile, 0, FILE_SEEK_FROM_END ); + + + FileWrite( hFile, pMap, sizeof( MODIFY_MAP ), &uiNumBytesWritten ); + if( uiNumBytesWritten != sizeof( MODIFY_MAP ) ) + { + //Error Writing size of array to disk + FileClose( hFile ); + return( FALSE ); + } + FileClose( hFile ); - return( FALSE ); + + SetSectorFlag( sSectorX, sSectorY, bSectorZ, SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS ); + + return( TRUE ); } - - FileClose( hFile ); - - SetSectorFlag( sSectorX, sSectorY, bSectorZ, SF_MAP_MODIFICATIONS_TEMP_FILE_EXISTS ); - - return( TRUE ); } @@ -161,6 +353,9 @@ BOOLEAN LoadAllMapChangesFromMapTempFileAndApplyThem( ) //Delete the file FileDelete( zMapName ); + // Begin save cache + EnableModifiedFileSetCache(TRUE); + uiNumberOfElements = uiFileSize / sizeof( MODIFY_MAP ); for( cnt=0; cnt< uiNumberOfElements; cnt++ ) @@ -313,6 +508,9 @@ BOOLEAN LoadAllMapChangesFromMapTempFileAndApplyThem( ) MemFree( pTempArrayOfMaps ); pTempArrayOfMaps = NULL; + // Flush any open file sets + EnableModifiedFileSetCache(FALSE); + return( TRUE ); }