From 465b3c214ad0cf06a8d80ed8a31d60e8a1b1379e Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sun, 14 Dec 2003 22:55:32 +0000 Subject: [PATCH] *** empty log message *** --- docs/index.html | 9 ++-- docs/index.rst | 12 +++-- examples/client_test.cpp | 27 ++++++---- include/libtorrent/peer_connection.hpp | 26 +++++++-- include/libtorrent/policy.hpp | 6 +++ src/entry.cpp | 1 + src/peer_connection.cpp | 7 +-- src/policy.cpp | 75 ++++++++++++++++++++++---- src/session.cpp | 2 +- src/storage.cpp | 2 +- 10 files changed, 129 insertions(+), 38 deletions(-) diff --git a/docs/index.html b/docs/index.html index 4f4ab5ce3..7f000ac3d 100755 --- a/docs/index.html +++ b/docs/index.html @@ -128,10 +128,11 @@ first have to build boost.thread and boost.filesystem. You do this by, in the di 'boost-1.30.2/tools/build/jam_src' run the build script ./build.sh. This should produce at least one folder with the 'bin' prefix (and the rest of the name describes your platform). Put the files in that folder somewhere in your path.

-

You can then invoke bjam in the directories 'boost-1.30.2/libs/thread/build' and -'boost-1.30.2/libs/filesystem/build'. That will produce the needed libraries. Put these -libraries in the libtorrent root directory. You then have to modify the makefile to use -you prefered compiler and to have the correct path to your boost istallation.

+

You can then invoke bjam in the directories 'boost-1.30.2/libs/thread/build', +'boost-1.30.2/libs/date_time/build' and 'boost-1.30.2/libs/filesystem/build'. That will +produce the needed libraries. Put these libraries in the libtorrent root directory. +You then have to modify the makefile to use you prefered compiler and to have the +correct path to your boost istallation.

Then the makefile should be able to do the rest.

When building (with boost 1.30.2) on linux and solaris however, I found that I had to make the following modifications to the boost.date-time library. In the file: diff --git a/docs/index.rst b/docs/index.rst index 2c23b2dd1..cd8b7041c 100755 --- a/docs/index.rst +++ b/docs/index.rst @@ -65,6 +65,9 @@ libtorrent has been successfully compiled and tested on: * Windows 2000 vc7.1 * Linux x86 (debian) GCC 3.0 +It does not compile on + + * GCC 2.95 building ======== @@ -84,10 +87,11 @@ first have to build boost.thread and boost.filesystem. You do this by, in the di produce at least one folder with the 'bin' prefix (and the rest of the name describes your platform). Put the files in that folder somewhere in your path. -You can then invoke ``bjam`` in the directories 'boost-1.30.2/libs/thread/build' and -'boost-1.30.2/libs/filesystem/build'. That will produce the needed libraries. Put these -libraries in the libtorrent root directory. You then have to modify the makefile to use -you prefered compiler and to have the correct path to your boost istallation. +You can then invoke ``bjam`` in the directories 'boost-1.30.2/libs/thread/build', +'boost-1.30.2/libs/date_time/build' and 'boost-1.30.2/libs/filesystem/build'. That will +produce the needed libraries. Put these libraries in the libtorrent root directory. +You then have to modify the makefile to use you prefered compiler and to have the +correct path to your boost istallation. Then the makefile should be able to do the rest. diff --git a/examples/client_test.cpp b/examples/client_test.cpp index b4207de4c..03e3412c2 100755 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -72,10 +72,12 @@ void set_cursor(int x, int y) void clear() { + CONSOLE_SCREEN_BUFFER_INFO si; HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(h, &si); COORD c = {0, 0}; DWORD n; - FillConsoleOutputCharacter(h, ' ', 120 * 80, c, &n); + FillConsoleOutputCharacter(h, ' ', si.dwSize.X * si.dwSize.Y, c, &n); } #else @@ -133,12 +135,12 @@ void clear() #endif -std::string to_string(float v) +std::string to_string(float v, int width) { std::stringstream s; - s.precision(3); + s.precision(width-2); s.flags(std::ios_base::right); - s.width(4); + s.width(width); s.fill(' '); s << v; return s.str(); @@ -146,16 +148,16 @@ std::string to_string(float v) std::string add_suffix(float val) { - const char* prefix[] = {"B ", "kB", "MB", "GB", "TB"}; + const char* prefix[] = {"B", "kB", "MB", "GB", "TB"}; const int num_prefix = sizeof(prefix) / sizeof(const char*); int i; for (i = 0; i < num_prefix; ++i) { if (abs(val) < 1024.f) - return to_string(val) + prefix[i]; + return to_string(val, i==0?7:6) + prefix[i]; val /= 1024.f; } - return to_string(val) + prefix[i]; + return to_string(val, 6) + prefix[i]; } int main(int argc, char* argv[]) @@ -279,7 +281,7 @@ int main(int argc, char* argv[]) << "(" << add_suffix(i->total_download) << ") " << "u: " << add_suffix(i->up_speed) << "/s " << "(" << add_suffix(i->total_upload) << ") " - << "df: " << add_suffix((int)i->total_download - (int)i->total_upload) << " " +// << "df: " << add_suffix((int)i->total_download - (int)i->total_upload) << " " << "l: " << add_suffix(i->upload_limit) << "/s " << "f: " << static_cast((i->flags & peer_info::interesting)?"I":"_") @@ -291,10 +293,13 @@ int main(int argc, char* argv[]) { out << i->downloading_piece_index << ";" << i->downloading_block_index << ": "; - float progress = i->downloading_progress / static_cast(i->downloading_total); - for (int j = 0; j < 20; ++j) + float progress + = i->downloading_progress + / static_cast(i->downloading_total) + * 35; + for (int j = 0; j < 35; ++j) { - if (progress * 20 > j) out << "#"; + if (progress > j) out << "#"; else out << "-"; } out << "\n"; diff --git a/include/libtorrent/peer_connection.hpp b/include/libtorrent/peer_connection.hpp index 3af1c2366..a0cdf28b2 100755 --- a/include/libtorrent/peer_connection.hpp +++ b/include/libtorrent/peer_connection.hpp @@ -213,6 +213,9 @@ namespace libtorrent // quota is unlimited. int send_quota_left() const { return m_send_quota_left; } + void add_free_upload(int free_upload) + { m_free_upload += free_upload; } + // returns the send quota assigned to this // peer. int send_quota() const { return m_send_quota; } @@ -235,6 +238,13 @@ namespace libtorrent int send_quota_limit() const { return m_send_quota_limit; } + int share_diff() const + { + return m_free_upload + + m_statistics.total_download() + - m_statistics.total_upload(); + } + #ifndef NDEBUG boost::shared_ptr m_logger; #endif @@ -248,7 +258,6 @@ namespace libtorrent void send_have(int index); void send_handshake(); - // is used during handshake enum state { @@ -344,10 +353,6 @@ namespace libtorrent // remote peer's id peer_id m_peer_id; - // the pieces that we are sending and receiving -// piece_file m_sending_piece; -// piece_file m_receiving_piece; - // other side says that it's interested in downloading // from us. bool m_peer_interested; @@ -378,8 +383,19 @@ namespace libtorrent // from this peer std::deque m_download_queue; + // statistics about upload and download speeds + // and total amount of uploads and downloads for + // this peer stat m_statistics; + // the amount of data this peer has been given + // as free upload. This is distributed from + // peers from which we get free download + // this will be negative on a peer from which + // we get free download, and positive on peers + // that we give the free upload, to keep the balance. + int m_free_upload; + // this is used to limit upload bandwidth. // it is reset to the allowed number of // bytes to send frequently. Every time diff --git a/include/libtorrent/policy.hpp b/include/libtorrent/policy.hpp index 08d0258c0..ebb18744e 100755 --- a/include/libtorrent/policy.hpp +++ b/include/libtorrent/policy.hpp @@ -150,6 +150,8 @@ namespace libtorrent peer* find_choke_candidate(); peer* find_unchoke_candidate(); + + // a functor that identifies peers that have disconnected and that // are too old for still being saved. struct old_disconnected_peer @@ -177,6 +179,10 @@ namespace libtorrent // the number of unchoked peers // at any given time int m_num_unchoked; + + // free download we have got that hasn't + // been distributed yet. + int m_available_free_upload; }; } diff --git a/src/entry.cpp b/src/entry.cpp index 8b68f63b6..da37e6c77 100755 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -172,3 +172,4 @@ void libtorrent::entry::print(std::ostream& os, int indent) const os << "\n"; } } + diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 7044eafd6..5e2779ab2 100755 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -95,6 +95,7 @@ libtorrent::peer_connection::peer_connection( , m_peer_choked(true) , m_interesting(false) , m_choked(true) + , m_free_upload(0) , m_send_quota(100) , m_send_quota_left(100) , m_send_quota_limit(100) @@ -142,6 +143,7 @@ libtorrent::peer_connection::peer_connection( , m_peer_choked(true) , m_interesting(false) , m_choked(true) + , m_free_upload(0) , m_send_quota(100) , m_send_quota_left(100) , m_send_quota_limit(100) @@ -297,7 +299,7 @@ bool libtorrent::peer_connection::dispatch_message(int received) } m_download_queue.clear(); #ifndef NDEBUG - m_torrent->picker().integrity_check(m_torrent); +// m_torrent->picker().integrity_check(m_torrent); #endif break; @@ -806,8 +808,7 @@ void libtorrent::peer_connection::second_tick() // client has sent us. This is the mean to // maintain a 1:1 share ratio with all peers. - int diff = static_cast(m_statistics.total_download()) - - static_cast(m_statistics.total_upload()); + int diff = share_diff(); if (diff > 2*m_torrent->block_size()) { diff --git a/src/policy.cpp b/src/policy.cpp index 0ab42c743..24c0fce95 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -178,6 +178,55 @@ namespace num_requests--; } + + int collect_free_download( + torrent::peer_iterator start + , torrent::peer_iterator end) + { + int accumulator = 0; + for (torrent::peer_iterator i = start; i != end; ++i) + { + // if the peer is interested in us, it means it may + // want to trade it's surplus uploads for downloads itself + // (and we should consider it free). If the share diff is + // negative, there's no free download to get from this peer. + int diff = (*i)->share_diff(); + if ((*i)->is_peer_interested() || diff <= 0) + continue; + + (*i)->add_free_upload(-diff); + accumulator += diff; + } + return accumulator; + } + + + // returns the amount of free upload left after + // it has been distributed to the peers + int distribute_free_upload( + torrent::peer_iterator start + , torrent::peer_iterator end + , int free_upload) + { + if (free_upload == 0) return free_upload; + int num_peers = 0; + for (torrent::peer_iterator i = start; i != end; ++i) + { + if ((*i)->is_interesting() || !(*i)->is_peer_interested()) continue; + ++num_peers; + } + + if (num_peers == 0) return free_upload; + int upload_share = free_upload / num_peers; + + for (torrent::peer_iterator i = start; i != end; ++i) + { + if ((*i)->is_interesting() || !(*i)->is_peer_interested()) continue; + (*i)->add_free_upload(upload_share); + free_upload -= upload_share; + } + return free_upload; + } } namespace libtorrent @@ -211,6 +260,7 @@ namespace libtorrent , m_torrent(t) , m_max_uploads(-1) , m_num_unchoked(0) + , m_available_free_upload(0) {} // finds the peer that has the worst download rate // and returns it. May return 0 if all peers are @@ -269,7 +319,7 @@ namespace libtorrent if (c == 0) continue; if (!c->is_choked()) continue; if (!c->is_peer_interested()) continue; - if (i->total_download() - i->total_upload() + if (c->share_diff() < -free_upload_amount) continue; if (i->last_optimistically_unchoked > min_time) continue; @@ -290,6 +340,19 @@ namespace libtorrent , old_disconnected_peer()) , m_peers.end()); + // accumulate all the free download we get + // and add it to the available free upload + m_available_free_upload + += collect_free_download( + m_torrent->begin() + , m_torrent->end()); + + // distribute the free upload among the peers + m_available_free_upload = distribute_free_upload( + m_torrent->begin() + , m_torrent->end() + , m_available_free_upload); + if (m_max_uploads != -1) { // make sure we don't have too many @@ -454,14 +517,7 @@ namespace libtorrent // called when a peer is interested in us void policy::interested(peer_connection& c) { - // if we're interested in the peer, we unchoke it - // and hopes it will unchoke us too -/* if (c.is_interesting()) - { - c.unchoke(); - ++m_num_unchoked; - } -*/ } + } // called when a peer is no longer interested in us void policy::not_interested(peer_connection& c) @@ -496,6 +552,7 @@ namespace libtorrent --m_num_unchoked; unchoke_one_peer(); } + m_available_free_upload += i->connection->share_diff(); i->connection = 0; } diff --git a/src/session.cpp b/src/session.cpp index 21dc89972..0637d38c1 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -224,7 +224,7 @@ namespace sum_quota_limit += p.send_quota_limit(); } - assert(abs(sum_quota - std::min(upload_limit,sum_quota_limit)) < 10); + assert(std::min(upload_limit,sum_quota_limit) - sum_quota < 100); } #endif } diff --git a/src/storage.cpp b/src/storage.cpp index 6443f93db..bdb50953b 100755 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -30,9 +30,9 @@ POSSIBILITY OF SUCH DAMAGE. */ +#include #include #include -#include #include #include #include