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)

This commit is contained in:
Arvid Norberg 2007-07-08 20:45:42 +00:00
parent e395747e35
commit 4771f323f6
5 changed files with 73 additions and 11 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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<piece_block, int> num_requests;
for (const_peer_iterator i = begin(); i != end(); ++i)
{
peer_connection const& p = *i->second;
for (std::deque<piece_block>::const_iterator i = p.request_queue().begin()
, end(p.request_queue().end()); i != end; ++i)
++num_requests[*i];
for (std::deque<piece_block>::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<piece_block, int>::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());

View File

@ -765,27 +765,61 @@ namespace libtorrent
const std::vector<piece_picker::downloading_piece>& q
= p.get_download_queue();
int block_size = t->block_size();
for (std::vector<piece_picker::downloading_piece>::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<policy::peer*>(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<piece_block_progress> 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);