summaryrefslogtreecommitdiffstats
path: root/Tools/MCADefrag/MCADefrag.h
blob: cddaef6255867241cb7fb3b21f2563ea72a938e0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

// 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:
		/** The compression methods, as specified by the MCA compression method byte. */
		enum
		{
			COMPRESSION_GZIP = 1,
			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.
		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);

		/** 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);
} ;