From 9ed7596daf4570359b8d489563a8e5b6cfc50f73 Mon Sep 17 00:00:00 2001 From: rakshasa Date: Wed, 30 Mar 2011 10:39:03 +0000 Subject: [PATCH] * Added framework for introducing different choking algorithms. git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1196 e378c898-3ddf-0310-93e7-cc216c733640 --- src/command_download.cc | 63 ++++++++++++++++++++++++++++++------ src/command_network.cc | 5 +++ src/core/download_factory.cc | 7 +++- src/core/download_list.cc | 14 ++++++-- src/ui/download.cc | 1 + 5 files changed, 76 insertions(+), 14 deletions(-) diff --git a/src/command_download.cc b/src/command_download.cc index 44872086..e63f5c3d 100644 --- a/src/command_download.cc +++ b/src/command_download.cc @@ -168,6 +168,16 @@ apply_d_delete_tied(core::Download* download) { return torrent::Object(); } +void +apply_d_directory(core::Download* download, const std::string& name) { + if (!download->file_list()->is_multi_file()) + download->set_root_directory(name); + else if (name.empty() || *name.rbegin() == '/') + download->set_root_directory(name + download->info()->name()); + else + download->set_root_directory(name + "/" + download->info()->name()); +} + torrent::Object apply_d_connection_type(core::Download* download, const std::string& name) { torrent::Download::ConnectionType connType; @@ -185,16 +195,6 @@ apply_d_connection_type(core::Download* download, const std::string& name) { return torrent::Object(); } -void -apply_d_directory(core::Download* download, const std::string& name) { - if (!download->file_list()->is_multi_file()) - download->set_root_directory(name); - else if (name.empty() || *name.rbegin() == '/') - download->set_root_directory(name + download->info()->name()); - else - download->set_root_directory(name + "/" + download->info()->name()); -} - const char* retrieve_d_connection_type(core::Download* download) { switch (download->download()->connection_type()) { @@ -209,6 +209,39 @@ retrieve_d_connection_type(core::Download* download) { } } +torrent::Object +apply_d_choke_heuristics(core::Download* download, const std::string& name, bool is_down) { + torrent::Download::HeuristicType connType; + + if (name == "upload_leech") + connType = torrent::Download::HEURISTICS_UPLOAD_LEECH; + else if (name == "download_leech") + connType = torrent::Download::HEURISTICS_DOWNLOAD_LEECH; + else + throw torrent::input_error("Unknown peer heuristic selected."); + + if (is_down) + download->download()->set_download_choke_heuristic(connType); + else + download->download()->set_upload_choke_heuristic(connType); + + return torrent::Object(); +} + +const char* +retrieve_d_choke_heuristics(core::Download* download, bool is_down) { + switch (is_down ? + download->download()->download_choke_heuristic() : + download->download()->upload_choke_heuristic()) { + case torrent::Download::HEURISTICS_UPLOAD_LEECH: + return "upload_leech"; + case torrent::Download::HEURISTICS_DOWNLOAD_LEECH: + return "download_leech"; + default: + return "unknown"; + } +} + const char* retrieve_d_priority_str(core::Download* download) { switch (download->priority()) { @@ -700,6 +733,16 @@ initialize_command_download() { CMD2_DL_VAR_STRING("d.connection_leech", "rtorrent", "connection_leech"); CMD2_DL_VAR_STRING("d.connection_seed", "rtorrent", "connection_seed"); + CMD2_DL ("d.up.choke_heuristics", std::tr1::bind(&retrieve_d_choke_heuristics, std::tr1::placeholders::_1, false)); + CMD2_DL_STRING("d.up.choke_heuristics.set", std::tr1::bind(&apply_d_choke_heuristics, std::tr1::placeholders::_1, std::tr1::placeholders::_2, false)); + CMD2_DL ("d.down.choke_heuristics", std::tr1::bind(&retrieve_d_choke_heuristics, std::tr1::placeholders::_1, true)); + CMD2_DL_STRING("d.down.choke_heuristics.set", std::tr1::bind(&apply_d_choke_heuristics, std::tr1::placeholders::_1, std::tr1::placeholders::_2, true)); + + CMD2_DL_VAR_STRING("d.up.choke_heuristics.leech", "rtorrent", "choke_heuristics.up.leech"); + CMD2_DL_VAR_STRING("d.up.choke_heuristics.seed", "rtorrent", "choke_heuristics.up.seed"); + CMD2_DL_VAR_STRING("d.down.choke_heuristics.leech", "rtorrent", "choke_heuristics.down.leech"); + CMD2_DL_VAR_STRING("d.down.choke_heuristics.seed", "rtorrent", "choke_heuristics.down.seed"); + CMD2_DL ("d.hashing_failed", std::tr1::bind(&core::Download::is_hash_failed, std::tr1::placeholders::_1)); CMD2_DL_VALUE_V("d.hashing_failed.set", std::tr1::bind(&core::Download::set_hash_failed, std::tr1::placeholders::_1, std::tr1::placeholders::_2)); diff --git a/src/command_network.cc b/src/command_network.cc index f2354fdf..3f9b3996 100644 --- a/src/command_network.cc +++ b/src/command_network.cc @@ -556,6 +556,11 @@ initialize_command_network() { CMD2_VAR_STRING ("protocol.connection.leech", "leech"); CMD2_VAR_STRING ("protocol.connection.seed", "seed"); + CMD2_VAR_STRING ("protocol.choke_heuristics.up.leech", "upload_leech"); + CMD2_VAR_STRING ("protocol.choke_heuristics.up.seed", "upload_leech"); + CMD2_VAR_STRING ("protocol.choke_heuristics.down.leech", "download_leech"); + CMD2_VAR_STRING ("protocol.choke_heuristics.down.seed", "download_leech"); + CMD2_ANY ("throttle.unchoked_uploads", std::tr1::bind(&torrent::currently_unchoked)); CMD2_ANY ("throttle.unchoked_downloads", std::tr1::bind(&torrent::download_unchoked)); diff --git a/src/core/download_factory.cc b/src/core/download_factory.cc index ba898d00..466c0872 100644 --- a/src/core/download_factory.cc +++ b/src/core/download_factory.cc @@ -397,7 +397,12 @@ DownloadFactory::initialize_rtorrent(Download* download, torrent::Object* rtorre rtorrent->insert_preserve_copy("views", torrent::Object::create_list()); rtorrent->insert_preserve_type("connection_leech", m_variables["connection_leech"]); - rtorrent->insert_preserve_type("connection_seed", m_variables["connection_seed"]); + rtorrent->insert_preserve_type("connection_seed", m_variables["connection_seed"]); + + rtorrent->insert_preserve_copy("choke_heuristics.up.leech", rpc::call_command_void("protocol.choke_heuristics.up.leech")); + rtorrent->insert_preserve_copy("choke_heuristics.up.seed", rpc::call_command_void("protocol.choke_heuristics.up.seed")); + rtorrent->insert_preserve_copy("choke_heuristics.down.leech", rpc::call_command_void("protocol.choke_heuristics.down.leech")); + rtorrent->insert_preserve_copy("choke_heuristics.down.seed", rpc::call_command_void("protocol.choke_heuristics.down.seed")); } } diff --git a/src/core/download_list.cc b/src/core/download_list.cc index b5e4d7cd..37a6f725 100644 --- a/src/core/download_list.cc +++ b/src/core/download_list.cc @@ -357,9 +357,14 @@ DownloadList::resume(Download* download, int flags) { rpc::call_command("d.state_counter.set", rpc::call_command_value("d.state_counter", rpc::make_target(download)) + 1, rpc::make_target(download)); if (download->is_done()) { - rpc::call_command("d.connection_current.set", rpc::call_command_void("d.connection_seed", rpc::make_target(download)), rpc::make_target(download)); + rpc::call_command("d.connection_current.set", rpc::call_command_void("d.connection_seed", rpc::make_target(download)), rpc::make_target(download)); + rpc::call_command("d.up.choke_heuristics.set", rpc::call_command_void("d.up.choke_heuristics.seed", rpc::make_target(download)), rpc::make_target(download)); + rpc::call_command("d.down.choke_heuristics.set", rpc::call_command_void("d.down.choke_heuristics.seed", rpc::make_target(download)), rpc::make_target(download)); + } else { - rpc::call_command("d.connection_current.set", rpc::call_command_void("d.connection_leech", rpc::make_target(download)), rpc::make_target(download)); + rpc::call_command("d.connection_current.set", rpc::call_command_void("d.connection_leech", rpc::make_target(download)), rpc::make_target(download)); + rpc::call_command("d.up.choke_heuristics.set", rpc::call_command_void("d.up.choke_heuristics.leech", rpc::make_target(download)), rpc::make_target(download)); + rpc::call_command("d.down.choke_heuristics.set", rpc::call_command_void("d.down.choke_heuristics.leech", rpc::make_target(download)), rpc::make_target(download)); // For the moment, clear the resume data so we force hash-check // on non-complete downloads after a crash. This shouldn't be @@ -576,7 +581,10 @@ DownloadList::confirm_finished(Download* download) { rpc::call_command("d.complete.set", (int64_t)1, rpc::make_target(download)); - rpc::call_command("d.connection_current.set", rpc::call_command_void("d.connection_seed", rpc::make_target(download)), rpc::make_target(download)); + rpc::call_command("d.connection_current.set", rpc::call_command_void("d.connection_seed", rpc::make_target(download)), rpc::make_target(download)); + rpc::call_command("d.up.choke_heuristics.set", rpc::call_command_void("d.up.choke_heuristics.seed", rpc::make_target(download)), rpc::make_target(download)); + rpc::call_command("d.down.choke_heuristics.set", rpc::call_command_void("d.down.choke_heuristics.seed", rpc::make_target(download)), rpc::make_target(download)); + download->set_priority(download->priority()); if (rpc::call_command_value("d.peers_min", rpc::make_target(download)) == rpc::call_command_value("throttle.min_peers.normal") && diff --git a/src/ui/download.cc b/src/ui/download.cc index 4854e24f..f09eeafb 100644 --- a/src/ui/download.cc +++ b/src/ui/download.cc @@ -177,6 +177,7 @@ Download::create_info() { element->push_back(""); element->push_column("Connection type:", te_command("d.connection_current=")); + element->push_column("Choke heuristic:", te_command("cat=$d.up.choke_heuristics=,\", \",$d.down.choke_heuristics=")); element->push_column("Safe sync:", te_command("if=$pieces.sync.always_safe=,yes,no")); element->push_column("Send buffer:", te_command("cat=$convert.kb=$network.send_buffer.size=,\" KB\"")); element->push_column("Receive buffer:", te_command("cat=$convert.kb=$network.receive_buffer.size=,\" KB\""));