diff --git a/docs/manual.rst b/docs/manual.rst index 294bc67b9..17ef9f7b0 100755 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -863,6 +863,10 @@ write_resume_data() is suitable for being bencoded. For more information about how fast-resume works, see `fast resume`_. It may throw invalid_handle_ if the torrent handle is invalid. +Note that by the time this function returns, the resume data may already be invalid if the torrent +is still downloading! The recommended practice is to first pause the torrent, then generate the +fast resume data, and then close it down. + status() -------- @@ -987,9 +991,14 @@ It contains the following fields:: size_type total_payload_download; size_type total_payload_upload; + size_type total_failed_bytes; + float download_rate; float upload_rate; + float download_payload_rate; + float upload_payload_rate; + int num_peers; const std::vector* pieces; @@ -1041,17 +1050,27 @@ uploaded to all peers, accumulated, *this session* only. send and received this session, but only the actual oayload data (i.e the interesting data), these counters ignore any protocol overhead. +``total_failed_bytes`` is the number of bytes that has been downloaded and that +has failed the piece hash test. In other words, this is just how much crap that +has been downloaded. + ``pieces`` is the bitmask that represents which pieces we have (set to true) and the pieces we don't have. It's a pointer and may be set to 0 if the torrent isn't downloading or seeding. ``download_rate`` and ``upload_rate`` are the total rates for all peers for this torrent. These will usually have better precision than summing the rates from -all peers. The rates are given as the number of bytes per second. +all peers. The rates are given as the number of bytes per second. The +``download_payload_rate`` and ``upload_payload_rate`` respectively is the +total transfer rate of payload only, not counting protocol chatter. This might +be slightly smaller than the other rates, but if projected over a long time +(e.g. when calculating ETA:s) the difference may be noticable. ``num_peers`` is the number of peers this torrent currently is connected to. -``total_done`` is the total number of bytes of the file(s) that we have. +``total_done`` 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 +``total_download_payload``). diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index fb0104826..edc6381f5 100755 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -229,6 +229,9 @@ namespace libtorrent int m_upload_rate; int m_download_rate; + // statistics gathered from all torrents. + stat m_stat; + // handles delayed alerts alert_manager m_alerts; @@ -253,6 +256,25 @@ namespace libtorrent struct http_settings; + struct session_status + { + bool has_incoming_connections; + + float upload_rate; + float download_rate; + + float payload_upload_rate; + float payload_download_rate; + + size_type total_download; + size_type total_upload; + + size_type total_payload_download; + size_type total_payload_upload; + + int num_peers; + }; + class session: public boost::noncopyable, detail::eh_initializer { public: @@ -271,6 +293,8 @@ namespace libtorrent , const boost::filesystem::path& save_path , const entry& resume_data = entry()); + session_status status() const; + bool is_listening() const; // if the listen port failed in some way diff --git a/include/libtorrent/stat.hpp b/include/libtorrent/stat.hpp index 6cc9eac66..d874d3192 100755 --- a/include/libtorrent/stat.hpp +++ b/include/libtorrent/stat.hpp @@ -58,13 +58,15 @@ namespace libtorrent , m_total_upload_payload(0) , m_total_download_protocol(0) , m_total_upload_protocol(0) - , m_peak_downloaded_per_second(0) - , m_peak_uploaded_per_second(0) - , m_mean_download_per_second(0) - , m_mean_upload_per_second(0) + , m_mean_download_rate(0) + , m_mean_upload_rate(0) + , m_mean_download_payload_rate(0) + , m_mean_upload_payload_rate(0) { - std::fill(m_download_per_second_history, m_download_per_second_history+history, 0); - std::fill(m_upload_per_second_history, m_upload_per_second_history+history, 0); + std::fill(m_download_rate_history, m_download_rate_history+history, 0); + std::fill(m_upload_rate_history, m_upload_rate_history+history, 0); + std::fill(m_download_payload_rate_history, m_download_payload_rate_history+history, 0); + std::fill(m_upload_payload_rate_history, m_upload_payload_rate_history+history, 0); } void operator+=(const stat& s) @@ -111,12 +113,11 @@ namespace libtorrent // should be called once every second void second_tick(); - // only counts the payload data! - float upload_rate() const { return m_mean_upload_per_second; } - float download_rate() const { return m_mean_download_per_second; } + float upload_rate() const { return m_mean_upload_rate; } + float download_rate() const { return m_mean_download_rate; } - float down_peak() const { return m_peak_downloaded_per_second; } - float up_peak() const { return m_peak_uploaded_per_second; } + float upload_payload_rate() const { return m_mean_upload_payload_rate; } + float download_payload_rate() const { return m_mean_download_payload_rate; } size_type total_payload_upload() const { return m_total_upload_payload; } size_type total_payload_download() const { return m_total_download_payload; } @@ -138,10 +139,10 @@ namespace libtorrent #ifndef NDEBUG void check_invariant() const { - assert(m_mean_upload_per_second >= 0); - assert(m_mean_download_per_second >= 0); - assert(m_peak_uploaded_per_second >= 0); - assert(m_peak_downloaded_per_second >= 0); + assert(m_mean_upload_rate >= 0); + assert(m_mean_download_rate >= 0); + assert(m_mean_upload_payload_rate >= 0); + assert(m_mean_download_payload_rate >= 0); assert(m_total_upload_payload >= 0); assert(m_total_download_payload >= 0); assert(m_total_upload_protocol >= 0); @@ -150,8 +151,11 @@ namespace libtorrent #endif // history of download/upload speeds a few seconds back - int m_download_per_second_history[history]; - int m_upload_per_second_history[history]; + int m_download_rate_history[history]; + int m_upload_rate_history[history]; + + int m_download_payload_rate_history[history]; + int m_upload_payload_rate_history[history]; // the accumulators we are adding the downloads/upploads // to this second. This only counts the actual payload @@ -175,13 +179,12 @@ namespace libtorrent size_type m_total_download_protocol; size_type m_total_upload_protocol; - // peak mean download/upload rates - float m_peak_downloaded_per_second; - float m_peak_uploaded_per_second; - // current mean download/upload rates - float m_mean_download_per_second; - float m_mean_upload_per_second; + float m_mean_download_rate; + float m_mean_upload_rate; + + float m_mean_download_payload_rate; + float m_mean_upload_payload_rate; }; } diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index 94bfd671f..24816495b 100755 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -321,7 +321,6 @@ namespace libtorrent void parse_response(const entry& e, std::vector& peer_list); torrent_info m_torrent_file; - piece_manager m_storage; // the time of next tracker request @@ -385,6 +384,10 @@ namespace libtorrent // 0 is infinite float m_ratio; + // the number of bytes that has been + // downloaded that failed the hash-test + size_type m_total_failed_bytes; + std::string m_username; std::string m_password; diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index 414db2ce3..185b806a7 100755 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -113,11 +113,20 @@ namespace libtorrent size_type total_payload_download; size_type total_payload_upload; + // the amount of payload bytes that + // has failed their hash test + size_type total_failed_bytes; + // current transfer rate // payload plus protocol float download_rate; float upload_rate; + // the rate of payload that is + // sent and received + float download_payload_rate; + float upload_payload_rate; + // the number of peers this torrent // is connected to. int num_peers; diff --git a/src/policy.cpp b/src/policy.cpp index d5f5e6ef7..42bb68929 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -172,7 +172,7 @@ namespace const int queue_size = (int)i->second->download_queue().size(); const float weight = queue_size == 0 ? std::numeric_limits::max() - : i->second->statistics().down_peak() / queue_size; + : i->second->statistics().download_payload_rate() / queue_size; if (weight < min_weight && std::find_first_of( @@ -219,7 +219,7 @@ namespace const int queue_size = (int)c.download_queue().size(); const float weight = queue_size == 0 ? std::numeric_limits::max() - : c.statistics().down_peak() / queue_size; + : c.statistics().download_payload_rate() / queue_size; if (weight <= min_weight) break; } diff --git a/src/session.cpp b/src/session.cpp index 4bbf5c0de..0130359f3 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -637,10 +637,15 @@ namespace libtorrent { namespace detail // tick() will set the used upload quota i->second->second_tick(); + + // accumulate the statistics from all torrents + m_stat += i->second->statistics(); ++i; } purge_connections(); + m_stat.second_tick(); + // distribute the maximum upload rate among the torrents allocate_resources(m_upload_rate == -1 @@ -905,6 +910,13 @@ namespace libtorrent return m_impl.m_listen_interface.port; } + session_status session::status() const + { + session_status s; +// TODO: implement + return s; + } + bool session::is_listening() const { boost::mutex::scoped_lock l(m_impl.m_mutex); diff --git a/src/stat.cpp b/src/stat.cpp index 7c51388af..83f9de655 100755 --- a/src/stat.cpp +++ b/src/stat.cpp @@ -47,29 +47,39 @@ void libtorrent::stat::second_tick() { INVARIANT_CHECK; - for(int i=history-2;i>=0;--i) + for (int i = history - 2; i >= 0; --i) { - m_download_per_second_history[i+1]=m_download_per_second_history[i]; - m_upload_per_second_history[i+1]=m_upload_per_second_history[i]; + m_download_rate_history[i + 1] = m_download_rate_history[i]; + m_upload_rate_history[i + 1] = m_upload_rate_history[i]; + m_download_payload_rate_history[i + 1] = m_download_payload_rate_history[i]; + m_upload_payload_rate_history[i + 1] = m_upload_payload_rate_history[i]; } - m_download_per_second_history[0] = m_downloaded_payload + m_downloaded_protocol; - m_upload_per_second_history[0] = m_uploaded_payload + m_uploaded_protocol; + m_download_rate_history[0] = m_downloaded_payload + m_downloaded_protocol; + m_upload_rate_history[0] = m_uploaded_payload + m_uploaded_protocol; + m_download_payload_rate_history[0] = m_downloaded_payload; + m_upload_payload_rate_history[0] = m_uploaded_payload; + m_downloaded_payload = 0; m_uploaded_payload = 0; m_downloaded_protocol = 0; m_uploaded_protocol = 0; - m_mean_download_per_second - = (float)std::accumulate(m_download_per_second_history, - m_download_per_second_history+history, 0) / history; + m_mean_download_rate = 0; + m_mean_upload_rate = 0; + m_mean_download_payload_rate = 0; + m_mean_upload_payload_rate = 0; - m_mean_upload_per_second - = (float)std::accumulate(m_upload_per_second_history, - m_upload_per_second_history+history, 0) / history; + for (int i = 0; i < history; ++i) + { + m_mean_download_rate += m_download_rate_history[i]; + m_mean_upload_rate += m_upload_rate_history[i]; + m_mean_download_payload_rate += m_download_payload_rate_history[i]; + m_mean_upload_payload_rate += m_download_payload_rate_history[i]; + } - if (m_mean_download_per_second > m_peak_downloaded_per_second) - m_peak_downloaded_per_second = m_mean_download_per_second; - if (m_mean_upload_per_second > m_peak_uploaded_per_second) - m_peak_uploaded_per_second = m_mean_upload_per_second; + m_mean_download_rate /= history; + m_mean_upload_rate /= history; + m_mean_download_payload_rate /= history; + m_mean_upload_payload_rate /= history; } diff --git a/src/torrent.cpp b/src/torrent.cpp index 3e834b4a1..b510352ce 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -169,6 +169,7 @@ namespace libtorrent , m_num_pieces(0) , m_got_tracker_response(false) , m_ratio(0.f) + , m_total_failed_bytes(0) , m_net_interface(net_interface.ip(), address::any_port) , m_upload_bandwidth_limit(std::numeric_limits::max()) , m_download_bandwidth_limit(std::numeric_limits::max()) @@ -343,6 +344,9 @@ namespace libtorrent s << "hash for piece " << index << " failed"; m_ses.m_alerts.post_alert(hash_failed_alert(get_handle(), index, s.str())); } + // increase the total amount of failed bytes + m_total_failed_bytes += m_torrent_file.piece_size(index); + std::vector
downloaders; m_picker.get_downloaders(downloaders, index); @@ -777,9 +781,14 @@ namespace libtorrent st.total_upload = m_stat.total_payload_upload() + m_stat.total_protocol_upload(); + // failed bytes + st.total_failed_bytes = m_total_failed_bytes; + // transfer rate st.download_rate = m_stat.download_rate(); st.upload_rate = m_stat.upload_rate(); + st.download_payload_rate = m_stat.download_payload_rate(); + st.upload_payload_rate = m_stat.upload_payload_rate(); st.progress = st.total_done / static_cast(m_torrent_file.total_size());