1 /* <!-- copyright */
2 /*
3  * aria2 - The high speed download utility
4  *
5  * Copyright (C) 2006 Tatsuhiro Tsujikawa
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  * In addition, as a special exception, the copyright holders give
22  * permission to link the code of portions of this program with the
23  * OpenSSL library under certain conditions as described in each
24  * individual source file, and distribute linked combinations
25  * including the two.
26  * You must obey the GNU General Public License in all respects
27  * for all of the code used other than OpenSSL.  If you modify
28  * file(s) with this exception, you may extend this exception to your
29  * version of the file(s), but you are not obligated to do so.  If you
30  * do not wish to do so, delete this exception statement from your
31  * version.  If you delete this exception statement from all source
32  * files in the program, then also delete it here.
33  */
34 /* copyright --> */
35 #ifndef D_DEFAULT_PIECE_STORAGE_H
36 #define D_DEFAULT_PIECE_STORAGE_H
37 
38 #include "PieceStorage.h"
39 
40 #include <deque>
41 #include <set>
42 
43 #include "a2functional.h"
44 
45 namespace aria2 {
46 
47 class DownloadContext;
48 class BitfieldMan;
49 class Option;
50 class DiskWriterFactory;
51 class FileEntry;
52 class PieceStatMan;
53 class PieceSelector;
54 class StreamPieceSelector;
55 
56 #define END_GAME_PIECE_NUM 20
57 
58 struct HaveEntry {
HaveEntryHaveEntry59   HaveEntry(uint64_t haveIndex, cuid_t cuid, size_t index, Timer registeredTime)
60       : haveIndex(haveIndex),
61         cuid(cuid),
62         index(index),
63         registeredTime(std::move(registeredTime))
64   {
65   }
66 
67   uint64_t haveIndex;
68   cuid_t cuid;
69   size_t index;
70   Timer registeredTime;
71 };
72 
73 class DefaultPieceStorage : public PieceStorage {
74 private:
75   std::shared_ptr<DownloadContext> downloadContext_;
76   std::unique_ptr<BitfieldMan> bitfieldMan_;
77   std::shared_ptr<DiskAdaptor> diskAdaptor_;
78   std::shared_ptr<DiskWriterFactory> diskWriterFactory_;
79   typedef std::set<std::shared_ptr<Piece>, DerefLess<std::shared_ptr<Piece>>>
80       UsedPieceSet;
81   UsedPieceSet usedPieces_;
82 
83   bool endGame_;
84   size_t endGamePieceNum_;
85   const Option* option_;
86 
87   // The next unique index on HaveEntry, which is ever strictly
88   // increasing sequence of integer.
89   uint64_t nextHaveIndex_;
90   std::deque<HaveEntry> haves_;
91 
92   std::shared_ptr<PieceStatMan> pieceStatMan_;
93 
94   std::unique_ptr<PieceSelector> pieceSelector_;
95   std::unique_ptr<StreamPieceSelector> streamPieceSelector_;
96 
97   WrDiskCache* wrDiskCache_;
98 #ifdef ENABLE_BITTORRENT
99   void getMissingPiece(std::vector<std::shared_ptr<Piece>>& pieces,
100                        size_t minMissingBlocks, const unsigned char* bitfield,
101                        size_t length, cuid_t cuid);
102 
103   void createFastIndexBitfield(BitfieldMan& bitfield,
104                                const std::shared_ptr<Peer>& peer);
105 #endif // ENABLE_BITTORRENT
106 
107   std::shared_ptr<Piece> checkOutPiece(size_t index, cuid_t cuid);
108   //   size_t deleteUsedPiecesByFillRate(int fillRate, size_t toDelete);
109   //   void reduceUsedPieces(size_t upperBound);
110   void deleteUsedPiece(const std::shared_ptr<Piece>& piece);
111   std::shared_ptr<Piece> findUsedPiece(size_t index) const;
112 
113   // Returns the sum of completed length of in-flight pieces
114   int64_t getInFlightPieceCompletedLength() const;
115   // Returns the sum of completed length of in-flight pieces
116   // intersecting filter ranges.
117   int64_t getInFlightPieceFilteredCompletedLength() const;
118 
119 public:
120   // Setting randomPieceStatsOrdering to true means a piece is chosen in
121   // random when more than 2 pieces has the same rarity.
122   // If it is set to false, a piece whose index is smallest has the highest
123   // priority.
124   DefaultPieceStorage(const std::shared_ptr<DownloadContext>& downloadContext,
125                       const Option* option);
126 
127   virtual ~DefaultPieceStorage();
128 
129 #ifdef ENABLE_BITTORRENT
130 
131   virtual bool
132   hasMissingPiece(const std::shared_ptr<Peer>& peer) CXX11_OVERRIDE;
133 
134   virtual void getMissingPiece(std::vector<std::shared_ptr<Piece>>& pieces,
135                                size_t minMissingBlocks,
136                                const std::shared_ptr<Peer>& peer,
137                                cuid_t cuid) CXX11_OVERRIDE;
138 
139   virtual void getMissingPiece(std::vector<std::shared_ptr<Piece>>& pieces,
140                                size_t minMissingBlocks,
141                                const std::shared_ptr<Peer>& peer,
142                                const std::vector<size_t>& excludedIndexes,
143                                cuid_t cuid) CXX11_OVERRIDE;
144 
145   virtual void getMissingFastPiece(std::vector<std::shared_ptr<Piece>>& pieces,
146                                    size_t minMissingBlocks,
147                                    const std::shared_ptr<Peer>& peer,
148                                    cuid_t cuid) CXX11_OVERRIDE;
149 
150   virtual void getMissingFastPiece(std::vector<std::shared_ptr<Piece>>& pieces,
151                                    size_t minMissingBlocks,
152                                    const std::shared_ptr<Peer>& peer,
153                                    const std::vector<size_t>& excludedIndexes,
154                                    cuid_t cuid) CXX11_OVERRIDE;
155 
156   virtual std::shared_ptr<Piece>
157   getMissingPiece(const std::shared_ptr<Peer>& peer,
158                   cuid_t cuid) CXX11_OVERRIDE;
159 
160   virtual std::shared_ptr<Piece>
161   getMissingPiece(const std::shared_ptr<Peer>& peer,
162                   const std::vector<size_t>& excludedIndexes,
163                   cuid_t cuid) CXX11_OVERRIDE;
164 
165   std::shared_ptr<Piece> getMissingFastPiece(const std::shared_ptr<Peer>& peer,
166                                              cuid_t cuid);
167 
168   std::shared_ptr<Piece>
169   getMissingFastPiece(const std::shared_ptr<Peer>& peer,
170                       const std::vector<size_t>& excludedIndexes, cuid_t cuid);
171 
172 #endif // ENABLE_BITTORRENT
173 
174   virtual bool hasMissingUnusedPiece() CXX11_OVERRIDE;
175 
176   virtual std::shared_ptr<Piece>
177   getMissingPiece(size_t minSplitSize, const unsigned char* ignoreBitfield,
178                   size_t length, cuid_t cuid) CXX11_OVERRIDE;
179 
180   virtual std::shared_ptr<Piece> getMissingPiece(size_t index,
181                                                  cuid_t cuid) CXX11_OVERRIDE;
182 
183   virtual std::shared_ptr<Piece> getPiece(size_t index) CXX11_OVERRIDE;
184 
185   virtual void
186   completePiece(const std::shared_ptr<Piece>& piece) CXX11_OVERRIDE;
187 
188   virtual void cancelPiece(const std::shared_ptr<Piece>& piece,
189                            cuid_t cuid) CXX11_OVERRIDE;
190 
191   virtual bool hasPiece(size_t index) CXX11_OVERRIDE;
192 
193   virtual bool isPieceUsed(size_t index) CXX11_OVERRIDE;
194 
195   virtual int64_t getTotalLength() CXX11_OVERRIDE;
196 
197   virtual int64_t getFilteredTotalLength() CXX11_OVERRIDE;
198 
199   virtual int64_t getCompletedLength() CXX11_OVERRIDE;
200 
201   virtual int64_t getFilteredCompletedLength() CXX11_OVERRIDE;
202 
203   virtual void initStorage() CXX11_OVERRIDE;
204 
205   virtual void setupFileFilter() CXX11_OVERRIDE;
206 
207   virtual void clearFileFilter() CXX11_OVERRIDE;
208 
209   virtual bool downloadFinished() CXX11_OVERRIDE;
210 
211   virtual bool allDownloadFinished() CXX11_OVERRIDE;
212 
213   virtual void setBitfield(const unsigned char* bitfield,
214                            size_t bitfieldLength) CXX11_OVERRIDE;
215 
216   virtual size_t getBitfieldLength() CXX11_OVERRIDE;
217 
218   virtual const unsigned char* getBitfield() CXX11_OVERRIDE;
219 
setEndGamePieceNum(size_t num)220   virtual void setEndGamePieceNum(size_t num) CXX11_OVERRIDE
221   {
222     endGamePieceNum_ = num;
223   }
224 
getEndGamePieceNum()225   size_t getEndGamePieceNum() const { return endGamePieceNum_; }
226 
227   virtual bool isSelectiveDownloadingMode() CXX11_OVERRIDE;
228 
isEndGame()229   virtual bool isEndGame() CXX11_OVERRIDE { return endGame_; }
230 
enterEndGame()231   virtual void enterEndGame() CXX11_OVERRIDE { endGame_ = true; }
232 
233   virtual std::shared_ptr<DiskAdaptor> getDiskAdaptor() CXX11_OVERRIDE;
234 
235   virtual WrDiskCache* getWrDiskCache() CXX11_OVERRIDE;
236 
237   virtual void flushWrDiskCacheEntry(bool releaseEntries) CXX11_OVERRIDE;
238 
239   virtual int32_t getPieceLength(size_t index) CXX11_OVERRIDE;
240 
241   virtual void advertisePiece(cuid_t cuid, size_t index,
242                               Timer registeredTime) CXX11_OVERRIDE;
243 
244   virtual uint64_t
245   getAdvertisedPieceIndexes(std::vector<size_t>& indexes, cuid_t myCuid,
246                             uint64_t lastHaveIndex) CXX11_OVERRIDE;
247 
248   virtual void removeAdvertisedPiece(const Timer& expiry) CXX11_OVERRIDE;
249 
250   virtual void markAllPiecesDone() CXX11_OVERRIDE;
251 
252   virtual void markPiecesDone(int64_t length) CXX11_OVERRIDE;
253 
254   virtual void markPieceMissing(size_t index) CXX11_OVERRIDE;
255 
256   virtual void addInFlightPiece(
257       const std::vector<std::shared_ptr<Piece>>& pieces) CXX11_OVERRIDE;
258 
259   virtual size_t countInFlightPiece() CXX11_OVERRIDE;
260 
261   virtual void
262   getInFlightPieces(std::vector<std::shared_ptr<Piece>>& pieces) CXX11_OVERRIDE;
263 
264   virtual void addPieceStats(size_t index) CXX11_OVERRIDE;
265 
266   virtual void addPieceStats(const unsigned char* bitfield,
267                              size_t bitfieldLength) CXX11_OVERRIDE;
268 
269   virtual void subtractPieceStats(const unsigned char* bitfield,
270                                   size_t bitfieldLength) CXX11_OVERRIDE;
271 
272   virtual void
273   updatePieceStats(const unsigned char* newBitfield, size_t newBitfieldLength,
274                    const unsigned char* oldBitfield) CXX11_OVERRIDE;
275 
276   virtual size_t getNextUsedIndex(size_t index) CXX11_OVERRIDE;
277 
278   virtual void onDownloadIncomplete() CXX11_OVERRIDE;
279 
280   /**
281    * This method is made private for test purpose only.
282    */
283   void addUsedPiece(const std::shared_ptr<Piece>& piece);
284 
285   void setDiskWriterFactory(
286       const std::shared_ptr<DiskWriterFactory>& diskWriterFactory);
287 
getPieceStatMan()288   const std::shared_ptr<PieceStatMan>& getPieceStatMan() const
289   {
290     return pieceStatMan_;
291   }
292 
293   void setPieceSelector(std::unique_ptr<PieceSelector> pieceSelector);
294 
getPieceSelector()295   const std::unique_ptr<PieceSelector>& getPieceSelector() const
296   {
297     return pieceSelector_;
298   }
299 
300   std::unique_ptr<PieceSelector> popPieceSelector();
301 
setWrDiskCache(WrDiskCache * wrDiskCache)302   void setWrDiskCache(WrDiskCache* wrDiskCache) { wrDiskCache_ = wrDiskCache; }
303 };
304 
305 } // namespace aria2
306 
307 #endif // D_DEFAULT_PIECE_STORAGE_H
308