improved accuracy of the file progress report to include completed blocks from incomplete pieces (but not partial blocks)

This commit is contained in:
Arvid Norberg 2008-07-09 10:45:07 +00:00
parent 9d97fc4bb9
commit d06f125513
5 changed files with 58 additions and 2 deletions

View File

@ -1412,7 +1412,7 @@ int main(int ac, char* av[])
out << progress_bar(file_progress[i], 60, "32");
else
out << progress_bar(file_progress[i], 60, "33");
out << " " << to_string(file_progress[i] * 100.f, 3) << "% "
out << " " << to_string(file_progress[i] * 100.f, 5) << "% "
<< info.file_at(i).path.leaf() << "\n";
}

View File

@ -94,6 +94,7 @@ namespace libtorrent
typedef std::vector<file_entry>::const_iterator iterator;
typedef std::vector<file_entry>::const_reverse_iterator reverse_iterator;
iterator file_at_offset(size_type offset) const;
iterator begin() const { return m_files.begin(); }
iterator end() const { return m_files.end(); }
reverse_iterator rbegin() const { return m_files.rbegin(); }

View File

@ -118,6 +118,8 @@ namespace libtorrent
int num_files() const { return m_files.num_files(); }
file_entry const& file_at(int index) const { return m_files.at(index); }
file_iterator file_at_offset(size_type offset) const
{ return m_files.file_at_offset(offset); }
std::vector<file_slice> map_block(int piece, size_type offset, int size) const
{ return m_files.map_block(piece, offset, size); }
peer_request map_file(int file, size_type offset, int size) const

View File

@ -64,6 +64,18 @@ namespace libtorrent
m_files[index].path = new_filename;
}
file_storage::iterator file_storage::file_at_offset(size_type offset) const
{
// TODO: do a binary search
std::vector<file_entry>::const_iterator i;
for (i = begin(); i != end(); ++i)
{
if (i->offset < offset && i->offset + i->size > offset)
return i;
}
return i;
}
std::vector<file_slice> file_storage::map_block(int piece, size_type offset
, int size_) const
{
@ -75,7 +87,7 @@ namespace libtorrent
TORRENT_ASSERT(start + size <= m_total_size);
// find the file iterator and file offset
// TODO: make a vector that can map piece -> file index in O(1)
// TODO: do a binary search on the file offsets
size_type file_offset = start;
std::vector<file_entry>::const_iterator file_iter;

View File

@ -3982,6 +3982,7 @@ namespace libtorrent
return;
}
TORRENT_ASSERT(has_picker());
fp.resize(m_torrent_file->num_files(), 0.f);
for (int i = 0; i < m_torrent_file->num_files(); ++i)
@ -4011,6 +4012,46 @@ namespace libtorrent
fp[i] = static_cast<float>(done) / m_torrent_file->files().at(i).size;
}
const std::vector<piece_picker::downloading_piece>& q
= m_picker->get_download_queue();
for (std::vector<piece_picker::downloading_piece>::const_iterator
i = q.begin(), end(q.end()); i != end; ++i)
{
size_type offset = size_type(i->index) * m_torrent_file->piece_length();
torrent_info::file_iterator file = m_torrent_file->file_at_offset(offset);
int file_index = file - m_torrent_file->begin_files();
int num_blocks = m_picker->blocks_in_piece(i->index);
piece_picker::block_info const* info = i->info;
for (int k = 0; k < num_blocks; ++k)
{
if (info[k].state != piece_picker::block_info::state_writing
&& info[k].state != piece_picker::block_info::state_finished)
continue;
if (offset + m_block_size > file->offset + file->size)
{
// split the block on multiple files
size_type block_size = m_block_size;
while (offset + block_size > file->offset + file->size)
{
TORRENT_ASSERT(offset < file->offset + file->size);
size_type slice = file->offset + file->size - offset;
fp[file_index] += float(slice) / file->size;
offset += slice;
block_size -= slice;
++file;
++file_index;
if (file == m_torrent_file->end_files()) break;
}
}
else
{
fp[file_index] += float(m_block_size) / file->size;
offset += m_block_size;
}
}
}
}
void torrent::set_state(torrent_status::state_t s)