*** empty log message ***

This commit is contained in:
Arvid Norberg 2005-05-30 17:43:03 +00:00
parent e525456498
commit fbffae1981
11 changed files with 196 additions and 51 deletions

View File

@ -1237,6 +1237,8 @@ struct torrent_status
const std::vector<bool>* pieces;
size_type total_done;
size_type total_wanted_done;
size_type total_wanted;
int num_seeds;
float distributed_copies;
@ -1278,6 +1280,7 @@ is a pure seeder.</td>
</tr>
</tbody>
</table>
<p>When downloading, the progress is <tt class="docutils literal"><span class="pre">total_wanted_done</span></tt> / <tt class="docutils literal"><span class="pre">total_wanted</span></tt>.</p>
<p><tt class="docutils literal"><span class="pre">paused</span></tt> is set to true if the torrent is paused and false otherwise.</p>
<p><tt class="docutils literal"><span class="pre">next_announce</span></tt> is the time until the torrent will announce itself to the tracker. And
<tt class="docutils literal"><span class="pre">announce_interval</span></tt> is the time the tracker want us to wait until we announce ourself
@ -1311,6 +1314,11 @@ that are still downloading (incomplete) this torrent.</p>
<p><tt class="docutils literal"><span class="pre">total_done</span></tt> is the total number of bytes of the file(s) that we have. All
this does not necessarily has to be downloaded during this session (that's
<tt class="docutils literal"><span class="pre">total_download_payload</span></tt>).</p>
<p><tt class="docutils literal"><span class="pre">total_wanted_done</span></tt> is the number of bytes we have downloadd, only counting the
pieces that we actually want to download. i.e. excluding any pieces that we have but
are filtered as not wanted.</p>
<p><tt class="docutils literal"><span class="pre">total_wanted</span></tt> is the total number of bytes we want to download. This is also
excluding pieces that have been filtered.</p>
<p><tt class="docutils literal"><span class="pre">num_seeds</span></tt> is the number of peers that are seeding that this client is
currently connected to.</p>
<p><tt class="docutils literal"><span class="pre">distributed_copies</span></tt> is the number of distributed copies of the torrent.
@ -1375,15 +1383,16 @@ any combination of the enums above. The following table describes each flag:</p>
</colgroup>
<tbody valign="top">
<tr><td><tt class="docutils literal"><span class="pre">interesting</span></tt></td>
<td>we are interested in pieces from this peer.</td>
<td><strong>we</strong> are interested in pieces from this peer.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">choked</span></tt></td>
<td><strong>we</strong> have choked this peer.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">remote_interested</span></tt>
<tt class="docutils literal"><span class="pre">remote_choked</span></tt></td>
<td>means the same thing but that the peer is interested
in pieces from us and the peer has choked <strong>us</strong>.</td>
<tr><td><tt class="docutils literal"><span class="pre">remote_interested</span></tt></td>
<td>the peer is interested in <strong>us</strong></td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">remote_choked</span></tt></td>
<td>the peer has choked <strong>us</strong>.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">support_extensions</span></tt></td>
<td>means that this peer supports the
@ -1391,7 +1400,7 @@ in pieces from us and the peer has choked <strong>us</strong>.</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">local_connection</span></tt></td>
<td>The connection was initiated by us, the peer has a
listen port open, and that port is the same is in the
listen port open, and that port is the same as in the
<a class="reference" href="#address">address</a> of this peer. If this flag is not set, this
peer connection was opened by this peer connecting to
us.</td>

View File

@ -1159,6 +1159,7 @@ It contains the following fields::
checking_files,
connecting_to_tracker,
downloading,
finished,
seeding
};
@ -1191,6 +1192,8 @@ It contains the following fields::
const std::vector<bool>* pieces;
size_type total_done;
size_type total_wanted_done;
size_type total_wanted;
int num_seeds;
float distributed_copies;
@ -1220,13 +1223,18 @@ current task is in the ``state`` member, it will be one of the following:
| |most torrents will be in most of the time. The progress |
| |meter will tell how much of the files that has been |
| |downloaded. |
| | |
+--------------------------+----------------------------------------------------------+
|``finished`` |In this state the torrent has finished downloading but |
| |still doesn't have the entire torrent. i.e. some pieces |
| |are filtered and won't get downloaded. |
+--------------------------+----------------------------------------------------------+
|``seeding`` |In this state the torrent has finished downloading and |
| |is a pure seeder. |
| | |
+--------------------------+----------------------------------------------------------+
When downloading, the progress is ``total_wanted_done`` / ``total_wanted``.
``paused`` is set to true if the torrent is paused and false otherwise.
``next_announce`` is the time until the torrent will announce itself to the tracker. And
@ -1271,6 +1279,13 @@ that are still downloading (incomplete) this torrent.
this does not necessarily has to be downloaded during this session (that's
``total_download_payload``).
``total_wanted_done`` is the number of bytes we have downloadd, only counting the
pieces that we actually want to download. i.e. excluding any pieces that we have but
are filtered as not wanted.
``total_wanted`` is the total number of bytes we want to download. This is also
excluding pieces that have been filtered.
``num_seeds`` is the number of peers that are seeding that this client is
currently connected to.
@ -1333,18 +1348,19 @@ The ``flags`` attribute tells you in which state the peer is. It is set to
any combination of the enums above. The following table describes each flag:
+-------------------------+-------------------------------------------------------+
| ``interesting`` | we are interested in pieces from this peer. |
| ``interesting`` | **we** are interested in pieces from this peer. |
+-------------------------+-------------------------------------------------------+
| ``choked`` | **we** have choked this peer. |
+-------------------------+-------------------------------------------------------+
| ``remote_interested`` | means the same thing but that the peer is interested |
| ``remote_choked`` | in pieces from us and the peer has choked **us**. |
| ``remote_interested`` | the peer is interested in **us** |
+-------------------------+-------------------------------------------------------+
| ``remote_choked`` | the peer has choked **us**. |
+-------------------------+-------------------------------------------------------+
| ``support_extensions`` | means that this peer supports the |
| | `extension protocol`__. |
+-------------------------+-------------------------------------------------------+
| ``local_connection`` | The connection was initiated by us, the peer has a |
| | listen port open, and that port is the same is in the |
| | listen port open, and that port is the same as in the |
| | address_ of this peer. If this flag is not set, this |
| | peer connection was opened by this peer connecting to |
| | us. |

View File

@ -147,7 +147,7 @@ void clear()
#endif
std::string to_string(float v, int width, int precision = 4)
std::string to_string(float v, int width, int precision = 3)
{
std::stringstream s;
s.precision(precision);
@ -197,7 +197,7 @@ std::string add_suffix(float val)
for (int i = 0; i < num_prefix; ++i)
{
if (fabs(val) < 1000.f)
return to_string(val, i==0?7:6) + prefix[i];
return to_string(val, i==0?5:4) + prefix[i];
val /= 1000.f;
}
return to_string(val, 6) + "PB";
@ -208,8 +208,9 @@ std::string progress_bar(float progress, int width)
std::vector<char> bar;
bar.reserve(width);
std::fill_n(std::back_inserter(bar), progress * width, '#');
std::fill_n(std::back_inserter(bar), width - (progress * width), '-');
int progress_chars = progress * width + .5f;
std::fill_n(std::back_inserter(bar), progress_chars, '#');
std::fill_n(std::back_inserter(bar), width - progress_chars, '-');
return std::string(bar.begin(), bar.end());
}
@ -217,7 +218,7 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
{
using namespace libtorrent;
out << " down up q r flags client block\n";
out << " down up q r flags block progress client \n";
for (std::vector<peer_info>::const_iterator i = peers.begin();
i != peers.end(); ++i)
@ -238,17 +239,20 @@ void print_peer_info(std::ostream& out, std::vector<libtorrent::peer_info> const
<< static_cast<const char*>((i->flags & peer_info::remote_interested)?"i":"_")
<< static_cast<const char*>((i->flags & peer_info::remote_choked)?"c":"_")
<< static_cast<const char*>((i->flags & peer_info::supports_extensions)?"e":"_")
<< static_cast<const char*>((i->flags & peer_info::local_connection)?"l":"r") << " "
<< identify_client(i->id);
<< static_cast<const char*>((i->flags & peer_info::local_connection)?"l":"r") << " ";
if (i->downloading_piece_index >= 0)
{
out << " " << progress_bar(
out << progress_bar(
i->downloading_progress / static_cast<float>(i->downloading_total)
, 15);
}
else
{
out << progress_bar(0.f, 15);
}
out << "\n";
out << " " << identify_client(i->id) << "\n";
}
}
@ -328,6 +332,12 @@ int main(int argc, char* argv[])
handles.back().set_max_connections(100);
handles.back().set_max_uploads(-1);
handles.back().set_ratio(1.02f);
/*
for (int i = 0; i < t.num_pieces(); ++i)
{
handles.back().filter_piece(i, i % 2 == 0);
}
*/
}
catch (std::exception& e)
{
@ -446,6 +456,10 @@ int main(int argc, char* argv[])
--i;
continue;
}
out << "name: ";
if (i->has_metadata()) out << i->get_torrent_info().name();
else out << "-";
out << "\n";
torrent_status s = i->status();
switch(s.state)
@ -465,6 +479,9 @@ int main(int argc, char* argv[])
case torrent_status::downloading:
out << "downloading ";
break;
case torrent_status::finished:
out << "finished ";
break;
case torrent_status::seeding:
out << "seeding ";
break;
@ -483,9 +500,9 @@ int main(int argc, char* argv[])
out << "peers: " << s.num_peers << " "
<< "seeds: " << s.num_seeds << " "
<< "distributed copies: " << s.distributed_copies << "\n";
out << "download:" << add_suffix(s.download_rate) << "/s "
out << "download: " << add_suffix(s.download_rate) << "/s "
<< "(" << add_suffix(s.total_download) << ") "
<< "upload:" << add_suffix(s.upload_rate) << "/s "
<< "upload: " << add_suffix(s.upload_rate) << "/s "
<< "(" << add_suffix(s.total_upload) << ") "
<< "ratio: " << ratio(s.total_payload_download, s.total_payload_upload) << "\n";
out << "info-hash: " << i->info_hash() << "\n";

View File

@ -199,6 +199,11 @@ namespace libtorrent
boost::optional<address> get_downloader(piece_block block) const;
// the number of filtered pieces we don't have
int num_filtered() const { return m_num_filtered; }
// the number of filtered pieces we already have
int num_have_filtered() const { return m_num_have_filtered; }
#ifndef NDEBUG
// used in debug mode
void integrity_check(const torrent* t = 0) const;
@ -298,6 +303,14 @@ namespace libtorrent
int m_blocks_per_piece;
int m_blocks_in_last_piece;
// the number of filtered pieces that we don't already
// have. total_number_of_pieces - number_of_pieces_we_have
// - num_filtered is supposed to the number of pieces
// we still want to download
int m_num_filtered;
// the number of pieces we have that also are filtered
int m_num_have_filtered;
};
inline int piece_picker::blocks_in_piece(int index) const

View File

@ -46,6 +46,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/limits.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/tuple/tuple.hpp>
#ifdef _MSC_VER
#pragma warning(pop)
@ -135,7 +136,7 @@ namespace libtorrent
stat statistics() const { return m_stat; }
size_type bytes_left() const;
size_type bytes_done() const;
boost::tuple<size_type, size_type> bytes_done() const;
void pause();
void resume();

View File

@ -89,6 +89,8 @@ namespace libtorrent
, num_incomplete(-1)
, pieces(0)
, total_done(0)
, total_wanted_done(0)
, total_wanted(0)
, num_seeds(0)
, distributed_copies(0.f)
, block_size(0)
@ -101,6 +103,7 @@ namespace libtorrent
connecting_to_tracker,
downloading_metadata,
downloading,
finished,
seeding
};
@ -150,8 +153,20 @@ namespace libtorrent
const std::vector<bool>* pieces;
// the number of bytes of the file we have
// including pieces that may have been filtered
// after we downloaded them
size_type total_done;
// the number of bytes we have of those that we
// want. i.e. not counting bytes from pieces that
// are filtered as not wanted.
size_type total_wanted_done;
// the total number of bytes we want to download
// this may be smaller than the total torrent size
// in case any pieces are filtered as not wanted
size_type total_wanted;
// the number of peers this torrent is connected to
// that are seeding.
int num_seeds;

View File

@ -268,13 +268,12 @@ namespace libtorrent
// peer has, in a shuffled order
bool interesting = false;
for (std::vector<int>::iterator i = piece_list.begin();
i != piece_list.end();
++i)
i != piece_list.end(); ++i)
{
int index = *i;
m_torrent->peer_has(index);
if (!m_torrent->have_piece(index)
&& m_torrent->picker().is_filtered(index))
&& !m_torrent->picker().is_filtered(index))
interesting = true;
}

View File

@ -59,6 +59,8 @@ namespace libtorrent
, m_downloading_piece_info(2)
, m_filtered_piece_info(2)
, m_piece_map((total_num_blocks + blocks_per_piece-1) / blocks_per_piece)
, m_num_filtered(0)
, m_num_have_filtered(0)
{
assert(blocks_per_piece > 0);
assert(total_num_blocks > 0);
@ -80,6 +82,7 @@ namespace libtorrent
std::fill(m_piece_map.begin(), m_piece_map.end(), piece_pos(0, piece_pos::we_have_index));
}
// pieces is a bitmask with the pieces we have
void piece_picker::files_checked(
const std::vector<bool>& pieces
, const std::vector<downloading_piece>& unfinished)
@ -93,6 +96,11 @@ namespace libtorrent
{
if (*i) continue;
int index = static_cast<int>(i - pieces.begin());
if (m_piece_map[index].filtered)
{
++m_num_filtered;
--m_num_have_filtered;
}
piece_list.push_back(index);
}
@ -149,11 +157,19 @@ namespace libtorrent
if (t != 0)
assert((int)m_piece_map.size() == t->torrent_file().num_pieces());
int num_filtered = 0;
int num_have_filtered = 0;
for (std::vector<piece_pos>::const_iterator i = m_piece_map.begin();
i != m_piece_map.end(); ++i)
{
int index = static_cast<int>(i - m_piece_map.begin());
if (i->filtered)
{
if (i->index != piece_pos::we_have_index)
++num_filtered;
else
++num_have_filtered;
}
if (t != 0)
{
int actual_peer_count = 0;
@ -241,7 +257,8 @@ namespace libtorrent
assert(down == m_downloads.end());
}
}
assert(num_filtered == m_num_filtered);
assert(num_have_filtered == m_num_have_filtered);
}
#endif
@ -452,6 +469,11 @@ namespace libtorrent
assert(info_index != piece_pos::we_have_index);
piece_pos& p = m_piece_map[index];
if (p.filtered)
{
--m_num_filtered;
++m_num_have_filtered;
}
remove(p.downloading, p.filtered, peer_count, info_index);
#ifndef NDEBUG
integrity_check();
@ -472,7 +494,14 @@ namespace libtorrent
if (p.filtered == 1) return;
p.filtered = 1;
if (p.index != piece_pos::we_have_index)
{
++m_num_filtered;
move(p.downloading, false, p.peer_count, p.index);
}
else
{
++m_num_have_filtered;
}
#ifndef NDEBUG
integrity_check();
@ -493,7 +522,16 @@ namespace libtorrent
if (p.filtered == 0) return;
p.filtered = 0;
if (p.index != piece_pos::we_have_index)
{
--m_num_filtered;
assert(m_num_filtered >= 0);
move(p.downloading, true, p.peer_count, p.index);
}
else
{
--m_num_have_filtered;
assert(m_num_have_filtered >= 0);
}
#ifndef NDEBUG
integrity_check();

View File

@ -188,9 +188,7 @@ namespace libtorrent { namespace detail
detail::piece_checker_data* checker_impl::find_torrent(sha1_hash const& info_hash)
{
for (std::deque<piece_checker_data>::iterator i
= m_torrents.begin();
i != m_torrents.end();
++i)
= m_torrents.begin(); i != m_torrents.end(); ++i)
{
if (i->info_hash == info_hash) return &(*i);
}
@ -200,9 +198,7 @@ namespace libtorrent { namespace detail
void checker_impl::remove_torrent(sha1_hash const& info_hash)
{
for (std::deque<piece_checker_data>::iterator i
= m_torrents.begin();
i != m_torrents.end();
++i)
= m_torrents.begin(); i != m_torrents.end(); ++i)
{
if (i->info_hash == info_hash)
{

View File

@ -364,16 +364,22 @@ namespace libtorrent
// if we don't have the metadata yet, we
// cannot tell how big the torrent is.
if (!valid_metadata()) return -1;
return m_torrent_file.total_size() - bytes_done();
return m_torrent_file.total_size() - boost::get<0>(bytes_done());
}
size_type torrent::bytes_done() const
// the first value is the total number of bytes downloaded
// the second value is the number of bytes of those that haven't
// been filtered as not wanted we have downloaded
boost::tuple<size_type, size_type> torrent::bytes_done() const
{
if (!valid_metadata()) return 0;
assert(m_picker.get());
const int last_piece = m_torrent_file.num_pieces()-1;
const int last_piece = m_torrent_file.num_pieces() - 1;
size_type wanted_done = (m_num_pieces - m_picker->num_have_filtered())
* m_torrent_file.piece_length();
size_type total_done
= m_num_pieces * m_torrent_file.piece_length();
@ -382,25 +388,28 @@ namespace libtorrent
// assumed all pieces were of equal size
if (m_have_pieces[last_piece])
{
total_done -= m_torrent_file.piece_length();
total_done += m_torrent_file.piece_size(last_piece);
int corr = m_torrent_file.piece_size(last_piece)
- m_torrent_file.piece_length();
total_done += corr;
if (!m_picker->is_filtered(last_piece))
wanted_done += corr;
}
const std::vector<piece_picker::downloading_piece>& dl_queue
= m_picker->get_download_queue();
const int blocks_per_piece = static_cast<int>(m_torrent_file.piece_length() / m_block_size);
const int blocks_per_piece = static_cast<int>(
m_torrent_file.piece_length() / m_block_size);
for (std::vector<piece_picker::downloading_piece>::const_iterator i =
dl_queue.begin();
i != dl_queue.end();
++i)
dl_queue.begin(); i != dl_queue.end(); ++i)
{
int corr = 0;
assert(!m_have_pieces[i->index]);
for (int j = 0; j < blocks_per_piece; ++j)
{
total_done += (i->finished_blocks[j]) * m_block_size;
corr += (i->finished_blocks[j]) * m_block_size;
}
// correction if this was the last piece
@ -408,9 +417,12 @@ namespace libtorrent
if (i->index == last_piece
&& i->finished_blocks[m_picker->blocks_in_last_piece()-1])
{
total_done -= m_block_size;
total_done += m_torrent_file.piece_size(last_piece) % m_block_size;
corr -= m_block_size;
corr += m_torrent_file.piece_size(last_piece) % m_block_size;
}
total_done += corr;
if (!m_picker->is_filtered(i->index))
wanted_done += corr;
}
std::map<piece_block, int> downloading_piece;
@ -443,8 +455,12 @@ namespace libtorrent
}
for (std::map<piece_block, int>::iterator i = downloading_piece.begin();
i != downloading_piece.end(); ++i)
{
total_done += i->second;
return total_done;
if (!m_picker->is_filtered(i->first.piece_index))
wanted_done += i->second;
}
return boost::make_tuple(total_done, wanted_done);
}
void torrent::piece_failed(int index)
@ -562,10 +578,14 @@ namespace libtorrent
assert(index >= 0);
assert(index < m_torrent_file.num_pieces());
// TODO: update peer's interesting-bit
if (filter) m_picker->mark_as_filtered(index);
else m_picker->mark_as_unfiltered(index);
}
// TODO: add a function to set the filter with one call
bool torrent::is_piece_filtered(int index) const
{
// this call is only valid on torrents with metadata
@ -1050,7 +1070,7 @@ namespace libtorrent
st.num_complete = m_complete;
st.num_incomplete = m_incomplete;
st.paused = m_paused;
st.total_done = bytes_done();
boost::tie(st.total_done, st.total_wanted_done) = bytes_done();
// payload transfer
st.total_payload_download = m_stat.total_payload_download();
@ -1102,8 +1122,27 @@ namespace libtorrent
// fill in status that depends on metadata
st.progress = st.total_done
/ static_cast<float>(m_torrent_file.total_size());
st.total_wanted = m_torrent_file.total_size();
if (m_picker.get() && (m_picker->num_filtered() > 0
|| m_picker->num_have_filtered() > 0))
{
int filtered_pieces = m_picker->num_filtered()
+ m_picker->num_have_filtered();
int last_piece_index = m_torrent_file.num_pieces() - 1;
if (m_picker->is_filtered(last_piece_index))
{
st.total_wanted -= m_torrent_file.piece_size(last_piece_index);
--filtered_pieces;
}
st.total_wanted -= filtered_pieces * m_torrent_file.piece_length();
}
assert(st.total_wanted >= st.total_wanted_done);
st.progress = st.total_wanted_done
/ static_cast<float>(st.total_wanted);
st.pieces = &m_have_pieces;
@ -1111,6 +1150,8 @@ namespace libtorrent
st.state = torrent_status::connecting_to_tracker;
else if (m_num_pieces == (int)m_have_pieces.size())
st.state = torrent_status::seeding;
else if (st.total_wanted_done == st.total_wanted)
st.state = torrent_status::finished;
else
st.state = torrent_status::downloading;

View File

@ -78,7 +78,7 @@ namespace libtorrent
{
void throw_invalid_handle()
{
throw_invalid_handle();
throw invalid_handle();
}
template<class Ret, class F>