From 4771f323f6d5e98e68de5dd4270f79ada0d32017 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 8 Jul 2007 20:45:42 +0000 Subject: [PATCH] added invariant checks for peer_counter in block_info. added bytes_progress and block_size to block_info (to allow a more detail download progress display). Updated client_test to show download progress per block and also to have a separate color for 'multi blocks' (i.e. blocks that have been requested from more than one peer) --- examples/client_test.cpp | 16 +++++----- include/libtorrent/stat.hpp | 2 ++ include/libtorrent/torrent_handle.hpp | 8 +++++ src/torrent.cpp | 16 ++++++++++ src/torrent_handle.cpp | 42 ++++++++++++++++++++++++--- 5 files changed, 73 insertions(+), 11 deletions(-) diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 9050d5588..cf8aee571 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -1023,17 +1023,19 @@ int main(int ac, char* av[]) { int index = peer_index(i->blocks[j].peer, peers); char str[] = "+"; - bool currently_downloading = false; if (index >= 0) - { str[0] = (index < 10)?'0' + index:'A' + index - 10; - currently_downloading = peers[index].downloading_piece_index == i->piece_index - && peers[index].downloading_block_index == j; - } #ifdef ANSI_TERMINAL_COLORS - if (currently_downloading) - out << esc("33;7") << str << esc("0"); + if (i->blocks[j].bytes_progress > 0 + && i->blocks[j].state == block_info::requested) + { + if (i->blocks[j].num_peers > 1) + out << esc("1;7"); + else + out << esc("33;7"); + out << to_string(i->blocks[j].bytes_progress / float(i->blocks[j].block_size) * 10, 1) << esc("0"); + } else if (i->blocks[j].state == block_info::finished) out << esc("32;7") << str << esc("0"); else if (i->blocks[j].state == block_info::writing) out << esc("35;7") << str << esc("0"); else if (i->blocks[j].state == block_info::requested) out << str; diff --git a/include/libtorrent/stat.hpp b/include/libtorrent/stat.hpp index 8ef8da1b4..2424d5d6c 100755 --- a/include/libtorrent/stat.hpp +++ b/include/libtorrent/stat.hpp @@ -131,6 +131,8 @@ namespace libtorrent // transfers from earlier connections. void add_stat(size_type downloaded, size_type uploaded) { + assert(downloaded >= 0); + assert(uploaded >= 0); m_total_download_payload += downloaded; m_total_upload_payload += uploaded; } diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index 6fa8d1082..4bc33f85d 100755 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -210,7 +210,15 @@ namespace libtorrent { none, requested, writing, finished }; tcp::endpoint peer; + // number of bytes downloaded in this block + unsigned bytes_progress:16; + // the total number of bytes in this block + unsigned block_size:16; + // the state this block is in (see block_state_t) unsigned state:2; + // the number of peers that has requested this block + // typically 0 or 1. If > 1, this block is in + // end game mode unsigned num_peers:14; }; diff --git a/src/torrent.cpp b/src/torrent.cpp index 6ed6dd65a..b4a5efcd1 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -2330,14 +2330,30 @@ namespace libtorrent // size_type download = m_stat.total_payload_download(); // size_type done = boost::get<0>(bytes_done()); // assert(download >= done - m_initial_done); + std::map num_requests; for (const_peer_iterator i = begin(); i != end(); ++i) { peer_connection const& p = *i->second; + for (std::deque::const_iterator i = p.request_queue().begin() + , end(p.request_queue().end()); i != end; ++i) + ++num_requests[*i]; + for (std::deque::const_iterator i = p.download_queue().begin() + , end(p.download_queue().end()); i != end; ++i) + ++num_requests[*i]; torrent* associated_torrent = p.associated_torrent().lock().get(); if (associated_torrent != this) assert(false); } + if (has_picker()) + { + for (std::map::iterator i = num_requests.begin() + , end(num_requests.end()); i != end; ++i) + { + assert(m_picker->num_peers(i->first) == i->second); + } + } + if (valid_metadata()) { assert(m_abort || int(m_have_pieces.size()) == m_torrent_file.num_pieces()); diff --git a/src/torrent_handle.cpp b/src/torrent_handle.cpp index 00877aa16..10e1172fa 100755 --- a/src/torrent_handle.cpp +++ b/src/torrent_handle.cpp @@ -765,27 +765,61 @@ namespace libtorrent const std::vector& q = p.get_download_queue(); + int block_size = t->block_size(); + for (std::vector::const_iterator i = q.begin(); i != q.end(); ++i) { partial_piece_info pi; pi.piece_state = (partial_piece_info::state_t)i->state; pi.blocks_in_piece = p.blocks_in_piece(i->index); + int piece_size = t->torrent_file().piece_size(i->index); for (int j = 0; j < pi.blocks_in_piece; ++j) { + block_info& bi = pi.blocks[j]; + bi.state = i->info[j].state; + bi.block_size = j < pi.blocks_in_piece - 1 ? block_size + : piece_size - (j * block_size); + bool complete = bi.state == block_info::writing + || bi.state == block_info::finished; if (i->info[j].peer == 0) - pi.blocks[j].peer = tcp::endpoint(); + { + bi.peer = tcp::endpoint(); + bi.bytes_progress = complete ? bi.block_size : 0; + } else { policy::peer* p = static_cast(i->info[j].peer); if (p->connection) - pi.blocks[j].peer = p->connection->remote(); + { + bi.peer = p->connection->remote(); + if (bi.state == block_info::requested) + { + boost::optional pbp + = p->connection->downloading_piece_progress(); + if (pbp && pbp->piece_index == i->index && pbp->block_index == j) + { + bi.bytes_progress = pbp->bytes_downloaded; + assert(bi.bytes_progress <= bi.block_size); + } + else + { + bi.bytes_progress = 0; + } + } + else + { + bi.bytes_progress = complete ? bi.block_size : 0; + } + } else - pi.blocks[j].peer = p->ip; + { + bi.peer = p->ip; + bi.bytes_progress = complete ? bi.block_size : 0; + } } pi.blocks[j].num_peers = i->info[j].num_peers; - pi.blocks[j].state = i->info[j].state; } pi.piece_index = i->index; queue.push_back(pi);