* More cleanup of commands, including some optimization by avoiding

some heap allocations.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@893 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2007-04-18 15:15:06 +00:00
parent d0ae367dca
commit 7077aba019
9 changed files with 216 additions and 74 deletions
+2
View File
@@ -19,6 +19,8 @@ rtorrent_LDADD = \
rtorrent_SOURCES = \
command_events.cc \
command_events.h \
command_helpers.cc \
command_helpers.h \
command_ui.cc \
command_ui.h \
command_scheduler.cc \
+38 -3
View File
@@ -37,15 +37,17 @@
#include "config.h"
#include <sigc++/bind.h>
#include <torrent/rate.h>
#include "core/download.h"
#include "core/download_list.h"
#include "core/manager.h"
#include "utils/command_slot.h"
#include "utils/parse.h"
#include "utils/variable_map.h"
#include "globals.h"
#include "control.h"
#include "command_helpers.h"
void
apply_on_state_change(core::DownloadList::slot_map* slotMap, const torrent::Object& rawArgs) {
@@ -66,8 +68,39 @@ apply_on_state_change(core::DownloadList::slot_map* slotMap, const torrent::Obje
utils::convert_list_to_command(++args.begin(), args.end()));
}
#define ADD_COMMAND_SLOT(key, function, slot) \
variables->insert(key, new utils::CommandSlot(slot), &utils::CommandSlot::function);
void
apply_stop_on_ratio(const torrent::Object& rawArgs) {
const torrent::Object::list_type& args = rawArgs.as_list();
if (args.empty())
throw torrent::input_error("Too few arguments.");
torrent::Object::list_type::const_iterator argItr = args.begin();
// first argument: minimum ratio to reach
// second argument: minimum upload amount to reach [optional]
// third argument: maximum ratio to reach [optional]
int64_t minRatio = utils::convert_to_value(*argItr++);
int64_t minUpload = argItr != args.end() ? utils::convert_to_value(*argItr++) : 0;
int64_t maxRatio = argItr != args.end() ? utils::convert_to_value(*argItr++) : 0;
core::DownloadList* downloadList = control->core()->download_list();
core::Manager::DListItr itr = downloadList->begin();
while ((itr = std::find_if(itr, downloadList->end(), std::mem_fun(&core::Download::is_seeding)))
!= downloadList->end()) {
int64_t totalDone = (*itr)->download()->bytes_done();
int64_t totalUpload = (*itr)->download()->up_rate()->total();
if ((totalUpload >= minUpload && totalUpload * 100 >= totalDone * minRatio) ||
(maxRatio > 0 && totalUpload * 100 > totalDone * maxRatio)) {
downloadList->stop_try(*itr);
(*itr)->set("ignore_commands", (int64_t)1);
}
++itr;
}
}
void
initialize_command_events() {
@@ -84,4 +117,6 @@ initialize_command_events() {
ADD_COMMAND_SLOT("on_hash_removed", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_hash_removed()));
ADD_COMMAND_SLOT("on_hash_done", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_hash_done()));
ADD_COMMAND_SLOT("on_finished", call_list, rak::bind_ptr_fn(&apply_on_state_change, &downloadList->slot_map_finished()));
ADD_COMMAND_SLOT("stop_on_ratio", call_list, rak::ptr_fn(&apply_stop_on_ratio));
}
+77
View File
@@ -0,0 +1,77 @@
// rTorrent - BitTorrent client
// Copyright (C) 2006, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations
// including the two.
//
// You must obey the GNU General Public License in all respects for
// all of the code used other than OpenSSL. If you modify file(s)
// with this exception, you may extend this exception to your version
// of the file(s), but you are not obligated to do so. If you do not
// wish to do so, delete this exception statement from your version.
// If you delete this exception statement from all source files in the
// program, then also delete it here.
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#include "config.h"
#include <torrent/exceptions.h>
#include "utils/command_slot.h"
#include "utils/command_variable.h"
#include "globals.h"
#include "control.h"
#include "command_helpers.h"
utils::CommandSlot commandSlots[COMMAND_SLOTS_SIZE];
utils::CommandSlot* commandSlotsItr = commandSlots;
utils::CommandVariable commandVariables[COMMAND_VARIABLES_SIZE];
utils::CommandVariable* commandVariablesItr = commandVariables;
void
initialize_commands() {
initialize_variables();
initialize_download_variables();
initialize_command_events();
initialize_command_ui();
if (commandSlotsItr != commandSlots + COMMAND_SLOTS_SIZE ||
commandVariablesItr != commandVariables + COMMAND_VARIABLES_SIZE)
throw torrent::internal_error("initialize_commands() static command array size mismatch.");
}
void
add_variable(const char* getKey, const char* setKey, const char* defaultSetKey,
utils::VariableMap::generic_slot getSlot, utils::VariableMap::generic_slot setSlot,
const torrent::Object& defaultObject) {
utils::CommandVariable* variable = commandVariablesItr++;
variable->set_variable(defaultObject);
control->variable()->insert(getKey, variable, getSlot, utils::VariableMap::flag_dont_delete);
control->variable()->insert(setKey, variable, setSlot, utils::VariableMap::flag_dont_delete);
if (defaultSetKey)
control->variable()->insert(defaultSetKey, variable, setSlot, utils::VariableMap::flag_dont_delete);
}
+82
View File
@@ -0,0 +1,82 @@
// rTorrent - BitTorrent client
// Copyright (C) 2006, Jari Sundell
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations
// including the two.
//
// You must obey the GNU General Public License in all respects for
// all of the code used other than OpenSSL. If you modify file(s)
// with this exception, you may extend this exception to your version
// of the file(s), but you are not obligated to do so. If you do not
// wish to do so, delete this exception statement from your version.
// If you delete this exception statement from all source files in the
// program, then also delete it here.
//
// Contact: Jari Sundell <jaris@ifi.uio.no>
//
// Skomakerveien 33
// 3185 Skoppum, NORWAY
#ifndef RTORRENT_UTILS_COMMAND_HELPERS_H
#define RTORRENT_UTILS_COMMAND_HELPERS_H
#include "utils/variable_map.h"
namespace utils {
class CommandSlot;
class CommandVariable;
}
// By using a static array we avoid allocating the variables on the
// heap. This should reduce memory use and improve cache locality.
#define COMMAND_SLOTS_SIZE 18
#define COMMAND_VARIABLES_SIZE 23
extern utils::CommandSlot commandSlots[COMMAND_SLOTS_SIZE];
extern utils::CommandSlot* commandSlotsItr;
extern utils::CommandVariable commandVariables[COMMAND_VARIABLES_SIZE];
extern utils::CommandVariable* commandVariablesItr;
void initialize_variables();
void initialize_download_variables();
void initialize_command_events();
void initialize_command_ui();
void initialize_commands();
void
add_variable(const char* getKey, const char* setKey, const char* defaultSetKey,
utils::VariableMap::generic_slot getSlot, utils::VariableMap::generic_slot setSlot,
const torrent::Object& defaultObject);
#define ADD_VARIABLE_BOOL(key, defaultValue) \
add_variable("get_" key, "set_" key, key, &utils::CommandVariable::get_bool, &utils::CommandVariable::set_bool, (int64_t)defaultValue);
#define ADD_VARIABLE_VALUE(key, defaultValue) \
add_variable("get_" key, "set_" key, key, &utils::CommandVariable::get_value, &utils::CommandVariable::set_value, (int64_t)defaultValue);
#define ADD_VARIABLE_STRING(key, defaultValue) \
add_variable("get_" key, "set_" key, key, &utils::CommandVariable::get_string, &utils::CommandVariable::set_string, std::string(defaultValue));
#define ADD_COMMAND_SLOT(key, function, slot) \
commandSlotsItr->set_slot(slot); \
variables->insert(key, commandSlotsItr++, &utils::CommandSlot::function, utils::VariableMap::flag_dont_delete);
#endif
+1 -4
View File
@@ -44,10 +44,10 @@
#include "core/view_manager.h"
#include "utils/command_slot.h"
#include "utils/parse.h"
#include "utils/variable_map.h"
#include "globals.h"
#include "control.h"
#include "command_helpers.h"
typedef void (core::ViewManager::*view_filter_slot)(const std::string&, const core::ViewManager::sort_args&);
@@ -91,9 +91,6 @@ apply_view_sort(const torrent::Object& rawArgs) {
control->view_manager()->sort(name, value);
}
#define ADD_COMMAND_SLOT(key, function, slot) \
variables->insert(key, new utils::CommandSlot(slot), &utils::CommandSlot::function);
void
initialize_command_ui() {
utils::VariableMap* variables = control->variable();
+2 -4
View File
@@ -71,6 +71,7 @@
void do_panic(int signum);
void print_help();
void initialize_commands();
int
parse_options(Control* c, int argc, char** argv) {
@@ -163,10 +164,7 @@ main(int argc, char** argv) {
// Initialize option handlers after libtorrent to ensure
// torrent::ConnectionManager* are valid etc.
initialize_variables();
initialize_download_variables();
initialize_command_events();
initialize_command_ui();
initialize_commands();
control->variable()->process_multiple
(
+1 -61
View File
@@ -78,6 +78,7 @@
#include "control.h"
#include "option_handler_rules.h"
#include "command_scheduler.h"
#include "command_helpers.h"
namespace core {
extern void
@@ -182,38 +183,6 @@ apply_close_low_diskspace(int64_t arg) {
}
}
void
apply_stop_on_ratio(const torrent::Object& rawArgs) {
const torrent::Object::list_type& args = rawArgs.as_list();
if (args.empty())
throw torrent::input_error("Too few arguments.");
torrent::Object::list_type::const_iterator argItr = args.begin();
// first argument: minimum ratio to reach
// second argument: minimum upload amount to reach [optional]
// third argument: maximum ratio to reach [optional]
int64_t minRatio = utils::convert_to_value(*argItr++);
int64_t minUpload = argItr != args.end() ? utils::convert_to_value(*argItr++) : 0;
int64_t maxRatio = argItr != args.end() ? utils::convert_to_value(*argItr++) : 0;
core::Manager::DListItr itr = control->core()->download_list()->begin();
while ((itr = std::find_if(itr, control->core()->download_list()->end(), std::mem_fun(&core::Download::is_seeding))) != control->core()->download_list()->end()) {
int64_t totalUpload = (*itr)->download()->up_rate()->total();
int64_t totalDone = (*itr)->download()->bytes_done();
if ((totalUpload >= minUpload && totalUpload * 100 >= totalDone * minRatio) ||
(maxRatio > 0 && totalUpload * 100 > totalDone * maxRatio)) {
control->core()->download_list()->stop_try(*itr);
(*itr)->set("ignore_commands", (int64_t)1);
}
++itr;
}
}
void
apply_encoding_list(const std::string& arg) {
torrent::encoding_list()->push_back(arg);
@@ -337,31 +306,6 @@ apply_schedule(const torrent::Object& rawArgs) {
control->command_scheduler()->parse(arg1, arg2, arg3, utils::convert_list_to_command(itr, args.end()));
}
void
add_variable(const char* getKey, const char* setKey, const char* defaultSetKey,
utils::VariableMap::generic_slot getSlot, utils::VariableMap::generic_slot setSlot,
const torrent::Object& defaultObject) {
utils::Variable* variable = new utils::CommandVariable(defaultObject);
control->variable()->insert(getKey, variable, getSlot);
control->variable()->insert(setKey, variable, setSlot, utils::VariableMap::flag_dont_delete);
if (defaultSetKey)
control->variable()->insert(defaultSetKey, variable, setSlot, utils::VariableMap::flag_dont_delete);
}
#define ADD_VARIABLE_BOOL(key, defaultValue) \
add_variable("get_" key, "set_" key, key, &utils::CommandVariable::get_bool, &utils::CommandVariable::set_bool, (int64_t)defaultValue);
#define ADD_VARIABLE_VALUE(key, defaultValue) \
add_variable("get_" key, "set_" key, key, &utils::CommandVariable::get_value, &utils::CommandVariable::set_value, (int64_t)defaultValue);
#define ADD_VARIABLE_STRING(key, defaultValue) \
add_variable("get_" key, "set_" key, key, &utils::CommandVariable::get_string, &utils::CommandVariable::set_string, std::string(defaultValue));
#define ADD_COMMAND_SLOT(key, function, slot) \
variables->insert(key, new utils::CommandSlot(slot), &utils::CommandSlot::function);
void
initialize_variables() {
utils::VariableMap* variables = control->variable();
@@ -430,7 +374,6 @@ initialize_variables() {
variables->insert("try_import", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_try_import)));
ADD_COMMAND_SLOT("schedule", call_list, rak::ptr_fn(&apply_schedule));
// variables->insert("schedule", new utils::VariableListSlot(rak::ptr_fn(&apply_schedule)));
variables->insert("schedule_remove", new utils::VariableStringSlot(NULL, rak::mem_fn<const std::string&>(control->command_scheduler(), &CommandScheduler::erase)));
variables->insert("download_scheduler", new utils::VariableVoidSlot(rak::mem_fn(control->scheduler(), &core::Scheduler::update)));
@@ -487,14 +430,11 @@ initialize_variables() {
variables->insert("remove_untied", new utils::VariableVoidSlot(rak::ptr_fn(&apply_remove_untied)));
variables->insert("close_low_diskspace", new utils::VariableValueSlot(rak::value_fn(int64_t()), rak::ptr_fn(&apply_close_low_diskspace)));
ADD_COMMAND_SLOT("stop_on_ratio", call_list, rak::ptr_fn(&apply_stop_on_ratio));
// variables->insert("stop_on_ratio", new utils::VariableListSlot(rak::ptr_fn(&apply_stop_on_ratio)));
variables->insert("enable_trackers", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_enable_trackers)));
variables->insert("encoding_list", new utils::VariableStringSlot(NULL, rak::ptr_fn(&apply_encoding_list)));
ADD_COMMAND_SLOT("encryption", call_list, rak::ptr_fn(&apply_encryption));
// variables->insert("encryption", new utils::VariableListSlot(rak::ptr_fn(&apply_encryption)));
// Move to command_ui.cc.
variables->insert("print", new utils::VariableStringSlot(NULL, rak::mem_fn(control->core(), &core::Manager::push_log)));
+10 -2
View File
@@ -47,6 +47,10 @@
namespace utils {
// The CommandSlot class uses union instead of creating multiple
// derived classes so that it is possible to create an array
// containing different slot types.
class CommandSlot : public Variable {
public:
// For now, only return void.
@@ -57,10 +61,14 @@ public:
// m_slotSet.set(slotSet);
// }
CommandSlot(slot_type::base_type* slotSet) {
m_slot.set(slotSet);
CommandSlot() {}
CommandSlot(slot_type::base_type* s) {
m_slot.set(s);
}
void set_slot(slot_type::base_type* s) { m_slot.set(s); }
static const torrent::Object& call_list(Variable* rawVariable, const torrent::Object& args);
// static const torrent::Object& get_list(Variable* rawVariable, const torrent::Object& args);
+3
View File
@@ -50,6 +50,9 @@ class CommandVariable : public Variable {
public:
CommandVariable(const torrent::Object& v = torrent::Object()) : m_variable(v) {}
const torrent::Object& variable() const { return m_variable; }
void set_variable(const torrent::Object& var) { m_variable = var; }
static const torrent::Object& set_bool(Variable* rawVariable, const torrent::Object& args);
static const torrent::Object& get_bool(Variable* rawVariable, const torrent::Object& args);