2014-02-13 05:47:20 -05:00
|
|
|
|
|
|
|
// MCADefrag.h
|
|
|
|
|
|
|
|
// Interfaces to the cMCADefrag class encapsulating the entire app
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class cMCADefrag
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
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:
|
2014-02-13 10:54:29 -05:00
|
|
|
/** The compression methods, as specified by the MCA compression method byte. */
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
COMPRESSION_GZIP = 1,
|
|
|
|
COMPRESSION_ZLIB = 2,
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
2014-02-13 05:47:20 -05:00
|
|
|
cMCADefrag & m_Parent;
|
|
|
|
|
|
|
|
/** The current compressed chunk data. Valid after a successful ReadChunk().
|
|
|
|
This contains only the compression method byte and the compressed data,
|
2014-02-13 06:48:22 -05:00
|
|
|
but not the exact-length preceding the data in the MCA file. */
|
2014-02-13 05:47:20 -05:00
|
|
|
unsigned char m_CompressedChunkData[MAX_COMPRESSED_CHUNK_DATA_SIZE];
|
|
|
|
|
2014-02-13 06:48:22 -05:00
|
|
|
/** 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. */
|
2014-02-13 05:47:20 -05:00
|
|
|
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;
|
|
|
|
|
2014-02-13 10:54:29 -05:00
|
|
|
/** 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;
|
|
|
|
|
2014-02-13 05:47:20 -05:00
|
|
|
|
|
|
|
/** 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.
|
|
|
|
Returns true if successful. */
|
|
|
|
bool ReadChunk(cFile & a_File, const Byte * a_LocationRaw);
|
|
|
|
|
|
|
|
/** Writes the chunk data from m_CompressedData or m_RawChunkData (performing recompression) into file.
|
|
|
|
Calls CompressChunkData() for the actual compression, if recompression is active.
|
|
|
|
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);
|
|
|
|
|
2014-02-13 10:54:29 -05:00
|
|
|
/** 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);
|
|
|
|
|
2014-02-13 05:47:20 -05:00
|
|
|
// 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;
|
|
|
|
|
2014-02-13 10:54:29 -05:00
|
|
|
/** If set to true, the chunk data is recompressed while saving each MCA file. */
|
|
|
|
bool m_ShouldRecompress;
|
|
|
|
|
2014-02-13 05:47:20 -05:00
|
|
|
|
|
|
|
/** 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);
|
|
|
|
} ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|