summaryrefslogtreecommitdiffstats
path: root/libktorrent/torrent/downloader.h
blob: 5b39eebe0bf1fd28b8503b51b7a03a379e8cf568 (plain)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/***************************************************************************
 *   Copyright (C) 2005 by Joris Guisson                                   *
 *   joris.guisson@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.             *
 ***************************************************************************/
#ifndef BTDOWNLOADER_H
#define BTDOWNLOADER_H

#include <qobject.h>
#include <util/ptrmap.h>
#include "globals.h"

namespace kt
{
	class MonitorInterface;
}


namespace bt
{
	class BitSet;
	class Torrent;
	class ChunkManager;
	class PeerManager;
	class Peer;
	class Chunk;
	class ChunkDownload;
	class PeerDownloader;
	class Piece;
	class Request;
	class ChunkSelector;

	typedef PtrMap<Uint32,ChunkDownload>::iterator CurChunkItr;
	typedef PtrMap<Uint32,ChunkDownload>::const_iterator CurChunkCItr;
	
	#define CURRENT_CHUNK_MAGIC 0xABCDEF00
	
	struct CurrentChunksHeader
	{
		Uint32 magic; // CURRENT_CHUNK_MAGIC
		Uint32 major;
		Uint32 minor;
		Uint32 num_chunks;
	};
	
	/**
	 * @author Joris Guisson
	 * @brief Manages the downloading
	 *
	 * This class manages the downloading of the file. It should
	 * regurarly be updated.
	*/
	class Downloader : public QObject
	{
		Q_OBJECT
		
	public:
		/**
		 * Constructor.
		 * @param tor The Torrent
		 * @param pman The PeerManager
		 * @param cman The ChunkManager
		 */
		Downloader(Torrent & tor,PeerManager & pman,ChunkManager & cman);
		virtual ~Downloader();

		/// Get the number of bytes we have downloaded
		Uint64 bytesDownloaded() const {return downloaded + curr_chunks_downloaded;}

		/// Get the current dowload rate
		Uint32 downloadRate() const;

		/// Get the number of chunks we are dowloading
		Uint32 numActiveDownloads() const {return current_chunks.count();}

		/// See if the download is finished.
		bool isFinished() const;
		
		/**
		 * Clear all downloads. Deletes all active downloads.
		 */
		void clearDownloads();
		
		CurChunkCItr beginDownloads() const {return current_chunks.begin();}
		CurChunkCItr endDownloads() const {return current_chunks.end();}

		/**
		 * See if we are downloading a Chunk
		 * @param chunk ID of Chunk
		 * @return true if we are, false if not
		 */
		bool areWeDownloading(Uint32 chunk) const;

		/**
		 * Save the current downloads.
		 * @param file The file to save to
		 */
		void saveDownloads(const QString & file);

		/**
		 * Load the current downloads.
		 * @param file The file to load from
		 */
		void loadDownloads(const QString & file);

		/**
		 * Get the number of bytes already downloaded in the current_chunks file.
		 * @param file The path of the current_chunks file
		 * @return The bytes already downloading
		 */
		Uint32 getDownloadedBytesOfCurrentChunksFile(const QString & file);
		
		/**
		 * A corrupted chunk has been detected, make sure we redownload it.
		 * @param chunk The chunk
		 */
		void corrupted(Uint32 chunk);
	public slots:
		/**
		 * Update the downloader.
		 */
		void update();
		
		/**
		 * We got a new connection.
		 * @param peer The Peer
		 */
		void onNewPeer(Peer* peer);
		
		/**
		 * A Peer has disconnected.
		 * @param peer The Peer
		 */
		void onPeerKilled(Peer* peer);
		
		/**
		 * Set the TorrentMonitor.
		 * @param tmo 
		 */
		void setMonitor(kt::MonitorInterface* tmo);
		
		static void setMemoryUsage(Uint32 m);
		
		/**
		 * Data has been checked, and these chunks are OK.
		 * @param ok_chunks The ok_chunks
		 */
		void dataChecked(const BitSet & ok_chunks);
		
		/**
		 * Recalculate the number of bytes downloaded.
		 */
		void recalcDownloaded();
		
	private slots:
		void pieceRecieved(const Piece & p);
		bool finished(ChunkDownload* c);
		
		/**
		 * Kill all ChunkDownload's which have been excluded.
		 * @param from First chunk of range
		 * @param to Last chunk of range
		 */
		void onExcluded(Uint32 from,Uint32 to);
		
		/**
		 * Make sure chunk selector is back OK, when chunks are included back again.
		 * @param from First chunk
		 * @param to Last chunk
		 */
		void onIncluded(Uint32 from,Uint32 to);
		
	signals:
		/**
		 * An error occurred while we we're writing or reading from disk.
		 * @param msg Message
		 */
		void ioError(const QString & msg);
		
	private:
		void downloadFrom(PeerDownloader* pd);
		void normalUpdate();
		Uint32 maxMemoryUsage();
		Uint32 numNonIdle();
		bool findDownloadForPD(PeerDownloader* pd,bool warmup);
		ChunkDownload* selectCD(PeerDownloader* pd,Uint32 num);
		ChunkDownload* selectWorst(PeerDownloader* pd);
		
	private:
		Torrent & tor;
		PeerManager & pman;
		ChunkManager & cman;
		Uint64 downloaded;
		Uint64 curr_chunks_downloaded;
		Uint64 unnecessary_data;
		PtrMap<Uint32,ChunkDownload> current_chunks;
		ChunkSelector* chunk_selector;
		
		kt::MonitorInterface* tmon;
		static Uint32 mem_usage;
	};
	


}

#endif