Using a fixed-size array instead of AString for conversion. Conversion now runs ~10x faster :) (in debug mode)

git-svn-id: http://mc-server.googlecode.com/svn/trunk@368 0a769ca7-a7f5-676a-18bf-c427514a06d6
master
madmaxoft@gmail.com 2012-03-05 17:00:35 +00:00
parent 0633c2440b
commit e4043be593
1 changed files with 29 additions and 25 deletions

View File

@ -394,7 +394,6 @@ bool cWSSCompact::cPAKFile::SaveChunk(const cChunkCoords & a_Chunk, cWorld * a_W
void cWSSCompact::cPAKFile::UpdateChunk1To2() void cWSSCompact::cPAKFile::UpdateChunk1To2()
{ {
LOGINFO("Updating \"%s\" version 1 to version 2", m_FileName.c_str() );
int Offset = 0; int Offset = 0;
AString NewDataContents; AString NewDataContents;
int ChunksConverted = 0; int ChunksConverted = 0;
@ -402,14 +401,12 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2()
{ {
sChunkHeader * Header = *itr; sChunkHeader * Header = *itr;
if( ChunksConverted % 32 == 0 ) if( ChunksConverted % 32 == 0 )
{ {
LOGINFO("Updating \"%s\" version 1 to version 2: %d%%", m_FileName.c_str(), (ChunksConverted*100) / m_ChunkHeaders.size() ); LOGINFO("Updating \"%s\" version 1 to version 2: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() );
} }
ChunksConverted++; ChunksConverted++;
AString Data; AString Data;
int UncompressedSize = Header->m_UncompressedSize; int UncompressedSize = Header->m_UncompressedSize;
Data.assign(m_DataContents, Offset, Header->m_CompressedSize); Data.assign(m_DataContents, Offset, Header->m_CompressedSize);
@ -454,56 +451,63 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2()
// Old version is 128 blocks high with YZX axis order // Old version is 128 blocks high with YZX axis order
AString ConvertedData; char ConvertedData[cChunk::c_BlockDataSize];
ConvertedData.reserve(cChunk::c_BlockDataSize); // Pre-alloc, so that push_back() and append() don't need to re-alloc int Index = 0;
unsigned int InChunkOffset = 0; unsigned int InChunkOffset = 0;
for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z )
{ {
for( int y = 0; y < 128; ++y ) for( int y = 0; y < 128; ++y )
{ {
ConvertedData.push_back( UncompressedData[y + z*128 + x*128*16 + InChunkOffset] ); ConvertedData[Index++] = UncompressedData[y + z * 128 + x * 128 * 16 + InChunkOffset];
} }
// Add 128 empty blocks after an old y column // Add 128 empty blocks after an old y column
ConvertedData.append( 128, E_BLOCK_AIR ); memset(ConvertedData + Index, E_BLOCK_AIR, 128);
Index += 128;
} }
InChunkOffset += (16*128*16); InChunkOffset += (16 * 128 * 16);
for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Metadata for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Metadata
{ {
for( int y = 0; y < 64; ++y ) for( int y = 0; y < 64; ++y )
{ {
ConvertedData.push_back( UncompressedData[y + z*64 + x*64*16 + InChunkOffset] ); ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset];
} }
ConvertedData.append( 64, 0 ); memset(ConvertedData + Index, 0, 64);
Index += 64;
} }
InChunkOffset += (16*128*16)/2; InChunkOffset += (16 * 128 * 16) / 2;
for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Block light for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Block light
{ {
for( int y = 0; y < 64; ++y ) for( int y = 0; y < 64; ++y )
{ {
ConvertedData.push_back( UncompressedData[y + z*64 + x*64*16 + InChunkOffset] ); ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset];
} }
ConvertedData.append( 64, 0 ); memset(ConvertedData + Index, 0, 64);
Index += 64;
} }
InChunkOffset += (16*128*16)/2; InChunkOffset += (16*128*16)/2;
for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Sky light for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) // Sky light
{ {
for( int y = 0; y < 64; ++y ) for( int y = 0; y < 64; ++y )
{ {
ConvertedData.push_back( UncompressedData[y + z*64 + x*64*16 + InChunkOffset] ); ConvertedData[Index++] = UncompressedData[y + z * 64 + x * 64 * 16 + InChunkOffset];
} }
ConvertedData.append( 64, 0 ); memset(ConvertedData + Index, 0, 64);
Index += 64;
} }
InChunkOffset += (16*128*16)/2; InChunkOffset += (16 * 128 * 16) / 2;
AString Converted(ConvertedData, ARRAYCOUNT(ConvertedData));
// Add JSON data afterwards // Add JSON data afterwards
if( UncompressedData.size() > InChunkOffset ) if (UncompressedData.size() > InChunkOffset)
{ {
ConvertedData.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() ); Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() );
} }
// Re-compress data // Re-compress data
AString CompressedData; AString CompressedData;
{ {
int errorcode = CompressString(ConvertedData.data(), ConvertedData.size(), CompressedData); int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData);
if (errorcode != Z_OK) if (errorcode != Z_OK)
{ {
LOGERROR("Error %d compressing data for chunk [%d, %d]", LOGERROR("Error %d compressing data for chunk [%d, %d]",
@ -514,17 +518,17 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2()
} }
} }
Header->m_UncompressedSize = ConvertedData.size(); // Save into file's cache
Header->m_UncompressedSize = Converted.size();
Header->m_CompressedSize = CompressedData.size(); Header->m_CompressedSize = CompressedData.size();
NewDataContents.append( CompressedData ); NewDataContents.append( CompressedData );
m_NumDirty++;
} }
// Done converting // Done converting
m_DataContents = NewDataContents; m_DataContents = NewDataContents;
m_ChunkVersion = 2; m_ChunkVersion = 2;
SynchronizeFile();
LOGINFO("Updated \"%s\" version 1 to version 2", m_FileName.c_str() ); LOGINFO("Updated \"%s\" version 1 to version 2", m_FileName.c_str() );
} }