forked from premiere/premiere-libtorrent
optimized away torrent::m_have_pieces (#62) and added some documentation on bitfield. The piece picker is now constructed with the torrent, but still freed when turned into a seed
This commit is contained in:
parent
bcc24bf831
commit
9d1e77dc88
197
docs/manual.html
197
docs/manual.html
|
@ -127,95 +127,96 @@
|
|||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#big-number" id="id109" name="id109">big_number</a></li>
|
||||
<li><a class="reference" href="#hasher" id="id110" name="id110">hasher</a></li>
|
||||
<li><a class="reference" href="#fingerprint" id="id111" name="id111">fingerprint</a></li>
|
||||
<li><a class="reference" href="#upnp-and-nat-pmp" id="id112" name="id112">UPnP and NAT-PMP</a><ul>
|
||||
<li><a class="reference" href="#add-mapping" id="id113" name="id113">add_mapping</a></li>
|
||||
<li><a class="reference" href="#delete-mapping" id="id114" name="id114">delete_mapping</a></li>
|
||||
<li><a class="reference" href="#router-model" id="id115" name="id115">router_model()</a></li>
|
||||
<li><a class="reference" href="#bitfield" id="id110" name="id110">bitfield</a></li>
|
||||
<li><a class="reference" href="#hasher" id="id111" name="id111">hasher</a></li>
|
||||
<li><a class="reference" href="#fingerprint" id="id112" name="id112">fingerprint</a></li>
|
||||
<li><a class="reference" href="#upnp-and-nat-pmp" id="id113" name="id113">UPnP and NAT-PMP</a><ul>
|
||||
<li><a class="reference" href="#add-mapping" id="id114" name="id114">add_mapping</a></li>
|
||||
<li><a class="reference" href="#delete-mapping" id="id115" name="id115">delete_mapping</a></li>
|
||||
<li><a class="reference" href="#router-model" id="id116" name="id116">router_model()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#free-functions" id="id116" name="id116">free functions</a><ul>
|
||||
<li><a class="reference" href="#identify-client" id="id117" name="id117">identify_client()</a></li>
|
||||
<li><a class="reference" href="#client-fingerprint" id="id118" name="id118">client_fingerprint()</a></li>
|
||||
<li><a class="reference" href="#bdecode-bencode" id="id119" name="id119">bdecode() bencode()</a></li>
|
||||
<li><a class="reference" href="#free-functions" id="id117" name="id117">free functions</a><ul>
|
||||
<li><a class="reference" href="#identify-client" id="id118" name="id118">identify_client()</a></li>
|
||||
<li><a class="reference" href="#client-fingerprint" id="id119" name="id119">client_fingerprint()</a></li>
|
||||
<li><a class="reference" href="#bdecode-bencode" id="id120" name="id120">bdecode() bencode()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#alerts" id="id120" name="id120">alerts</a><ul>
|
||||
<li><a class="reference" href="#external-ip-alert" id="id121" name="id121">external_ip_alert</a></li>
|
||||
<li><a class="reference" href="#listen-failed-alert" id="id122" name="id122">listen_failed_alert</a></li>
|
||||
<li><a class="reference" href="#portmap-error-alert" id="id123" name="id123">portmap_error_alert</a></li>
|
||||
<li><a class="reference" href="#portmap-alert" id="id124" name="id124">portmap_alert</a></li>
|
||||
<li><a class="reference" href="#file-error-alert" id="id125" name="id125">file_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-announce-alert" id="id126" name="id126">tracker_announce_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-alert" id="id127" name="id127">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-error-alert" id="id128" name="id128">tracker_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-reply-alert" id="id129" name="id129">tracker_reply_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-warning-alert" id="id130" name="id130">tracker_warning_alert</a></li>
|
||||
<li><a class="reference" href="#scrape-reply-alert" id="id131" name="id131">scrape_reply_alert</a></li>
|
||||
<li><a class="reference" href="#scrape-failed-alert" id="id132" name="id132">scrape_failed_alert</a></li>
|
||||
<li><a class="reference" href="#url-seed-alert" id="id133" name="id133">url_seed_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id134" name="id134">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-ban-alert" id="id135" name="id135">peer_ban_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id136" name="id136">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id137" name="id137">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id138" name="id138">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-failed-alert" id="id139" name="id139">metadata_failed_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-received-alert" id="id140" name="id140">metadata_received_alert</a></li>
|
||||
<li><a class="reference" href="#fastresume-rejected-alert" id="id141" name="id141">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference" href="#peer-blocked-alert" id="id142" name="id142">peer_blocked_alert</a></li>
|
||||
<li><a class="reference" href="#storage-moved-alert" id="id143" name="id143">storage_moved_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-paused-alert" id="id144" name="id144">torrent_paused_alert</a></li>
|
||||
<li><a class="reference" href="#save-resume-data-alert" id="id145" name="id145">save_resume_data_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id146" name="id146">dispatcher</a></li>
|
||||
<li><a class="reference" href="#alerts" id="id121" name="id121">alerts</a><ul>
|
||||
<li><a class="reference" href="#external-ip-alert" id="id122" name="id122">external_ip_alert</a></li>
|
||||
<li><a class="reference" href="#listen-failed-alert" id="id123" name="id123">listen_failed_alert</a></li>
|
||||
<li><a class="reference" href="#portmap-error-alert" id="id124" name="id124">portmap_error_alert</a></li>
|
||||
<li><a class="reference" href="#portmap-alert" id="id125" name="id125">portmap_alert</a></li>
|
||||
<li><a class="reference" href="#file-error-alert" id="id126" name="id126">file_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-announce-alert" id="id127" name="id127">tracker_announce_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-alert" id="id128" name="id128">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-error-alert" id="id129" name="id129">tracker_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-reply-alert" id="id130" name="id130">tracker_reply_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-warning-alert" id="id131" name="id131">tracker_warning_alert</a></li>
|
||||
<li><a class="reference" href="#scrape-reply-alert" id="id132" name="id132">scrape_reply_alert</a></li>
|
||||
<li><a class="reference" href="#scrape-failed-alert" id="id133" name="id133">scrape_failed_alert</a></li>
|
||||
<li><a class="reference" href="#url-seed-alert" id="id134" name="id134">url_seed_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id135" name="id135">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-ban-alert" id="id136" name="id136">peer_ban_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id137" name="id137">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id138" name="id138">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id139" name="id139">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-failed-alert" id="id140" name="id140">metadata_failed_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-received-alert" id="id141" name="id141">metadata_received_alert</a></li>
|
||||
<li><a class="reference" href="#fastresume-rejected-alert" id="id142" name="id142">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference" href="#peer-blocked-alert" id="id143" name="id143">peer_blocked_alert</a></li>
|
||||
<li><a class="reference" href="#storage-moved-alert" id="id144" name="id144">storage_moved_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-paused-alert" id="id145" name="id145">torrent_paused_alert</a></li>
|
||||
<li><a class="reference" href="#save-resume-data-alert" id="id146" name="id146">save_resume_data_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id147" name="id147">dispatcher</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#exceptions" id="id147" name="id147">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id148" name="id148">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id149" name="id149">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id150" name="id150">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id151" name="id151">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id152" name="id152">invalid_torrent_file</a></li>
|
||||
<li><a class="reference" href="#exceptions" id="id148" name="id148">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id149" name="id149">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id150" name="id150">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id151" name="id151">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id152" name="id152">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id153" name="id153">invalid_torrent_file</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#storage-interface" id="id153" name="id153">storage_interface</a><ul>
|
||||
<li><a class="reference" href="#initialize" id="id154" name="id154">initialize()</a></li>
|
||||
<li><a class="reference" href="#read" id="id155" name="id155">read()</a></li>
|
||||
<li><a class="reference" href="#write" id="id156" name="id156">write()</a></li>
|
||||
<li><a class="reference" href="#id11" id="id157" name="id157">move_storage()</a></li>
|
||||
<li><a class="reference" href="#verify-resume-data" id="id158" name="id158">verify_resume_data()</a></li>
|
||||
<li><a class="reference" href="#write-resume-data" id="id159" name="id159">write_resume_data()</a></li>
|
||||
<li><a class="reference" href="#move-slot" id="id160" name="id160">move_slot()</a></li>
|
||||
<li><a class="reference" href="#swap-slots" id="id161" name="id161">swap_slots()</a></li>
|
||||
<li><a class="reference" href="#swap-slots3" id="id162" name="id162">swap_slots3()</a></li>
|
||||
<li><a class="reference" href="#hash-for-slot" id="id163" name="id163">hash_for_slot()</a></li>
|
||||
<li><a class="reference" href="#release-files" id="id164" name="id164">release_files()</a></li>
|
||||
<li><a class="reference" href="#delete-files" id="id165" name="id165">delete_files()</a></li>
|
||||
<li><a class="reference" href="#storage-interface" id="id154" name="id154">storage_interface</a><ul>
|
||||
<li><a class="reference" href="#initialize" id="id155" name="id155">initialize()</a></li>
|
||||
<li><a class="reference" href="#read" id="id156" name="id156">read()</a></li>
|
||||
<li><a class="reference" href="#write" id="id157" name="id157">write()</a></li>
|
||||
<li><a class="reference" href="#id11" id="id158" name="id158">move_storage()</a></li>
|
||||
<li><a class="reference" href="#verify-resume-data" id="id159" name="id159">verify_resume_data()</a></li>
|
||||
<li><a class="reference" href="#write-resume-data" id="id160" name="id160">write_resume_data()</a></li>
|
||||
<li><a class="reference" href="#move-slot" id="id161" name="id161">move_slot()</a></li>
|
||||
<li><a class="reference" href="#swap-slots" id="id162" name="id162">swap_slots()</a></li>
|
||||
<li><a class="reference" href="#swap-slots3" id="id163" name="id163">swap_slots3()</a></li>
|
||||
<li><a class="reference" href="#hash-for-slot" id="id164" name="id164">hash_for_slot()</a></li>
|
||||
<li><a class="reference" href="#release-files" id="id165" name="id165">release_files()</a></li>
|
||||
<li><a class="reference" href="#delete-files" id="id166" name="id166">delete_files()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#queuing" id="id166" name="id166">queuing</a><ul>
|
||||
<li><a class="reference" href="#downloading" id="id167" name="id167">downloading</a></li>
|
||||
<li><a class="reference" href="#seeding" id="id168" name="id168">seeding</a></li>
|
||||
<li><a class="reference" href="#queuing" id="id167" name="id167">queuing</a><ul>
|
||||
<li><a class="reference" href="#downloading" id="id168" name="id168">downloading</a></li>
|
||||
<li><a class="reference" href="#seeding" id="id169" name="id169">seeding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#fast-resume" id="id169" name="id169">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id170" name="id170">file format</a></li>
|
||||
<li><a class="reference" href="#fast-resume" id="id170" name="id170">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id171" name="id171">file format</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#threads" id="id171" name="id171">threads</a></li>
|
||||
<li><a class="reference" href="#storage-allocation" id="id172" name="id172">storage allocation</a><ul>
|
||||
<li><a class="reference" href="#sparse-allocation" id="id173" name="id173">sparse allocation</a></li>
|
||||
<li><a class="reference" href="#full-allocation" id="id174" name="id174">full allocation</a></li>
|
||||
<li><a class="reference" href="#compact-allocation" id="id175" name="id175">compact allocation</a></li>
|
||||
<li><a class="reference" href="#threads" id="id172" name="id172">threads</a></li>
|
||||
<li><a class="reference" href="#storage-allocation" id="id173" name="id173">storage allocation</a><ul>
|
||||
<li><a class="reference" href="#sparse-allocation" id="id174" name="id174">sparse allocation</a></li>
|
||||
<li><a class="reference" href="#full-allocation" id="id175" name="id175">full allocation</a></li>
|
||||
<li><a class="reference" href="#compact-allocation" id="id176" name="id176">compact allocation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#extensions" id="id176" name="id176">extensions</a><ul>
|
||||
<li><a class="reference" href="#metadata-from-peers" id="id177" name="id177">metadata from peers</a></li>
|
||||
<li><a class="reference" href="#http-seeding" id="id178" name="id178">HTTP seeding</a></li>
|
||||
<li><a class="reference" href="#extensions" id="id177" name="id177">extensions</a><ul>
|
||||
<li><a class="reference" href="#metadata-from-peers" id="id178" name="id178">metadata from peers</a></li>
|
||||
<li><a class="reference" href="#http-seeding" id="id179" name="id179">HTTP seeding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#filename-checks" id="id179" name="id179">filename checks</a></li>
|
||||
<li><a class="reference" href="#acknowledgments" id="id180" name="id180">acknowledgments</a></li>
|
||||
<li><a class="reference" href="#filename-checks" id="id180" name="id180">filename checks</a></li>
|
||||
<li><a class="reference" href="#acknowledgments" id="id181" name="id181">acknowledgments</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
|
@ -2236,7 +2237,7 @@ struct torrent_status
|
|||
|
||||
int connect_candidates;
|
||||
|
||||
const std::vector<bool>* pieces;
|
||||
bitfield pieces;
|
||||
int num_pieces;
|
||||
|
||||
size_type total_done;
|
||||
|
@ -2482,7 +2483,7 @@ struct peer_info
|
|||
size_type total_download;
|
||||
size_type total_upload;
|
||||
peer_id pid;
|
||||
std::vector<bool> pieces;
|
||||
bitfield pieces;
|
||||
int upload_limit;
|
||||
int download_limit;
|
||||
|
||||
|
@ -2686,9 +2687,9 @@ the payload data.</p>
|
|||
<p><tt class="docutils literal"><span class="pre">pid</span></tt> is the peer's id as used in the bit torrent protocol. This id can be used to
|
||||
extract 'fingerprints' from the peer. Sometimes it can tell you which client the peer
|
||||
is using. See identify_client()_</p>
|
||||
<p><tt class="docutils literal"><span class="pre">pieces</span></tt> is a vector of booleans that has as many entries as there are pieces
|
||||
in the torrent. Each boolean tells you if the peer has that piece (if it's set to true)
|
||||
or if the peer miss that piece (set to false).</p>
|
||||
<p><tt class="docutils literal"><span class="pre">pieces</span></tt> is a bitfield, with one bit per piece in the torrent.
|
||||
Each bit tells you if the peer has that piece (if it's set to 1)
|
||||
or if the peer miss that piece (set to 0).</p>
|
||||
<p><tt class="docutils literal"><span class="pre">seed</span></tt> is true if this peer is a seed.</p>
|
||||
<p><tt class="docutils literal"><span class="pre">upload_limit</span></tt> is the number of bytes per second we are allowed to send to this
|
||||
peer every second. It may be -1 if there's no local limit on the peer. The global
|
||||
|
@ -3235,6 +3236,50 @@ public:
|
|||
<p>The iterators gives you access to individual bytes.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1><a id="bitfield" name="bitfield">bitfield</a></h1>
|
||||
<p>The bitfiled type stores any number of bits as a bitfield in an array.</p>
|
||||
<pre class="literal-block">
|
||||
class bitfield
|
||||
{
|
||||
bitfield();
|
||||
bitfield(int bits);
|
||||
bitfield(int bits, bool val);
|
||||
bitfield(char const* bytes, int bits);
|
||||
bitfield(bitfield const& rhs);
|
||||
|
||||
void borrow_bytes(char* bytes, int bits);
|
||||
~bitfield();
|
||||
|
||||
void assign(char const* bytes, int bits);
|
||||
|
||||
bool operator[](int index) const;
|
||||
|
||||
bool get_bit(int index) const;
|
||||
|
||||
void clear_bit(int index);
|
||||
void set_bit(int index);
|
||||
|
||||
std::size_t size() const;
|
||||
bool empty() const;
|
||||
|
||||
char const* bytes() const;
|
||||
|
||||
bitfield& operator=(bitfield const& rhs);
|
||||
|
||||
int count() const;
|
||||
|
||||
typedef const_iterator;
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
void resize(int bits, bool val);
|
||||
void set_all();
|
||||
void clear_all();
|
||||
void resize(int bits);
|
||||
};
|
||||
</pre>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h1><a id="hasher" name="hasher">hasher</a></h1>
|
||||
<p>This class creates sha1-hashes. Its declaration looks like this:</p>
|
||||
<pre class="literal-block">
|
||||
|
|
|
@ -2197,7 +2197,7 @@ It contains the following fields::
|
|||
|
||||
int connect_candidates;
|
||||
|
||||
const std::vector<bool>* pieces;
|
||||
bitfield pieces;
|
||||
int num_pieces;
|
||||
|
||||
size_type total_done;
|
||||
|
@ -2466,7 +2466,7 @@ It contains the following fields::
|
|||
size_type total_download;
|
||||
size_type total_upload;
|
||||
peer_id pid;
|
||||
std::vector<bool> pieces;
|
||||
bitfield pieces;
|
||||
int upload_limit;
|
||||
int download_limit;
|
||||
|
||||
|
@ -2642,9 +2642,9 @@ the payload data.
|
|||
extract 'fingerprints' from the peer. Sometimes it can tell you which client the peer
|
||||
is using. See identify_client()_
|
||||
|
||||
``pieces`` is a vector of booleans that has as many entries as there are pieces
|
||||
in the torrent. Each boolean tells you if the peer has that piece (if it's set to true)
|
||||
or if the peer miss that piece (set to false).
|
||||
``pieces`` is a bitfield, with one bit per piece in the torrent.
|
||||
Each bit tells you if the peer has that piece (if it's set to 1)
|
||||
or if the peer miss that piece (set to 0).
|
||||
|
||||
``seed`` is true if this peer is a seed.
|
||||
|
||||
|
@ -3291,6 +3291,53 @@ Both the ``peer_id`` and ``sha1_hash`` types are typedefs of the class
|
|||
The iterators gives you access to individual bytes.
|
||||
|
||||
|
||||
bitfield
|
||||
========
|
||||
|
||||
The bitfiled type stores any number of bits as a bitfield in an array.
|
||||
|
||||
::
|
||||
|
||||
class bitfield
|
||||
{
|
||||
bitfield();
|
||||
bitfield(int bits);
|
||||
bitfield(int bits, bool val);
|
||||
bitfield(char const* bytes, int bits);
|
||||
bitfield(bitfield const& rhs);
|
||||
|
||||
void borrow_bytes(char* bytes, int bits);
|
||||
~bitfield();
|
||||
|
||||
void assign(char const* bytes, int bits);
|
||||
|
||||
bool operator[](int index) const;
|
||||
|
||||
bool get_bit(int index) const;
|
||||
|
||||
void clear_bit(int index);
|
||||
void set_bit(int index);
|
||||
|
||||
std::size_t size() const;
|
||||
bool empty() const;
|
||||
|
||||
char const* bytes() const;
|
||||
|
||||
bitfield& operator=(bitfield const& rhs);
|
||||
|
||||
int count() const;
|
||||
|
||||
typedef const_iterator;
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
void resize(int bits, bool val);
|
||||
void set_all();
|
||||
void clear_all();
|
||||
void resize(int bits);
|
||||
};
|
||||
|
||||
|
||||
|
||||
hasher
|
||||
======
|
||||
|
|
|
@ -1317,8 +1317,8 @@ int main(int ac, char* av[])
|
|||
out.fill(' ');
|
||||
out << (s.progress*100) << "% ";
|
||||
out << progress_bar(s.progress, terminal_width - 37, progress_bar_color) << "\n";
|
||||
if (print_piece_bar && s.progress < 1.f && s.pieces)
|
||||
out << " " << piece_bar(*s.pieces, terminal_width - 5) << "\n";
|
||||
if (print_piece_bar && s.progress < 1.f)
|
||||
out << " " << piece_bar(s.pieces, terminal_width - 5) << "\n";
|
||||
out << " peers: " << esc("37") << s.num_peers << esc("0") << " (" << esc("37") << s.connect_candidates << esc("0") << ") "
|
||||
<< "seeds: " << esc("37") << s.num_seeds << esc("0") << " "
|
||||
<< "distributed copies: " << esc("37") << s.distributed_copies << esc("0")
|
||||
|
|
|
@ -209,7 +209,7 @@ namespace libtorrent
|
|||
void write_not_interested();
|
||||
void write_request(peer_request const& r);
|
||||
void write_cancel(peer_request const& r);
|
||||
void write_bitfield(bitfield const& bits);
|
||||
void write_bitfield();
|
||||
void write_have(int index);
|
||||
void write_piece(peer_request const& r, disk_buffer_holder& buffer);
|
||||
void write_handshake();
|
||||
|
|
|
@ -129,18 +129,13 @@ namespace libtorrent
|
|||
boost::int16_t requested;
|
||||
};
|
||||
|
||||
piece_picker(int blocks_per_piece
|
||||
, int total_num_blocks);
|
||||
piece_picker();
|
||||
|
||||
void get_availability(std::vector<int>& avail) const;
|
||||
|
||||
void sequential_download(bool sd);
|
||||
bool sequential_download() const { return m_sequential_download >= 0; }
|
||||
|
||||
// the vector tells which pieces we already have
|
||||
// and which we don't have.
|
||||
void init(bitfield const& pieces);
|
||||
|
||||
// increases the peer count for the given piece
|
||||
// (is used when a HAVE message is received)
|
||||
void inc_refcount(int index);
|
||||
|
@ -164,6 +159,17 @@ namespace libtorrent
|
|||
// we are not interested in this piece anymore
|
||||
// (i.e. we don't have to maintain a refcount)
|
||||
void we_have(int index);
|
||||
void we_dont_have(int index);
|
||||
|
||||
void init(int blocks_per_piece, int total_num_blocks);
|
||||
int num_pieces() const { return int(m_piece_map.size()); }
|
||||
|
||||
bool have_piece(int index) const
|
||||
{
|
||||
TORRENT_ASSERT(index >= 0);
|
||||
TORRENT_ASSERT(index < int(m_piece_map.size()));
|
||||
return m_piece_map[index].index == piece_pos::we_have_index;
|
||||
}
|
||||
|
||||
// sets the priority of a piece.
|
||||
// returns true if the priority was changed from 0 to non-0
|
||||
|
@ -276,6 +282,8 @@ namespace libtorrent
|
|||
// the number of filtered pieces we already have
|
||||
int num_have_filtered() const { return m_num_have_filtered; }
|
||||
|
||||
int num_have() const { return m_num_have; }
|
||||
|
||||
#ifndef NDEBUG
|
||||
// used in debug mode
|
||||
void verify_priority(int start, int end, int prio) const;
|
||||
|
@ -350,6 +358,7 @@ namespace libtorrent
|
|||
|
||||
bool have() const { return index == we_have_index; }
|
||||
void set_have() { index = we_have_index; TORRENT_ASSERT(have()); }
|
||||
void set_not_have() { index = 0; TORRENT_ASSERT(!have()); }
|
||||
|
||||
bool filtered() const { return piece_priority == filter_priority; }
|
||||
void filtered(bool f) { piece_priority = f ? filter_priority : 0; }
|
||||
|
@ -466,10 +475,6 @@ namespace libtorrent
|
|||
// if this is set to true, it means update_pieces()
|
||||
// has to be called before accessing m_pieces.
|
||||
mutable bool m_dirty;
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool m_files_checked_called;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline int piece_picker::blocks_in_piece(int index) const
|
||||
|
|
|
@ -378,14 +378,15 @@ namespace libtorrent
|
|||
// returns true if we have downloaded the given piece
|
||||
bool have_piece(int index) const
|
||||
{
|
||||
TORRENT_ASSERT(index >= 0 && index < (signed)m_have_pieces.size());
|
||||
return m_have_pieces[index];
|
||||
return has_picker()?m_picker->have_piece(index):true;
|
||||
}
|
||||
|
||||
bitfield const& pieces() const
|
||||
{ return m_have_pieces; }
|
||||
|
||||
int num_pieces() const { return m_num_pieces; }
|
||||
int num_pieces() const
|
||||
{
|
||||
return has_picker()
|
||||
?m_picker->num_have()
|
||||
:m_torrent_file->num_pieces();
|
||||
}
|
||||
|
||||
// when we get a have message, this is called for that piece
|
||||
void peer_has(int index)
|
||||
|
@ -393,7 +394,6 @@ namespace libtorrent
|
|||
if (m_picker.get())
|
||||
{
|
||||
TORRENT_ASSERT(!is_seed());
|
||||
TORRENT_ASSERT(index >= 0 && index < (signed)m_have_pieces.size());
|
||||
m_picker->inc_refcount(index);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
|
@ -440,7 +440,6 @@ namespace libtorrent
|
|||
if (m_picker.get())
|
||||
{
|
||||
TORRENT_ASSERT(!is_seed());
|
||||
TORRENT_ASSERT(index >= 0 && index < (signed)m_have_pieces.size());
|
||||
m_picker->dec_refcount(index);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
|
@ -507,7 +506,9 @@ namespace libtorrent
|
|||
bool is_seed() const
|
||||
{
|
||||
return valid_metadata()
|
||||
&& m_num_pieces == m_torrent_file->num_pieces();
|
||||
&& (!m_picker
|
||||
|| m_state == torrent_status::seeding
|
||||
|| m_picker->num_have() == m_picker->num_pieces());
|
||||
}
|
||||
|
||||
// this is true if we have all the pieces that we want
|
||||
|
@ -515,7 +516,7 @@ namespace libtorrent
|
|||
{
|
||||
if (is_seed()) return true;
|
||||
return valid_metadata() && m_torrent_file->num_pieces()
|
||||
- m_num_pieces - m_picker->num_filtered() == 0;
|
||||
- m_picker->num_have() - m_picker->num_filtered() == 0;
|
||||
}
|
||||
|
||||
fs::path save_path() const;
|
||||
|
@ -741,9 +742,6 @@ namespace libtorrent
|
|||
std::vector<announce_entry> m_trackers;
|
||||
// this is an index into m_trackers
|
||||
|
||||
// the bitmask that says which pieces we have
|
||||
bitfield m_have_pieces;
|
||||
|
||||
// the number of bytes that has been
|
||||
// downloaded that failed the hash-test
|
||||
size_type m_total_failed_bytes;
|
||||
|
@ -782,11 +780,6 @@ namespace libtorrent
|
|||
|
||||
float m_progress;
|
||||
|
||||
// the number of pieces we have. The same as
|
||||
// std::accumulate(m_have_pieces.begin(),
|
||||
// m_have_pieces.end(), 0)
|
||||
int m_num_pieces;
|
||||
|
||||
// the upload/download ratio that each peer
|
||||
// tries to maintain.
|
||||
// 0 is infinite
|
||||
|
|
|
@ -100,7 +100,6 @@ namespace libtorrent
|
|||
, num_incomplete(-1)
|
||||
, list_seeds(0)
|
||||
, list_peers(0)
|
||||
, pieces(0)
|
||||
, num_pieces(0)
|
||||
, total_done(0)
|
||||
, total_wanted_done(0)
|
||||
|
@ -201,7 +200,7 @@ namespace libtorrent
|
|||
// we potentially could connect to
|
||||
int connect_candidates;
|
||||
|
||||
bitfield const* pieces;
|
||||
bitfield pieces;
|
||||
|
||||
// this is the number of pieces the client has
|
||||
// downloaded. it is equal to:
|
||||
|
|
|
@ -245,7 +245,7 @@ namespace libtorrent
|
|||
{
|
||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||
TORRENT_ASSERT(t);
|
||||
write_bitfield(t->pieces());
|
||||
write_bitfield();
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (m_supports_dht_port && m_ses.m_dht)
|
||||
write_dht_port(m_ses.get_dht_settings().service_port);
|
||||
|
@ -1416,7 +1416,7 @@ namespace libtorrent
|
|||
send_buffer(msg, sizeof(msg));
|
||||
}
|
||||
|
||||
void bt_peer_connection::write_bitfield(bitfield const& bits)
|
||||
void bt_peer_connection::write_bitfield()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
|
@ -1449,14 +1449,11 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
int num_pieces = bits.size();
|
||||
int num_pieces = t->picker().num_pieces();
|
||||
int lazy_pieces[50];
|
||||
int num_lazy_pieces = 0;
|
||||
int lazy_piece = 0;
|
||||
|
||||
TORRENT_ASSERT(t->is_seed() == (bits.count()
|
||||
== num_pieces));
|
||||
|
||||
if (t->is_seed() && m_ses.settings().lazy_bitfields)
|
||||
{
|
||||
num_lazy_pieces = (std::min)(50, num_pieces / 10);
|
||||
|
@ -1470,26 +1467,6 @@ namespace libtorrent
|
|||
lazy_piece = 0;
|
||||
}
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << time_now_string() << " ==> BITFIELD ";
|
||||
|
||||
std::stringstream bitfield_string;
|
||||
for (int i = 0; i < (int)get_bitfield().size(); ++i)
|
||||
{
|
||||
if (lazy_piece < num_lazy_pieces
|
||||
&& lazy_pieces[lazy_piece] == i)
|
||||
{
|
||||
bitfield_string << "0";
|
||||
++lazy_piece;
|
||||
continue;
|
||||
}
|
||||
if (bits[i]) bitfield_string << "1";
|
||||
else bitfield_string << "0";
|
||||
}
|
||||
bitfield_string << "\n";
|
||||
(*m_logger) << bitfield_string.str();
|
||||
lazy_piece = 0;
|
||||
#endif
|
||||
const int packet_size = (num_pieces + 7) / 8 + 5;
|
||||
|
||||
buffer::interval i = allocate_send_buffer(packet_size);
|
||||
|
@ -1498,15 +1475,46 @@ namespace libtorrent
|
|||
detail::write_int32(packet_size - 4, i.begin);
|
||||
detail::write_uint8(msg_bitfield, i.begin);
|
||||
|
||||
memcpy(i.begin, bits.bytes(), packet_size - 5);
|
||||
if (t->is_seed())
|
||||
{
|
||||
memset(i.begin, 0xff, packet_size - 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(i.begin, 0, packet_size - 5);
|
||||
piece_picker const& p = t->picker();
|
||||
int mask = 0x80;
|
||||
unsigned char* byte = (unsigned char*)i.begin;
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
{
|
||||
if (p.have_piece(i)) *byte |= mask;
|
||||
mask >>= 1;
|
||||
if (mask == 0)
|
||||
{
|
||||
mask = 0x80;
|
||||
++byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int c = 0; c < num_lazy_pieces; ++c)
|
||||
i.begin[lazy_pieces[c] / 8] &= ~(0x80 >> (lazy_pieces[c] & 7));
|
||||
TORRENT_ASSERT(i.end - i.begin == (num_pieces + 7) / 8);
|
||||
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << time_now_string() << " ==> BITFIELD ";
|
||||
|
||||
std::stringstream bitfield_string;
|
||||
for (int k = 0; k < num_pieces; ++k)
|
||||
{
|
||||
if (i.begin[k / 8] & (0x80 >> (k % 8))) bitfield_string << "1";
|
||||
else bitfield_string << "0";
|
||||
}
|
||||
bitfield_string << "\n";
|
||||
(*m_logger) << bitfield_string.str();
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
m_sent_bitfield = true;
|
||||
#endif
|
||||
setup_send();
|
||||
|
||||
if (num_lazy_pieces > 0)
|
||||
{
|
||||
|
@ -1522,6 +1530,7 @@ namespace libtorrent
|
|||
|
||||
if (m_supports_fast)
|
||||
send_allowed_set();
|
||||
setup_send();
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
|
@ -2377,7 +2386,7 @@ namespace libtorrent
|
|||
// sent the handshake
|
||||
if (!is_local()) write_handshake();
|
||||
// if (t->valid_metadata())
|
||||
// write_bitfield(t->pieces());
|
||||
// write_bitfield();
|
||||
|
||||
if (is_disconnecting()) return;
|
||||
|
||||
|
@ -2511,7 +2520,7 @@ namespace libtorrent
|
|||
reset_recv_buffer(5);
|
||||
if (t->valid_metadata())
|
||||
{
|
||||
write_bitfield(t->pieces());
|
||||
write_bitfield();
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (m_supports_dht_port && m_ses.m_dht)
|
||||
write_dht_port(m_ses.get_dht_settings().service_port);
|
||||
|
|
|
@ -326,15 +326,19 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(t);
|
||||
|
||||
bool interested = false;
|
||||
bitfield const& we_have = t->pieces();
|
||||
for (int j = 0; j != (int)we_have.size(); ++j)
|
||||
if (!t->is_finished())
|
||||
{
|
||||
if (!we_have[j]
|
||||
&& t->piece_priority(j) > 0
|
||||
&& m_have_piece[j])
|
||||
piece_picker const& p = t->picker();
|
||||
int num_pieces = p.num_pieces();
|
||||
for (int j = 0; j != num_pieces; ++j)
|
||||
{
|
||||
interested = true;
|
||||
break;
|
||||
if (!p.have_piece(j)
|
||||
&& t->piece_priority(j) > 0
|
||||
&& m_have_piece[j])
|
||||
{
|
||||
interested = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
try
|
||||
|
|
|
@ -58,10 +58,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace libtorrent
|
||||
{
|
||||
|
||||
piece_picker::piece_picker(int blocks_per_piece, int total_num_blocks)
|
||||
piece_picker::piece_picker()
|
||||
: m_seeds(0)
|
||||
, m_priority_boundries(1, int(m_pieces.size()))
|
||||
, m_piece_map((total_num_blocks + blocks_per_piece-1) / blocks_per_piece)
|
||||
, m_num_filtered(0)
|
||||
, m_num_have_filtered(0)
|
||||
, m_num_have(0)
|
||||
|
@ -69,13 +68,22 @@ namespace libtorrent
|
|||
, m_dirty(false)
|
||||
{
|
||||
#ifdef TORRENT_PICKER_LOG
|
||||
std::cout << "new piece_picker" << std::endl;
|
||||
std::cerr << "new piece_picker" << std::endl;
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
check_invariant();
|
||||
#endif
|
||||
}
|
||||
|
||||
void piece_picker::init(int blocks_per_piece, int total_num_blocks)
|
||||
{
|
||||
TORRENT_ASSERT(blocks_per_piece > 0);
|
||||
TORRENT_ASSERT(total_num_blocks >= 0);
|
||||
#ifndef NDEBUG
|
||||
m_files_checked_called = false;
|
||||
#endif
|
||||
|
||||
// allocate the piece_map to cover all pieces
|
||||
// and make them invalid (as if we don't have a single piece)
|
||||
m_piece_map.resize((total_num_blocks + blocks_per_piece-1) / blocks_per_piece
|
||||
, piece_pos(0, 0));
|
||||
|
||||
// the piece index is stored in 20 bits, which limits the allowed
|
||||
// number of pieces somewhat
|
||||
|
@ -87,15 +95,6 @@ namespace libtorrent
|
|||
if (m_blocks_in_last_piece == 0) m_blocks_in_last_piece = blocks_per_piece;
|
||||
|
||||
TORRENT_ASSERT(m_blocks_in_last_piece <= m_blocks_per_piece);
|
||||
|
||||
// allocate the piece_map to cover all pieces
|
||||
// and make them invalid (as if we don't have a single piece)
|
||||
std::fill(m_piece_map.begin(), m_piece_map.end()
|
||||
, piece_pos(0, 0));
|
||||
m_num_have = 0;
|
||||
#ifndef NDEBUG
|
||||
check_invariant();
|
||||
#endif
|
||||
}
|
||||
|
||||
void piece_picker::sequential_download(bool sd)
|
||||
|
@ -122,24 +121,6 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
// pieces is a bitmask with the pieces we have
|
||||
void piece_picker::init(bitfield const& pieces)
|
||||
{
|
||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
#ifndef NDEBUG
|
||||
m_files_checked_called = true;
|
||||
#endif
|
||||
int index = 0;
|
||||
for (bitfield::const_iterator i = pieces.begin();
|
||||
i != pieces.end(); ++i, ++index)
|
||||
{
|
||||
TORRENT_ASSERT(index < pieces.size());
|
||||
piece_pos& p = m_piece_map[index];
|
||||
if (*i) we_have(index);
|
||||
else TORRENT_ASSERT(p.index == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void piece_picker::piece_info(int index, piece_picker::downloading_piece& st) const
|
||||
{
|
||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
|
@ -249,7 +230,7 @@ namespace libtorrent
|
|||
for (std::vector<int>::const_iterator i = m_priority_boundries.begin()
|
||||
, end(m_priority_boundries.end()); i != end; ++i)
|
||||
{
|
||||
std::cout << *i << " ";
|
||||
std::cerr << *i << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
int index = 0;
|
||||
|
@ -260,12 +241,12 @@ namespace libtorrent
|
|||
if (*i == -1) break;
|
||||
while (j != m_priority_boundries.end() && *j <= index)
|
||||
{
|
||||
std::cout << "| ";
|
||||
std::cerr << "| ";
|
||||
++j;
|
||||
}
|
||||
std::cout << *i << "(" << m_piece_map[*i].index << ") ";
|
||||
std::cerr << *i << "(" << m_piece_map[*i].index << ") ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cerr << std::endl;
|
||||
}
|
||||
|
||||
void piece_picker::check_invariant(const torrent* t) const
|
||||
|
@ -534,7 +515,7 @@ namespace libtorrent
|
|||
else new_index = rand() % (range_end - range_start) + range_start;
|
||||
|
||||
#ifdef TORRENT_PICKER_LOG
|
||||
std::cout << "add " << index << " (" << priority << ")" << std::endl;
|
||||
std::cerr << "add " << index << " (" << priority << ")" << std::endl;
|
||||
print_pieces();
|
||||
#endif
|
||||
m_pieces.push_back(-1);
|
||||
|
@ -554,7 +535,7 @@ namespace libtorrent
|
|||
new_index = temp;
|
||||
#ifdef TORRENT_PICKER_LOG
|
||||
print_pieces();
|
||||
std::cout << " index: " << index
|
||||
std::cerr << " index: " << index
|
||||
<< " prio: " << priority
|
||||
<< " new_index: " << new_index
|
||||
<< std::endl;
|
||||
|
@ -581,7 +562,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_sequential_download == -1);
|
||||
|
||||
#ifdef TORRENT_PICKER_LOG
|
||||
std::cout << "remove " << m_pieces[elem_index] << " (" << priority << ")" << std::endl;
|
||||
std::cerr << "remove " << m_pieces[elem_index] << " (" << priority << ")" << std::endl;
|
||||
#endif
|
||||
int next_index = elem_index;
|
||||
TORRENT_ASSERT(m_piece_map[m_pieces[elem_index]].priority(this) == -1);
|
||||
|
@ -624,7 +605,6 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(!m_dirty);
|
||||
TORRENT_ASSERT(priority >= 0);
|
||||
TORRENT_ASSERT(elem_index >= 0);
|
||||
TORRENT_ASSERT(m_files_checked_called);
|
||||
TORRENT_ASSERT(m_sequential_download == -1);
|
||||
|
||||
TORRENT_ASSERT(int(m_priority_boundries.size()) > priority);
|
||||
|
@ -648,7 +628,7 @@ namespace libtorrent
|
|||
m_priority_boundries.resize(new_priority + 1, m_pieces.size());
|
||||
|
||||
#ifdef TORRENT_PICKER_LOG
|
||||
std::cout << "update " << index << " (" << priority << "->" << new_priority << ")" << std::endl;
|
||||
std::cerr << "update " << index << " (" << priority << "->" << new_priority << ")" << std::endl;
|
||||
#endif
|
||||
if (priority > new_priority)
|
||||
{
|
||||
|
@ -772,7 +752,6 @@ namespace libtorrent
|
|||
|
||||
TORRENT_ASSERT(index >= 0);
|
||||
TORRENT_ASSERT(index < (int)m_piece_map.size());
|
||||
TORRENT_ASSERT(m_files_checked_called);
|
||||
|
||||
TORRENT_ASSERT(m_piece_map[index].downloading == 1);
|
||||
|
||||
|
@ -804,7 +783,6 @@ namespace libtorrent
|
|||
void piece_picker::inc_refcount_all()
|
||||
{
|
||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
TORRENT_ASSERT(m_files_checked_called);
|
||||
++m_seeds;
|
||||
if (m_sequential_download >= 0) return;
|
||||
if (m_seeds == 1)
|
||||
|
@ -819,7 +797,6 @@ namespace libtorrent
|
|||
void piece_picker::dec_refcount_all()
|
||||
{
|
||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
TORRENT_ASSERT(m_files_checked_called);
|
||||
|
||||
if (m_sequential_download >= 0)
|
||||
{
|
||||
|
@ -935,7 +912,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_sequential_download == -1);
|
||||
if (m_priority_boundries.empty()) m_priority_boundries.resize(1, 0);
|
||||
#ifdef TORRENT_PICKER_LOG
|
||||
std::cout << "update_pieces" << std::endl;
|
||||
std::cerr << "update_pieces" << std::endl;
|
||||
#endif
|
||||
std::fill(m_priority_boundries.begin(), m_priority_boundries.end(), 0);
|
||||
for (std::vector<piece_pos>::iterator i = m_piece_map.begin()
|
||||
|
@ -1004,6 +981,33 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
|
||||
void piece_picker::we_dont_have(int index)
|
||||
{
|
||||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
TORRENT_ASSERT(index >= 0);
|
||||
TORRENT_ASSERT(index < (int)m_piece_map.size());
|
||||
|
||||
piece_pos& p = m_piece_map[index];
|
||||
TORRENT_ASSERT(p.downloading == 0);
|
||||
|
||||
if (!p.have()) return;
|
||||
|
||||
if (m_sequential_download > index)
|
||||
m_sequential_download = index;
|
||||
|
||||
if (p.filtered())
|
||||
{
|
||||
++m_num_filtered;
|
||||
--m_num_have_filtered;
|
||||
}
|
||||
|
||||
--m_num_have;
|
||||
p.set_not_have();
|
||||
|
||||
if (m_dirty) return;
|
||||
if (!p.filtered()) add(index);
|
||||
}
|
||||
|
||||
// this is used to indicate that we succesfully have
|
||||
// downloaded a piece, and that no further attempts
|
||||
// to pick that piece should be made. The piece will
|
||||
|
@ -1167,7 +1171,6 @@ namespace libtorrent
|
|||
TORRENT_PIECE_PICKER_INVARIANT_CHECK;
|
||||
TORRENT_ASSERT(num_blocks > 0);
|
||||
TORRENT_ASSERT(pieces.size() == m_piece_map.size());
|
||||
TORRENT_ASSERT(m_files_checked_called);
|
||||
|
||||
TORRENT_ASSERT(!m_priority_boundries.empty()
|
||||
|| m_sequential_download >= 0
|
||||
|
|
130
src/torrent.cpp
130
src/torrent.cpp
|
@ -164,7 +164,7 @@ namespace libtorrent
|
|||
, m_last_dht_announce(time_now() - minutes(15))
|
||||
#endif
|
||||
, m_ses(ses)
|
||||
, m_picker(0)
|
||||
, m_picker(new piece_picker())
|
||||
, m_trackers(m_torrent_file->trackers())
|
||||
, m_total_failed_bytes(0)
|
||||
, m_total_redundant_bytes(0)
|
||||
|
@ -175,7 +175,6 @@ namespace libtorrent
|
|||
, m_settings(ses.settings())
|
||||
, m_storage_constructor(sc)
|
||||
, m_progress(0.f)
|
||||
, m_num_pieces(0)
|
||||
, m_ratio(0.f)
|
||||
, m_max_uploads((std::numeric_limits<int>::max)())
|
||||
, m_num_uploads(0)
|
||||
|
@ -240,7 +239,7 @@ namespace libtorrent
|
|||
, m_last_dht_announce(time_now() - minutes(15))
|
||||
#endif
|
||||
, m_ses(ses)
|
||||
, m_picker(0)
|
||||
, m_picker(new piece_picker())
|
||||
, m_total_failed_bytes(0)
|
||||
, m_total_redundant_bytes(0)
|
||||
, m_net_interface(net_interface.address(), 0)
|
||||
|
@ -250,7 +249,6 @@ namespace libtorrent
|
|||
, m_settings(ses.settings())
|
||||
, m_storage_constructor(sc)
|
||||
, m_progress(0.f)
|
||||
, m_num_pieces(0)
|
||||
, m_ratio(0.f)
|
||||
, m_max_uploads((std::numeric_limits<int>::max)())
|
||||
, m_num_uploads(0)
|
||||
|
@ -409,16 +407,14 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_torrent_file->num_files() > 0);
|
||||
TORRENT_ASSERT(m_torrent_file->total_size() >= 0);
|
||||
|
||||
m_have_pieces.resize(m_torrent_file->num_pieces(), false);
|
||||
// the shared_from_this() will create an intentional
|
||||
// cycle of ownership, se the hpp file for description.
|
||||
m_owning_storage = new piece_manager(shared_from_this(), m_torrent_file
|
||||
, m_save_path, m_ses.m_files, m_ses.m_disk_thread, m_storage_constructor
|
||||
, m_storage_mode);
|
||||
m_storage = m_owning_storage.get();
|
||||
m_picker.reset(new piece_picker(
|
||||
m_torrent_file->piece_length() / m_block_size
|
||||
, int((m_torrent_file->total_size()+m_block_size-1)/m_block_size)));
|
||||
m_picker->init(m_torrent_file->piece_length() / m_block_size
|
||||
, int((m_torrent_file->total_size()+m_block_size-1)/m_block_size));
|
||||
|
||||
std::vector<std::string> const& url_seeds = m_torrent_file->url_seeds();
|
||||
std::copy(url_seeds.begin(), url_seeds.end(), std::inserter(m_web_seeds
|
||||
|
@ -475,8 +471,6 @@ namespace libtorrent
|
|||
" ]\n";
|
||||
#endif
|
||||
}
|
||||
m_have_pieces.clear_all();
|
||||
m_num_pieces = 0;
|
||||
m_error = j.str;
|
||||
pause();
|
||||
return;
|
||||
|
@ -550,8 +544,6 @@ namespace libtorrent
|
|||
// there are either no files for this torrent
|
||||
// or the resume_data was accepted
|
||||
|
||||
m_num_pieces = 0;
|
||||
m_have_pieces.clear_all();
|
||||
if (!fastresume_rejected)
|
||||
{
|
||||
TORRENT_ASSERT(m_resume_data.type() == entry::dictionary_t);
|
||||
|
@ -565,8 +557,7 @@ namespace libtorrent
|
|||
for (int i = 0, end(pieces_str.size()); i < end; ++i)
|
||||
{
|
||||
if ((pieces_str[i] & 1) == 0) continue;
|
||||
m_have_pieces.set_bit(i);
|
||||
++m_num_pieces;
|
||||
m_picker->we_have(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -589,11 +580,8 @@ namespace libtorrent
|
|||
if (piece_index < 0 || piece_index >= torrent_file().num_pieces())
|
||||
continue;
|
||||
|
||||
if (m_have_pieces[piece_index])
|
||||
{
|
||||
m_have_pieces.clear_bit(piece_index);
|
||||
--m_num_pieces;
|
||||
}
|
||||
if (m_picker->have_piece(piece_index))
|
||||
m_picker->we_dont_have(piece_index);
|
||||
|
||||
entry const* bitmask_ent = i->find_key("bitmask");
|
||||
if (bitmask_ent == 0 || bitmask_ent->type() != entry::string_t) break;
|
||||
|
@ -619,13 +607,6 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
for (bitfield::const_iterator i = m_have_pieces.begin()
|
||||
, end(m_have_pieces.end()); i != end; ++i, ++index)
|
||||
{
|
||||
if (*i) m_picker->we_have(index);
|
||||
}
|
||||
}
|
||||
|
||||
files_checked();
|
||||
|
@ -663,8 +644,6 @@ namespace libtorrent
|
|||
" ]\n";
|
||||
#endif
|
||||
}
|
||||
m_have_pieces.clear_all();
|
||||
m_num_pieces = 0;
|
||||
m_error = j.str;
|
||||
pause();
|
||||
m_ses.done_checking(shared_from_this());
|
||||
|
@ -673,13 +652,9 @@ namespace libtorrent
|
|||
|
||||
m_progress = j.piece / float(torrent_file().num_pieces());
|
||||
|
||||
if (j.offset >= 0 && !m_have_pieces[j.offset])
|
||||
{
|
||||
m_have_pieces.set_bit(j.offset);
|
||||
++m_num_pieces;
|
||||
TORRENT_ASSERT(m_picker);
|
||||
TORRENT_ASSERT(m_picker);
|
||||
if (j.offset >= 0 && !m_picker->have_piece(j.offset))
|
||||
m_picker->we_have(j.offset);
|
||||
}
|
||||
|
||||
// we're not done checking yet
|
||||
// this handler will be called repeatedly until
|
||||
|
@ -984,12 +959,12 @@ namespace libtorrent
|
|||
const int last_piece = m_torrent_file->num_pieces() - 1;
|
||||
|
||||
size_type total_done
|
||||
= size_type(m_num_pieces) * m_torrent_file->piece_length();
|
||||
= size_type(num_pieces()) * m_torrent_file->piece_length();
|
||||
|
||||
// if we have the last piece, we have to correct
|
||||
// the amount we have, since the first calculation
|
||||
// assumed all pieces were of equal size
|
||||
if (m_have_pieces[last_piece])
|
||||
if (m_picker->have_piece(last_piece))
|
||||
{
|
||||
int corr = m_torrent_file->piece_size(last_piece)
|
||||
- m_torrent_file->piece_length();
|
||||
|
@ -1015,19 +990,19 @@ namespace libtorrent
|
|||
return make_tuple(m_torrent_file->total_size()
|
||||
, m_torrent_file->total_size());
|
||||
|
||||
TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered());
|
||||
size_type wanted_done = size_type(m_num_pieces - m_picker->num_have_filtered())
|
||||
TORRENT_ASSERT(num_pieces() >= m_picker->num_have_filtered());
|
||||
size_type wanted_done = size_type(num_pieces() - m_picker->num_have_filtered())
|
||||
* piece_size;
|
||||
TORRENT_ASSERT(wanted_done >= 0);
|
||||
|
||||
size_type total_done
|
||||
= size_type(m_num_pieces) * piece_size;
|
||||
TORRENT_ASSERT(m_num_pieces < m_torrent_file->num_pieces());
|
||||
= size_type(num_pieces()) * piece_size;
|
||||
TORRENT_ASSERT(num_pieces() < m_torrent_file->num_pieces());
|
||||
|
||||
// if we have the last piece, we have to correct
|
||||
// the amount we have, since the first calculation
|
||||
// assumed all pieces were of equal size
|
||||
if (m_have_pieces[last_piece])
|
||||
if (m_picker->have_piece(last_piece))
|
||||
{
|
||||
TORRENT_ASSERT(total_done >= piece_size);
|
||||
int corr = m_torrent_file->piece_size(last_piece)
|
||||
|
@ -1056,7 +1031,7 @@ namespace libtorrent
|
|||
{
|
||||
int corr = 0;
|
||||
int index = i->index;
|
||||
if (m_have_pieces[index]) continue;
|
||||
if (m_picker->have_piece(index)) continue;
|
||||
TORRENT_ASSERT(i->finished <= m_picker->blocks_in_piece(index));
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -1101,7 +1076,7 @@ namespace libtorrent
|
|||
= pc->downloading_piece_progress();
|
||||
if (p)
|
||||
{
|
||||
if (m_have_pieces[p->piece_index])
|
||||
if (m_picker->have_piece(p->piece_index))
|
||||
continue;
|
||||
|
||||
piece_block block(p->piece_index, p->block_index);
|
||||
|
@ -1138,16 +1113,16 @@ namespace libtorrent
|
|||
wanted_done += i->second;
|
||||
}
|
||||
|
||||
TORRENT_ASSERT(total_done <= m_torrent_file->total_size());
|
||||
TORRENT_ASSERT(wanted_done <= m_torrent_file->total_size());
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
if (total_done >= m_torrent_file->total_size())
|
||||
{
|
||||
// Thist happens when a piece has been downloaded completely
|
||||
// but not yet verified against the hash
|
||||
std::copy(m_have_pieces.begin(), m_have_pieces.end()
|
||||
, std::ostream_iterator<bool>(std::cerr, " "));
|
||||
std::cerr << std::endl;
|
||||
std::cerr << "num_pieces: " << m_num_pieces << std::endl;
|
||||
std::cerr << "num_pieces: " << num_pieces() << std::endl;
|
||||
|
||||
std::cerr << "unfinished:" << std::endl;
|
||||
|
||||
|
@ -1352,7 +1327,7 @@ namespace libtorrent
|
|||
m_picker->restore_piece(index);
|
||||
TORRENT_ASSERT(m_storage);
|
||||
|
||||
TORRENT_ASSERT(m_have_pieces[index] == false);
|
||||
TORRENT_ASSERT(m_picker->have_piece(index) == false);
|
||||
|
||||
#ifndef NDEBUG
|
||||
for (std::vector<void*>::iterator i = downloaders.begin()
|
||||
|
@ -1488,13 +1463,6 @@ namespace libtorrent
|
|||
std::set<void*> peers;
|
||||
std::copy(downloaders.begin(), downloaders.end(), std::inserter(peers, peers.begin()));
|
||||
|
||||
if (!m_have_pieces[index])
|
||||
m_num_pieces++;
|
||||
m_have_pieces.set_bit(index);
|
||||
|
||||
TORRENT_ASSERT(std::accumulate(m_have_pieces.begin(), m_have_pieces.end(), 0)
|
||||
== m_num_pieces);
|
||||
|
||||
m_picker->we_have(index);
|
||||
for (peer_iterator i = m_connections.begin(); i != m_connections.end(); ++i)
|
||||
(*i)->announce_piece(index);
|
||||
|
@ -1560,7 +1528,7 @@ namespace libtorrent
|
|||
|
||||
bool was_finished = is_finished();
|
||||
bool filter_updated = m_picker->set_piece_priority(index, priority);
|
||||
TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered());
|
||||
TORRENT_ASSERT(num_pieces() >= m_picker->num_have_filtered());
|
||||
if (filter_updated) update_peer_interest(was_finished);
|
||||
}
|
||||
|
||||
|
@ -1598,7 +1566,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(*i >= 0);
|
||||
TORRENT_ASSERT(*i <= 7);
|
||||
filter_updated |= m_picker->set_piece_priority(index, *i);
|
||||
TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered());
|
||||
TORRENT_ASSERT(num_pieces() >= m_picker->num_have_filtered());
|
||||
}
|
||||
if (filter_updated) update_peer_interest(was_finished);
|
||||
}
|
||||
|
@ -2444,8 +2412,16 @@ namespace libtorrent
|
|||
// write have bitmask
|
||||
entry::string_type& pieces = ret["pieces"].string();
|
||||
pieces.resize(m_torrent_file->num_pieces());
|
||||
for (int i = 0, end(pieces.size()); i < end; ++i)
|
||||
pieces[i] = m_have_pieces[i] ? 1 : 0;
|
||||
if (is_seed())
|
||||
{
|
||||
for (int i = 0, end(pieces.size()); i < end; ++i)
|
||||
pieces[i] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0, end(pieces.size()); i < end; ++i)
|
||||
pieces[i] = m_picker->have_piece(i) ? 1 : 0;
|
||||
}
|
||||
|
||||
// write local peers
|
||||
|
||||
|
@ -3119,7 +3095,6 @@ namespace libtorrent
|
|||
|
||||
if (!is_seed())
|
||||
{
|
||||
m_picker->init(m_have_pieces);
|
||||
if (m_sequential_download)
|
||||
picker().sequential_download(m_sequential_download);
|
||||
}
|
||||
|
@ -3293,16 +3268,16 @@ namespace libtorrent
|
|||
if (!m_picker->is_downloaded(i->first))
|
||||
TORRENT_ASSERT(m_picker->num_peers(i->first) == i->second);
|
||||
}
|
||||
TORRENT_ASSERT(m_num_pieces >= m_picker->num_have_filtered());
|
||||
TORRENT_ASSERT(num_pieces() >= m_picker->num_have_filtered());
|
||||
}
|
||||
|
||||
if (valid_metadata())
|
||||
{
|
||||
TORRENT_ASSERT(m_abort || int(m_have_pieces.size()) == m_torrent_file->num_pieces());
|
||||
TORRENT_ASSERT(m_abort || !m_picker || m_picker->num_pieces() == m_torrent_file->num_pieces());
|
||||
}
|
||||
else
|
||||
{
|
||||
TORRENT_ASSERT(m_abort || m_have_pieces.empty());
|
||||
TORRENT_ASSERT(m_abort || m_picker->num_pieces() == 0);
|
||||
}
|
||||
|
||||
for (policy::const_iterator i = m_policy.begin_peer()
|
||||
|
@ -3317,7 +3292,7 @@ namespace libtorrent
|
|||
if (is_seed())
|
||||
TORRENT_ASSERT(total_done == m_torrent_file->total_size());
|
||||
else
|
||||
TORRENT_ASSERT(total_done != m_torrent_file->total_size());
|
||||
TORRENT_ASSERT(total_done != m_torrent_file->total_size() || !m_files_checked);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3348,8 +3323,6 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
// This check is very expensive.
|
||||
TORRENT_ASSERT(m_num_pieces
|
||||
== std::count(m_have_pieces.begin(), m_have_pieces.end(), true));
|
||||
TORRENT_ASSERT(!valid_metadata() || m_block_size > 0);
|
||||
TORRENT_ASSERT(!valid_metadata() || (m_torrent_file->piece_length() % m_block_size) == 0);
|
||||
// if (is_seed()) TORRENT_ASSERT(m_picker.get() == 0);
|
||||
|
@ -3821,7 +3794,7 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(m_storage->refcount() > 0);
|
||||
TORRENT_ASSERT(piece_index >= 0);
|
||||
TORRENT_ASSERT(piece_index < m_torrent_file->num_pieces());
|
||||
TORRENT_ASSERT(piece_index < (int)m_have_pieces.size());
|
||||
TORRENT_ASSERT(piece_index < (int)m_picker->num_pieces());
|
||||
#ifndef NDEBUG
|
||||
if (m_picker)
|
||||
{
|
||||
|
@ -3872,6 +3845,12 @@ namespace libtorrent
|
|||
TORRENT_ASSERT(valid_metadata());
|
||||
|
||||
fp.clear();
|
||||
if (is_seed())
|
||||
{
|
||||
fp.resize(m_torrent_file->num_files(), 1.f);
|
||||
return;
|
||||
}
|
||||
|
||||
fp.resize(m_torrent_file->num_files(), 0.f);
|
||||
|
||||
for (int i = 0; i < m_torrent_file->num_files(); ++i)
|
||||
|
@ -3892,7 +3871,7 @@ namespace libtorrent
|
|||
{
|
||||
size_type bytes_step = (std::min)(size_type(m_torrent_file->piece_size(ret.piece)
|
||||
- ret.start), size);
|
||||
if (m_have_pieces[ret.piece]) done += bytes_step;
|
||||
if (m_picker->have_piece(ret.piece)) done += bytes_step;
|
||||
++ret.piece;
|
||||
ret.start = 0;
|
||||
size -= bytes_step;
|
||||
|
@ -3907,11 +3886,6 @@ namespace libtorrent
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
TORRENT_ASSERT(std::accumulate(
|
||||
m_have_pieces.begin()
|
||||
, m_have_pieces.end()
|
||||
, 0) == m_num_pieces);
|
||||
|
||||
ptime now = time_now();
|
||||
|
||||
torrent_status st;
|
||||
|
@ -4038,8 +4012,14 @@ namespace libtorrent
|
|||
else st.progress = st.total_wanted_done
|
||||
/ static_cast<float>(st.total_wanted);
|
||||
|
||||
st.pieces = &m_have_pieces;
|
||||
st.num_pieces = m_num_pieces;
|
||||
if (has_picker())
|
||||
{
|
||||
int num_pieces = m_picker->num_pieces();
|
||||
st.pieces.resize(num_pieces, false);
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
if (m_picker->have_piece(i)) st.pieces.set_bit(i);
|
||||
}
|
||||
st.num_pieces = num_pieces();
|
||||
st.num_seeds = num_seeds();
|
||||
if (m_picker.get())
|
||||
st.distributed_copies = m_picker->distributed_copies();
|
||||
|
|
|
@ -36,7 +36,8 @@ boost::shared_ptr<piece_picker> setup_picker(
|
|||
const int num_pieces = strlen(availability);
|
||||
assert(int(strlen(have_str)) == num_pieces);
|
||||
|
||||
boost::shared_ptr<piece_picker> p(new piece_picker(blocks_per_piece, num_pieces * blocks_per_piece));
|
||||
boost::shared_ptr<piece_picker> p(new piece_picker);
|
||||
p->init(blocks_per_piece, num_pieces * blocks_per_piece);
|
||||
|
||||
bitfield have = string2vec(have_str);
|
||||
|
||||
|
@ -93,11 +94,10 @@ boost::shared_ptr<piece_picker> setup_picker(
|
|||
TEST_CHECK(p->piece_priority(i) == prio);
|
||||
}
|
||||
|
||||
p->init(have);
|
||||
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
{
|
||||
if (!have[i]) continue;
|
||||
p->we_have(i);
|
||||
for (int j = 0; j < blocks_per_piece; ++j)
|
||||
TEST_CHECK(p->is_finished(piece_block(i, j)));
|
||||
}
|
||||
|
@ -152,6 +152,11 @@ void print_pick(std::vector<piece_block> const& picked)
|
|||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
void print_title(char const* name)
|
||||
{
|
||||
std::cerr << "==== " << name << " ====\n";
|
||||
}
|
||||
|
||||
int test_pick(boost::shared_ptr<piece_picker> const& p)
|
||||
{
|
||||
std::vector<piece_block> picked;
|
||||
|
@ -174,6 +179,7 @@ int test_main()
|
|||
|
||||
// make sure the block that is picked is from piece 1, since it
|
||||
// it is the piece with the lowest availability
|
||||
print_title("test pick lowest availability");
|
||||
p = setup_picker("2223333", "* * * ", "", "");
|
||||
picked.clear();
|
||||
p->pick_pieces(string2vec("*******"), picked, 1, false, 0, piece_picker::fast, true, false, empty_vector);
|
||||
|
@ -185,6 +191,7 @@ int test_main()
|
|||
|
||||
// make sure the block that is picked is from piece 5, since it
|
||||
// has the highest priority among the available pieces
|
||||
print_title("test pick highest priority");
|
||||
p = setup_picker("1111111", "* * * ", "1111122", "");
|
||||
picked.clear();
|
||||
p->pick_pieces(string2vec("****** "), picked, 1, false, 0, piece_picker::fast, true, false, empty_vector);
|
||||
|
@ -196,6 +203,7 @@ int test_main()
|
|||
|
||||
// make sure the 4 blocks are picked from the same piece if
|
||||
// whole pieces are preferred. The only whole piece is 1.
|
||||
print_title("test pick whole pieces");
|
||||
p = setup_picker("1111111", " ", "1111111", "1023460");
|
||||
picked.clear();
|
||||
p->pick_pieces(string2vec("****** "), picked, 1, 1, &peer_struct, piece_picker::fast, true, true, empty_vector);
|
||||
|
@ -209,6 +217,7 @@ int test_main()
|
|||
// test the distributed copies function. It should include ourself
|
||||
// in the availability. i.e. piece 0 has availability 2.
|
||||
// there are 2 pieces with availability 2 and 5 with availability 3
|
||||
print_title("test distributed copies");
|
||||
p = setup_picker("1233333", "* ", "", "");
|
||||
float dc = p->distributed_copies();
|
||||
TEST_CHECK(fabs(dc - (2.f + 5.f / 7.f)) < 0.01f);
|
||||
|
@ -216,6 +225,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// make sure filtered pieces are ignored
|
||||
print_title("test filtered pieces");
|
||||
p = setup_picker("1111111", " ", "0010000", "");
|
||||
picked.clear();
|
||||
p->pick_pieces(string2vec("*** ** "), picked, 1, false, 0, piece_picker::fast, true, false, empty_vector);
|
||||
|
@ -223,9 +233,23 @@ int test_main()
|
|||
TEST_CHECK(int(picked.size()) > 0);
|
||||
TEST_CHECK(picked.front().piece_index == 2);
|
||||
|
||||
// ========================================================
|
||||
|
||||
// make sure we_dont_have works
|
||||
print_title("test we_dont_have");
|
||||
p = setup_picker("1111111", "*******", "0100000", "");
|
||||
picked.clear();
|
||||
p->we_dont_have(1);
|
||||
p->we_dont_have(2);
|
||||
p->pick_pieces(string2vec("*** ** "), picked, 1, false, 0, piece_picker::fast, true, false, empty_vector);
|
||||
TEST_CHECK(verify_pick(p, picked));
|
||||
TEST_CHECK(int(picked.size()) > 0);
|
||||
TEST_CHECK(picked.front().piece_index == 1);
|
||||
|
||||
// ========================================================
|
||||
|
||||
// make sure requested blocks aren't picked
|
||||
print_title("test don't pick requested blocks");
|
||||
p = setup_picker("1234567", " ", "", "");
|
||||
picked.clear();
|
||||
p->pick_pieces(string2vec("*******"), picked, 1, false, 0, piece_picker::fast, true, false, empty_vector);
|
||||
|
@ -294,6 +318,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// test piece priorities
|
||||
print_title("test piece priorities");
|
||||
p = setup_picker("5555555", " ", "3214576", "");
|
||||
TEST_CHECK(p->num_filtered() == 0);
|
||||
TEST_CHECK(p->num_have_filtered() == 0);
|
||||
|
@ -327,6 +352,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// test restore_piece
|
||||
print_title("test restore piece");
|
||||
p = setup_picker("1234567", " ", "", "");
|
||||
p->mark_as_finished(piece_block(0,0), 0);
|
||||
p->mark_as_finished(piece_block(0,1), 0);
|
||||
|
@ -380,6 +406,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// test non-rarest-first mode
|
||||
print_title("test not rarest first");
|
||||
p = setup_picker("1234567", "* * * ", "1111122", "");
|
||||
picked.clear();
|
||||
p->pick_pieces(string2vec("****** "), picked, 5 * blocks_per_piece, false, 0, piece_picker::fast, false, false, empty_vector);
|
||||
|
@ -397,6 +424,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// test have_all and have_none
|
||||
print_title("test have_all and have_none");
|
||||
p = setup_picker("0123333", "* ", "", "");
|
||||
dc = p->distributed_copies();
|
||||
std::cout << "distributed copies: " << dc << std::endl;
|
||||
|
@ -413,6 +441,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// test inc_ref and dec_ref
|
||||
print_title("test inc_ref dec_ref");
|
||||
p = setup_picker("1233333", " * ", "", "");
|
||||
TEST_CHECK(test_pick(p) == 0);
|
||||
|
||||
|
@ -464,6 +493,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// test unverified_blocks, marking blocks and get_downloader
|
||||
print_title("test unverified blocks");
|
||||
p = setup_picker("1111111", " ", "", "0300700");
|
||||
TEST_CHECK(p->unverified_blocks() == 2 + 3);
|
||||
TEST_CHECK(p->get_downloader(piece_block(4, 0)) == 0);
|
||||
|
@ -503,6 +533,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// test prefer_whole_pieces
|
||||
print_title("test prefer whole pieces");
|
||||
p = setup_picker("1111111", " ", "", "");
|
||||
picked.clear();
|
||||
p->pick_pieces(string2vec("*******"), picked, 1, 3, 0, piece_picker::fast, true, false, empty_vector);
|
||||
|
@ -533,6 +564,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// test parole mode
|
||||
print_title("test parole mode");
|
||||
p = setup_picker("3333133", " ", "", "");
|
||||
p->mark_as_finished(piece_block(0, 0), 0);
|
||||
picked.clear();
|
||||
|
@ -561,6 +593,7 @@ int test_main()
|
|||
// ========================================================
|
||||
|
||||
// test suggested pieces
|
||||
print_title("test suggested pieces");
|
||||
p = setup_picker("1111222233334444", " ", "", "");
|
||||
int v[] = {1, 5};
|
||||
std::vector<int> suggested_pieces(v, v + 2);
|
||||
|
|
Loading…
Reference in New Issue