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_PIECE_STORAGE_H
36 #define D_PIECE_STORAGE_H
37 
38 #include "common.h"
39 
40 #include <string>
41 #include <vector>
42 #include <memory>
43 
44 #include "TimerA2.h"
45 #include "Command.h"
46 
47 namespace aria2 {
48 
49 class Piece;
50 #ifdef ENABLE_BITTORRENT
51 class Peer;
52 #endif // ENABLE_BITTORRENT
53 class DiskAdaptor;
54 class WrDiskCache;
55 
56 class PieceStorage {
57 public:
58   virtual ~PieceStorage() = default;
59 
60 #ifdef ENABLE_BITTORRENT
61   /**
62    * Returns true if the peer has a piece that localhost doesn't have.
63    * Otherwise returns false.
64    */
65   virtual bool hasMissingPiece(const std::shared_ptr<Peer>& peer) = 0;
66 
67   // Stores pieces that the peer has but localhost doesn't.  Those
68   // pieces will be marked "used" status in order to prevent other
69   // command from get the same piece. But in end game mode, same
70   // piece may be got by several commands. This function stores N
71   // pieces where the sum of missing block of first N-1 pieces is
72   // less than minMissingBlocks and the sum of missing block of N
73   // pieces is greater than or equal to minMissingBlocks. If there is
74   // M missing pieces left where M < N, M pieces are stored.
75   virtual void getMissingPiece(std::vector<std::shared_ptr<Piece>>& pieces,
76                                size_t minMissingBlocks,
77                                const std::shared_ptr<Peer>& peer,
78                                cuid_t cuid) = 0;
79 
80   // Same as getMissingPiece(pieces, minMissingBlocks, peer), but the
81   // indexes in excludedIndexes are excluded.
82   virtual void getMissingPiece(std::vector<std::shared_ptr<Piece>>& pieces,
83                                size_t minMissingBlocks,
84                                const std::shared_ptr<Peer>& peer,
85                                const std::vector<size_t>& excludedIndexes,
86                                cuid_t cuid) = 0;
87 
88   // Stores pieces that the peer has but localhost doesn't.  Only
89   // pieces that declared as "fast" are stored.  Those pieces stored
90   // will be marked "used" status in order to prevent other command
91   // from get the same piece. But in end game mode, same piece may be
92   // got by several commands. This function stores N pieces where the
93   // sum of missing block of first N-1 pieces is less than
94   // minMissingBlocks and the sum of missing block of N pieces is
95   // greater than or equal to minMissingBlocks. If there is M missing
96   // pieces left where M < N, M pieces are stored.
97   virtual void getMissingFastPiece(std::vector<std::shared_ptr<Piece>>& pieces,
98                                    size_t minMissingBlocks,
99                                    const std::shared_ptr<Peer>& peer,
100                                    cuid_t cuid) = 0;
101 
102   // Same as getMissingFastPiece(pieces, minMissingBlocks, peer), but
103   // the indexes in excludedIndexes are excluded.
104   virtual void getMissingFastPiece(std::vector<std::shared_ptr<Piece>>& pieces,
105                                    size_t minMissingBlocks,
106                                    const std::shared_ptr<Peer>& peer,
107                                    const std::vector<size_t>& excludedIndexes,
108                                    cuid_t cuid) = 0;
109 
110   /**
111    * Returns a piece that the peer has but localhost doesn't.
112    * The piece will be marked "used" status in order to prevent other command
113    * from get the same piece. But in end game mode, same piece may be returned
114    * to several commands.
115    */
116   virtual std::shared_ptr<Piece>
117   getMissingPiece(const std::shared_ptr<Peer>& peer, cuid_t cuid) = 0;
118 
119   /**
120    * Same as getMissingPiece(const std::shared_ptr<Peer>& peer), but the indexes
121    * in
122    * excludedIndexes are excluded.
123    */
124   virtual std::shared_ptr<Piece>
125   getMissingPiece(const std::shared_ptr<Peer>& peer,
126                   const std::vector<size_t>& excludedIndexes, cuid_t cuid) = 0;
127 #endif // ENABLE_BITTORRENT
128 
129   // Returns true if there is at least one missing and unused piece.
130   virtual bool hasMissingUnusedPiece() = 0;
131 
132   /**
133    * Returns a missing piece if available. Otherwise returns 0;
134    * If ignoreBitfield is set, indexes of true bit are excluded.
135    */
136   virtual std::shared_ptr<Piece>
137   getMissingPiece(size_t minSplitSize, const unsigned char* ignoreBitfield,
138                   size_t length, cuid_t cuid) = 0;
139 
140   /**
141    * Returns a missing piece whose index is index.
142    * If a piece whose index is index is already acquired or currently used,
143    * then returns 0.
144    * Also returns 0 if any of missing piece is not available.
145    */
146   virtual std::shared_ptr<Piece> getMissingPiece(size_t index, cuid_t cuid) = 0;
147 
148   /**
149    * Returns the piece denoted by index.
150    * No status of the piece is changed in this method.
151    */
152   virtual std::shared_ptr<Piece> getPiece(size_t index) = 0;
153 
154   /**
155    * Marks the piece whose index is index as missing.
156    */
157   virtual void markPieceMissing(size_t index) = 0;
158 
159   /**
160    * Tells that the download of the specified piece completes.
161    */
162   virtual void completePiece(const std::shared_ptr<Piece>& piece) = 0;
163 
164   /**
165    * Tells that the download of the specified piece is canceled.
166    */
167   virtual void cancelPiece(const std::shared_ptr<Piece>& piece,
168                            cuid_t cuid) = 0;
169 
170   /**
171    * Returns true if the specified piece is already downloaded.
172    * Otherwise returns false.
173    */
174   virtual bool hasPiece(size_t index) = 0;
175 
176   virtual bool isPieceUsed(size_t index) = 0;
177 
178   virtual int64_t getTotalLength() = 0;
179 
180   virtual int64_t getFilteredTotalLength() = 0;
181 
182   virtual int64_t getCompletedLength() = 0;
183 
184   virtual int64_t getFilteredCompletedLength() = 0;
185 
186   virtual void setupFileFilter() = 0;
187 
188   virtual void clearFileFilter() = 0;
189 
190   /**
191    * Returns true if download has completed.
192    * If file filter is enabled, then returns true if those files have
193    * downloaded.
194    */
195   virtual bool downloadFinished() = 0;
196 
197   /**
198    * Returns true if all files have downloaded.
199    * The file filter is ignored.
200    */
201   virtual bool allDownloadFinished() = 0;
202 
203   /**
204    * Initializes DiskAdaptor.
205    * TODO add better documentation here.
206    */
207   virtual void initStorage() = 0;
208 
209   virtual const unsigned char* getBitfield() = 0;
210 
211   virtual void setBitfield(const unsigned char* bitfield,
212                            size_t bitfieldLength) = 0;
213 
214   virtual size_t getBitfieldLength() = 0;
215 
216   virtual bool isSelectiveDownloadingMode() = 0;
217 
218   virtual bool isEndGame() = 0;
219 
220   virtual void enterEndGame() = 0;
221 
222   // TODO We can remove this.
223   virtual void setEndGamePieceNum(size_t num) = 0;
224 
225   virtual std::shared_ptr<DiskAdaptor> getDiskAdaptor() = 0;
226 
227   virtual WrDiskCache* getWrDiskCache() = 0;
228 
229   // Flushes write disk cache for in-flight piece
230   // and optionally releases the associated cache entries.
231   virtual void flushWrDiskCacheEntry(bool releaseEntries) = 0;
232 
233   virtual int32_t getPieceLength(size_t index) = 0;
234 
235   /**
236    * Adds piece index to advertise to other commands. They send have message
237    * based on this information.
238    */
239   virtual void advertisePiece(cuid_t cuid, size_t index,
240                               Timer registerdTime) = 0;
241 
242   /**
243    * indexes is filled with piece index which is not advertised by the
244    * caller command and newer than lastHaveIndex.
245    */
246   virtual uint64_t getAdvertisedPieceIndexes(std::vector<size_t>& indexes,
247                                              cuid_t myCuid,
248                                              uint64_t lastHaveIndex) = 0;
249 
250   /**
251    * Removes have entry if its registeredTime is at least as old as
252    * expiry.
253    */
254   virtual void removeAdvertisedPiece(const Timer& expiry) = 0;
255 
256   /**
257    * Sets all bits in bitfield to 1.
258    */
259   virtual void markAllPiecesDone() = 0;
260 
261   /**
262    * Sets all bits in bitfield(0 to length) to 1.
263    */
264   virtual void markPiecesDone(int64_t length) = 0;
265 
266   virtual void
267   addInFlightPiece(const std::vector<std::shared_ptr<Piece>>& pieces) = 0;
268 
269   virtual size_t countInFlightPiece() = 0;
270 
271   virtual void
272   getInFlightPieces(std::vector<std::shared_ptr<Piece>>& pieces) = 0;
273 
274   virtual void addPieceStats(size_t index) = 0;
275 
276   virtual void addPieceStats(const unsigned char* bitfield,
277                              size_t bitfieldLength) = 0;
278 
279   virtual void subtractPieceStats(const unsigned char* bitfield,
280                                   size_t bitfieldLength) = 0;
281 
282   virtual void updatePieceStats(const unsigned char* newBitfield,
283                                 size_t newBitfieldLength,
284                                 const unsigned char* oldBitfield) = 0;
285 
286   // Returns index x where all pieces in [index+1, x-1], inclusive,
287   // are not used and not completed. If all pieces after index+1 are
288   // used or completed, returns the number of pieces.
289   virtual size_t getNextUsedIndex(size_t index) = 0;
290 
291   // Called when system detects download is not finished
292   virtual void onDownloadIncomplete() = 0;
293 };
294 
295 } // namespace aria2
296 
297 #endif // D_PIECE_STORAGE_H
298