summaryrefslogtreecommitdiffstats
path: root/Tools/MCADefrag
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/MCADefrag')
-rw-r--r--Tools/MCADefrag/MCADefrag.cpp52
-rw-r--r--Tools/MCADefrag/MCADefrag.h68
2 files changed, 56 insertions, 64 deletions
diff --git a/Tools/MCADefrag/MCADefrag.cpp b/Tools/MCADefrag/MCADefrag.cpp
index c7de1933b..82f5ab807 100644
--- a/Tools/MCADefrag/MCADefrag.cpp
+++ b/Tools/MCADefrag/MCADefrag.cpp
@@ -31,17 +31,17 @@ int main(int argc, char ** argv)
return EXIT_FAILURE;
}
auto fileAttachment = cLogger::GetInstance().AttachListener(std::move(fileLogListenerRet.second));
-
+
cLogger::InitiateMultithreading();
-
+
cMCADefrag Defrag;
if (!Defrag.Init(argc, argv))
{
return EXIT_FAILURE;
}
-
+
Defrag.Run();
-
+
return 0;
}
@@ -49,7 +49,7 @@ int main(int argc, char ** argv)
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
// cMCADefrag:
cMCADefrag::cMCADefrag(void) :
@@ -82,7 +82,7 @@ void cMCADefrag::Run(void)
{
StartThread();
}
-
+
// Wait for all the threads to finish:
while (!m_Threads.empty())
{
@@ -122,7 +122,7 @@ AString cMCADefrag::GetNextFileName(void)
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
// cMCADefrag::cThread:
cMCADefrag::cThread::cThread(cMCADefrag & a_Parent) :
@@ -161,7 +161,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
return;
}
LOGINFO("%s", a_FileName.c_str());
-
+
// Open input and output files:
AString OutFileName = a_FileName + ".new";
cFile In, Out;
@@ -175,7 +175,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
LOGWARNING("Cannot open file %s for writing, skipping file.", OutFileName.c_str());
return;
}
-
+
// Read the Locations and Timestamps from the input file:
Byte Locations[4096];
UInt32 Timestamps[1024];
@@ -189,7 +189,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
LOGWARNING("Cannot read Timestamps in file %s, skipping file.", a_FileName.c_str());
return;
}
-
+
// Write dummy Locations to the Out file (will be overwritten once the correct ones are known)
if (Out.Write(Locations, sizeof(Locations)) != sizeof(Locations))
{
@@ -197,14 +197,14 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
return;
}
m_CurrentSectorOut = 2;
-
+
// Write a copy of the Timestamps into the Out file:
if (Out.Write(Timestamps, sizeof(Timestamps)) != sizeof(Timestamps))
{
LOGWARNING("Cannot write Timestamps to file %s, skipping file.", OutFileName.c_str());
return;
}
-
+
// Process each chunk:
for (size_t i = 0; i < 1024; i++)
{
@@ -231,7 +231,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
return;
}
}
-
+
// Write the new Locations into the MCA header:
Out.Seek(0);
if (Out.Write(Locations, sizeof(Locations)) != sizeof(Locations))
@@ -239,7 +239,7 @@ void cMCADefrag::cThread::ProcessFile(const AString & a_FileName)
LOGWARNING("Cannot write updated Locations to file %s, skipping file.", OutFileName.c_str());
return;
}
-
+
// Close the files, delete orig, rename new:
In.Close();
Out.Close();
@@ -263,7 +263,7 @@ bool cMCADefrag::cThread::ReadChunk(cFile & a_File, const Byte * a_LocationRaw)
);
return false;
}
-
+
// Read the exact size:
Byte Buf[4];
if (a_File.Read(Buf, 4) != 4)
@@ -277,14 +277,14 @@ bool cMCADefrag::cThread::ReadChunk(cFile & a_File, const Byte * a_LocationRaw)
LOGWARNING("Invalid chunk data - SizeInSectors (%d) smaller that RealSize (%d)", SizeInSectors, m_CompressedChunkDataSize);
return false;
}
-
+
// Read the data:
if (a_File.Read(m_CompressedChunkData, static_cast<size_t>(m_CompressedChunkDataSize)) != m_CompressedChunkDataSize)
{
LOGWARNING("Failed to read chunk data!");
return false;
}
-
+
// Uncompress the data if recompression is active
if (m_Parent.m_ShouldRecompress)
{
@@ -294,7 +294,7 @@ bool cMCADefrag::cThread::ReadChunk(cFile & a_File, const Byte * a_LocationRaw)
LOGINFO("Chunk failed to uncompress, will be copied verbatim instead.");
}
}
-
+
return true;
}
@@ -312,14 +312,14 @@ bool cMCADefrag::cThread::WriteChunk(cFile & a_File, Byte * a_LocationRaw)
LOGINFO("Chunk failed to recompress, will be coped verbatim instead.");
}
}
-
+
// Update the Location:
a_LocationRaw[0] = static_cast<Byte>(m_CurrentSectorOut >> 16);
a_LocationRaw[1] = (m_CurrentSectorOut >> 8) & 0xff;
a_LocationRaw[2] = m_CurrentSectorOut & 0xff;
a_LocationRaw[3] = static_cast<Byte>((m_CompressedChunkDataSize + (4 KiB) + 3) / (4 KiB)); // +3 because the m_CompressedChunkDataSize doesn't include the exact-length
m_CurrentSectorOut += a_LocationRaw[3];
-
+
// Write the data length:
Byte Buf[4];
Buf[0] = static_cast<Byte>(m_CompressedChunkDataSize >> 24);
@@ -331,14 +331,14 @@ bool cMCADefrag::cThread::WriteChunk(cFile & a_File, Byte * a_LocationRaw)
LOGWARNING("Failed to write chunk length!");
return false;
}
-
+
// Write the data:
if (a_File.Write(m_CompressedChunkData, static_cast<size_t>(m_CompressedChunkDataSize)) != m_CompressedChunkDataSize)
{
LOGWARNING("Failed to write chunk data!");
return false;
}
-
+
// Pad onto the next sector:
int NumPadding = a_LocationRaw[3] * 4096 - (m_CompressedChunkDataSize + 4);
ASSERT(NumPadding >= 0);
@@ -347,7 +347,7 @@ bool cMCADefrag::cThread::WriteChunk(cFile & a_File, Byte * a_LocationRaw)
LOGWARNING("Failed to write padding");
return false;
}
-
+
return true;
}
@@ -419,7 +419,7 @@ bool cMCADefrag::cThread::CompressChunk(void)
LOGINFO("Too much data for the internal compression buffer!");
return false;
}
-
+
// Compress the data using the highest compression factor:
int errorcode = compress2(m_CompressedChunkData + 1, &CompressedSize, m_RawChunkData, static_cast<uLong>(m_RawChunkDataSize), Z_BEST_COMPRESSION);
if (errorcode != Z_OK)
@@ -432,7 +432,3 @@ bool cMCADefrag::cThread::CompressChunk(void)
m_CompressedChunkDataSize = static_cast<int>(CompressedSize + 1);
return true;
}
-
-
-
-
diff --git a/Tools/MCADefrag/MCADefrag.h b/Tools/MCADefrag/MCADefrag.h
index d7fa1fc6e..cddaef625 100644
--- a/Tools/MCADefrag/MCADefrag.h
+++ b/Tools/MCADefrag/MCADefrag.h
@@ -22,26 +22,26 @@ public:
MAX_COMPRESSED_CHUNK_DATA_SIZE = (1 MiB),
MAX_RAW_CHUNK_DATA_SIZE = (100 MiB),
} ;
-
+
cMCADefrag(void);
-
+
/** Reads the cmdline params and initializes the app.
Returns true if the app should continue, false if not. */
bool Init(int argc, char ** argv);
-
+
/** Runs the entire app. */
void Run(void);
-
+
protected:
/** A single thread processing MCA files from the queue */
class cThread :
public cIsThread
{
typedef cIsThread super;
-
+
public:
cThread(cMCADefrag & a_Parent);
-
+
protected:
/** The compression methods, as specified by the MCA compression method byte. */
enum
@@ -50,35 +50,35 @@ protected:
COMPRESSION_ZLIB = 2,
} ;
-
+
cMCADefrag & m_Parent;
-
+
/** The current compressed chunk data. Valid after a successful ReadChunk().
This contains only the compression method byte and the compressed data,
but not the exact-length preceding the data in the MCA file. */
unsigned char m_CompressedChunkData[MAX_COMPRESSED_CHUNK_DATA_SIZE];
-
+
/** Size of the actual current compressed chunk data, excluding the 4 exact-length bytes.
This is the amount of bytes in m_CompressedChunkData[] that are valid. */
int m_CompressedChunkDataSize;
-
+
/** The current raw chunk data. Valid after a successful ReadChunk(), if recompression is active. */
unsigned char m_RawChunkData[MAX_RAW_CHUNK_DATA_SIZE];
-
+
/** Size of the actual current raw chunk data. */
int m_RawChunkDataSize;
-
+
/** Number of the sector where the next chunk will be written by WriteChunk(). */
int m_CurrentSectorOut;
-
+
/** Set to true when the chunk has been successfully uncompressed. Only used if recompression is active.
WriteChunk() tests this flag to decide whether to call Compress(). */
bool m_IsChunkUncompressed;
-
-
+
+
/** Processes the specified file. */
void ProcessFile(const AString & a_FileName);
-
+
/** Reads the chunk data into m_CompressedChunkData.
Calls DecompressChunkData() if recompression is active.
a_LocationRaw is the pointer to the first byte of the Location data in the MCA header.
@@ -90,55 +90,51 @@ protected:
a_LocationRaw is the pointer to the first byte of the Location data to be put into the MCA header,
the chunk's location is stored in that memory area. Updates m_CurrentSectorOut.
Returns true if successful. */
- bool WriteChunk(cFile & a_File, Byte * a_LocationRaw);
-
+ bool WriteChunk(cFile & a_File, Byte * a_LocationRaw);
+
/** Uncompresses the chunk data from m_CompressedChunkData into m_RawChunkData.
Returns true if successful, false on failure. */
bool UncompressChunk(void);
-
+
/** Uncompresses the chunk data from m_CompressedChunkData into m_RawChunkData, using Gzip.
Returns true if successful, false on failure. */
bool UncompressChunkGzip(void);
-
+
/** Uncompresses the chunk data from m_CompressedChunkData into m_RawChunkData, using Zlib.
Returns true if successful, false on failure. */
bool UncompressChunkZlib(void);
-
+
/** Compresses the chunk data from m_RawChunkData into m_CompressedChunkData.
Returns true if successful, false on failure. */
bool CompressChunk(void);
-
+
// cIsThread overrides:
virtual void Execute(void) override;
} ;
-
+
typedef std::list<cThread *> cThreads;
-
-
+
+
/** The mutex protecting m_Files agains multithreaded access. */
cCriticalSection m_CS;
-
+
/** The queue of MCA files to be processed by the threads. Protected by m_CS. */
AStringVector m_Queue;
-
+
/** List of threads that the server has running. */
cThreads m_Threads;
-
+
/** The number of threads that should be started. Configurable on the command line. */
int m_NumThreads;
-
+
/** If set to true, the chunk data is recompressed while saving each MCA file. */
bool m_ShouldRecompress;
-
-
+
+
/** Starts a new processing thread and adds it to cThreads. */
void StartThread(void);
-
+
/** Retrieves one file from the queue (and removes it from the queue).
Returns an empty string when queue empty. */
AString GetNextFileName(void);
} ;
-
-
-
-