📄 piece_picker.hpp
字号:
/*Copyright (c) 2003, Arvid NorbergAll rights reserved.Redistribution and use in source and binary forms, with or withoutmodification, are permitted provided that the following conditionsare met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSEARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BELIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, ORCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OFSUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESSINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER INCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THEPOSSIBILITY OF SUCH DAMAGE.*/#ifndef TORRENT_PIECE_PICKER_HPP_INCLUDED#define TORRENT_PIECE_PICKER_HPP_INCLUDED#include <algorithm>#include <vector>#include <bitset>#include <utility>#ifdef _MSC_VER#pragma warning(push, 1)#endif#include <boost/static_assert.hpp>#ifdef _MSC_VER#pragma warning(pop)#endif#include "libtorrent/peer_id.hpp"#include "libtorrent/socket.hpp"#include "libtorrent/session_settings.hpp"#include "libtorrent/config.hpp"#include "libtorrent/assert.hpp"namespace libtorrent{ class torrent; class peer_connection; struct TORRENT_EXPORT piece_block { piece_block(int p_index, int b_index) : piece_index(p_index) , block_index(b_index) {} int piece_index; int block_index; bool operator<(piece_block const& b) const { if (piece_index < b.piece_index) return true; if (piece_index == b.piece_index) return block_index < b.block_index; return false; } bool operator==(piece_block const& b) const { return piece_index == b.piece_index && block_index == b.block_index; } bool operator!=(piece_block const& b) const { return piece_index != b.piece_index || block_index != b.block_index; } }; class TORRENT_EXPORT piece_picker { public: struct block_info { block_info(): peer(0), num_peers(0), state(state_none) {} // the peer this block was requested or // downloaded from. This is a pointer to // a policy::peer object void* peer; // the number of peers that has this block in their // download or request queues unsigned num_peers:14; // the state of this block enum { state_none, state_requested, state_writing, state_finished }; unsigned state:2; }; // the peers that are downloading this piece // are considered fast peers or slow peers. // none is set if the blocks were downloaded // in a previous session enum piece_state_t { none, slow, medium, fast }; struct downloading_piece { downloading_piece(): finished(0), writing(0), requested(0) {} piece_state_t state; // the index of the piece int index; // info about each block // this is a pointer into the m_block_info // vector owned by the piece_picker block_info* info; // the number of blocks in the finished state boost::int16_t finished; // the number of blocks in the writing state boost::int16_t writing; // the number of blocks in the requested state boost::int16_t requested; }; piece_picker(int blocks_per_piece , int total_num_blocks); void get_availability(std::vector<int>& avail) const; void set_sequenced_download_threshold(int sequenced_download_threshold); // the vector tells which pieces we already have // and which we don't have. void files_checked( std::vector<bool> const& pieces , std::vector<downloading_piece> const& unfinished , std::vector<int>& verify_pieces); // increases the peer count for the given piece // (is used when a HAVE or BITFIELD message is received) void inc_refcount(int index); // decreases the peer count for the given piece // (used when a peer disconnects) void dec_refcount(int index); // these will increase and decrease the peer count // of all pieces. They are used when seeds join // or leave the swarm. void inc_refcount_all(); void dec_refcount_all(); // This indicates that we just received this piece // it means that the refcounter will indicate that // we are not interested in this piece anymore // (i.e. we don't have to maintain a refcount) void we_have(int index); // sets the priority of a piece. // returns true if the priority was changed from 0 to non-0 // or vice versa bool set_piece_priority(int index, int prio); // returns the priority for the piece at 'index' int piece_priority(int index) const; // returns the current piece priorities for all pieces void piece_priorities(std::vector<int>& pieces) const; // ========== start deprecation ============== // fills the bitmask with 1's for pieces that are filtered void filtered_pieces(std::vector<bool>& mask) const; // ========== end deprecation ============== // pieces should be the vector that represents the pieces a // client has. It returns a list of all pieces that this client // has and that are interesting to download. It returns them in // priority order. It doesn't care about the download flag. // The user of this function must lookup if any piece is // marked as being downloaded. If the user of this function // decides to download a piece, it must mark it as being downloaded // itself, by using the mark_as_downloading() member function. // THIS IS DONE BY THE peer_connection::send_request() MEMBER FUNCTION! // The last argument is the policy::peer pointer for the peer that // we'll download from. void pick_pieces(std::vector<bool> const& pieces , std::vector<piece_block>& interesting_blocks , int num_pieces, int prefer_whole_pieces , void* peer, piece_state_t speed , bool rarest_first, bool on_parole , std::vector<int> const& suggested_pieces) const; // picks blocks from each of the pieces in the piece_list // vector that is also in the piece bitmask. The blocks // are added to interesting_blocks, and busy blocks are // added to backup_blocks. num blocks is the number of // blocks to be picked. Blocks are not picked from pieces // that are being downloaded int add_blocks(std::vector<int> const& piece_list , const std::vector<bool>& pieces , std::vector<piece_block>& interesting_blocks , int num_blocks, int prefer_whole_pieces , void* peer, std::vector<int> const& ignore) const; // picks blocks only from downloading pieces int add_blocks_downloading( std::vector<bool> const& pieces , std::vector<piece_block>& interesting_blocks , std::vector<piece_block>& backup_blocks , int num_blocks, int prefer_whole_pieces , void* peer, piece_state_t speed , bool on_parole) const; // clears the peer pointer in all downloading pieces with this // peer pointer void clear_peer(void* peer); // returns true if any client is currently downloading this // piece-block, or if it's queued for downloading by some client // or if it already has been successfully downloaded bool is_requested(piece_block block) const; // returns true if the block has been downloaded bool is_downloaded(piece_block block) const; // returns true if the block has been downloaded and written to disk
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -