diff options
Diffstat (limited to 'Tools/MCADefrag')
-rw-r--r-- | Tools/MCADefrag/MCADefrag.cpp | 52 | ||||
-rw-r--r-- | Tools/MCADefrag/MCADefrag.h | 68 |
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); } ; - - - - |