* Converted VariableMap and ViewManager to using const char* as the

key, since they are never changed nor added from outside. This cut the
stripped binary size by 50KB.

* Use a shared have piece queue for each download. Each connection has
a time-stamp for the last have message they sent, which is checked
against the queue. This also avoids the race condition where some
peers would get incomplete views of our bitfield due to lost have
messages during handshake.


git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@839 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2007-01-01 14:57:10 +00:00
parent fe7adfc999
commit de744ad11d
8 changed files with 72 additions and 52 deletions
+9 -9
View File
@@ -462,14 +462,14 @@ public:
typedef Ret (Object::*Function)() const; typedef Ret (Object::*Function)() const;
const_mem_fun0() : m_object(NULL) {} const_mem_fun0() : m_object(NULL) {}
const_mem_fun0(Object* o, Function f) : m_object(o), m_function(f) {} const_mem_fun0(const Object* o, Function f) : m_object(o), m_function(f) {}
bool is_valid() const { return m_object; } bool is_valid() const { return m_object; }
Ret operator () () { return (m_object->*m_function)(); } Ret operator () () const { return (m_object->*m_function)(); }
private: private:
Object* m_object; const Object* m_object;
Function m_function; Function m_function;
}; };
@@ -498,14 +498,14 @@ public:
typedef Ret (Object::*Function)(Arg1) const; typedef Ret (Object::*Function)(Arg1) const;
const_mem_fun1() : m_object(NULL) {} const_mem_fun1() : m_object(NULL) {}
const_mem_fun1(Object* o, Function f) : m_object(o), m_function(f) {} const_mem_fun1(const Object* o, Function f) : m_object(o), m_function(f) {}
bool is_valid() const { return m_object; } bool is_valid() const { return m_object; }
Ret operator () (Arg1 a1) { return (m_object->*m_function)(a1); } Ret operator () (Arg1 a1) const { return (m_object->*m_function)(a1); }
private: private:
Object* m_object; const Object* m_object;
Function m_function; Function m_function;
}; };
@@ -556,9 +556,9 @@ make_mem_fun(Object* o, Ret (Object::*f)()) {
} }
template <typename Object, typename Ret> template <typename Object, typename Ret>
inline const_mem_fun0<const Object, Ret> inline const_mem_fun0<Object, Ret>
make_mem_fun(const Object* o, Ret (Object::*f)() const) { make_mem_fun(const Object* o, Ret (Object::*f)() const) {
return const_mem_fun0<const Object, Ret>(o, f); return const_mem_fun0<Object, Ret>(o, f);
} }
template <typename Object, typename Ret, typename Arg1> template <typename Object, typename Ret, typename Arg1>
@@ -569,7 +569,7 @@ make_mem_fun(Object* o, Ret (Object::*f)(Arg1)) {
template <typename Object, typename Ret, typename Arg1> template <typename Object, typename Ret, typename Arg1>
inline const_mem_fun1<Object, Ret, Arg1> inline const_mem_fun1<Object, Ret, Arg1>
make_mem_fun(Object* o, Ret (Object::*f)(Arg1) const) { make_mem_fun(const Object* o, Ret (Object::*f)(Arg1) const) {
return const_mem_fun1<Object, Ret, Arg1>(o, f); return const_mem_fun1<Object, Ret, Arg1>(o, f);
} }
+6 -2
View File
@@ -83,8 +83,12 @@ public:
void set_hash_failed(bool v) { m_hashFailed = v; } void set_hash_failed(bool v) { m_hashFailed = v; }
variable_map_type* variable() { return &m_variables; } variable_map_type* variable() { return &m_variables; }
int64_t variable_value(const std::string& key) const { return m_variables.get_value(key); }
const std::string& variable_string(const std::string& key) const { return m_variables.get_string(key); } int64_t variable_value(const std::string& key) const { return m_variables.get_value(key.c_str()); }
const std::string& variable_string(const std::string& key) const { return m_variables.get_string(key.c_str()); }
int64_t variable_value_c(const char* key) const { return m_variables.get_value(key); }
const std::string& variable_string_c(const char* key) const { return m_variables.get_string(key); }
download_type* download() { return &m_download; } download_type* download() { return &m_download; }
const download_type* c_download() const { return &m_download; } const download_type* c_download() const { return &m_download; }
+9 -11
View File
@@ -66,8 +66,7 @@ public:
class ViewSortVariable : public ViewSort { class ViewSortVariable : public ViewSort {
public: public:
ViewSortVariable(const std::string& name, const std::string& value) : ViewSortVariable(const char* name, const char* value) : m_name(name), m_value(value) {}
m_name(name), m_value(value) {}
virtual bool operator () (Download* d1, Download* d2) const { virtual bool operator () (Download* d1, Download* d2) const {
return return
@@ -76,14 +75,13 @@ public:
} }
private: private:
std::string m_name; const char* m_name;
std::string m_value; const char* m_value;
}; };
class ViewSortVariableValue : public ViewSort { class ViewSortVariableValue : public ViewSort {
public: public:
ViewSortVariableValue(const std::string& name, bool reverse = false) : ViewSortVariableValue(const char* name, bool reverse = false) : m_name(name), m_reverse(reverse) {}
m_name(name), m_reverse(reverse) {}
virtual bool operator () (Download* d1, Download* d2) const { virtual bool operator () (Download* d1, Download* d2) const {
if (m_reverse) if (m_reverse)
@@ -93,7 +91,7 @@ public:
} }
private: private:
std::string m_name; const char* m_name;
bool m_reverse; bool m_reverse;
}; };
@@ -112,7 +110,7 @@ private:
class ViewFilterVariableValue : public ViewFilter { class ViewFilterVariableValue : public ViewFilter {
public: public:
ViewFilterVariableValue(const std::string& name, torrent::Object::value_type v, bool inverse = false) : ViewFilterVariableValue(const char* name, torrent::Object::value_type v, bool inverse = false) :
m_name(name), m_value(v), m_inverse(inverse) {} m_name(name), m_value(v), m_inverse(inverse) {}
virtual bool operator () (Download* d1) const { virtual bool operator () (Download* d1) const {
@@ -120,7 +118,7 @@ public:
} }
private: private:
std::string m_name; const char* m_name;
torrent::Object::value_type m_value; torrent::Object::value_type m_value;
bool m_inverse; bool m_inverse;
}; };
@@ -191,7 +189,7 @@ ViewManager::build_sort_list(const sort_args& args) {
sortList.reserve(args.size()); sortList.reserve(args.size());
for (sort_args::const_iterator itr = args.begin(), last = args.end(); itr != last; ++itr) { for (sort_args::const_iterator itr = args.begin(), last = args.end(); itr != last; ++itr) {
sort_map::const_iterator sortItr = m_sort.find(*itr); sort_map::const_iterator sortItr = m_sort.find(itr->c_str());
if (sortItr == m_sort.end()) if (sortItr == m_sort.end())
throw torrent::input_error("Invalid sorting identifier."); throw torrent::input_error("Invalid sorting identifier.");
@@ -235,7 +233,7 @@ ViewManager::build_filter_list(const filter_args& args) {
filterList.reserve(args.size()); filterList.reserve(args.size());
for (filter_args::const_iterator itr = args.begin(), last = args.end(); itr != last; ++itr) { for (filter_args::const_iterator itr = args.begin(), last = args.end(); itr != last; ++itr) {
filter_map::const_iterator filterItr = m_filter.find(*itr); filter_map::const_iterator filterItr = m_filter.find(itr->c_str());
if (filterItr == m_filter.end()) if (filterItr == m_filter.end())
throw torrent::input_error("Invalid filtering identifier."); throw torrent::input_error("Invalid filtering identifier.");
+7 -2
View File
@@ -38,6 +38,7 @@
#define RTORRENT_CORE_VIEW_MANAGER_H #define RTORRENT_CORE_VIEW_MANAGER_H
#include <map> #include <map>
#include <cstring>
#include <string> #include <string>
#include <rak/unordered_vector.h> #include <rak/unordered_vector.h>
@@ -45,17 +46,21 @@
namespace core { namespace core {
struct view_manager_comp : public std::binary_function<const char*, const char*, bool> {
bool operator () (const char* arg1, const char* arg2) const { return std::strcmp(arg1, arg2) < 0; }
};
class ViewSort; class ViewSort;
class ViewManager : public rak::unordered_vector<View*> { class ViewManager : public rak::unordered_vector<View*> {
public: public:
typedef rak::unordered_vector<View*> base_type; typedef rak::unordered_vector<View*> base_type;
typedef std::map<std::string, ViewSort*> sort_map; typedef std::map<const char*, ViewSort*, view_manager_comp> sort_map;
typedef View::sort_list sort_list; typedef View::sort_list sort_list;
typedef std::list<std::string> sort_args; typedef std::list<std::string> sort_args;
typedef std::map<std::string, ViewFilter*> filter_map; typedef std::map<const char*, ViewFilter*, view_manager_comp> filter_map;
typedef View::filter_list filter_list; typedef View::filter_list filter_list;
typedef std::list<std::string> filter_args; typedef std::list<std::string> filter_args;
+1 -1
View File
@@ -88,7 +88,7 @@ parse_options(Control* c, int argc, char** argv) {
optionParser.insert_option('s', sigc::bind<0>(sigc::mem_fun(c->variable(), &utils::VariableMap::set_string), "session")); optionParser.insert_option('s', sigc::bind<0>(sigc::mem_fun(c->variable(), &utils::VariableMap::set_string), "session"));
optionParser.insert_option('O', sigc::mem_fun(c->variable(), &utils::VariableMap::process_command)); optionParser.insert_option('O', sigc::mem_fun(c->variable(), &utils::VariableMap::process_command));
optionParser.insert_option_list('o', sigc::mem_fun(c->variable(), &utils::VariableMap::set_string)); optionParser.insert_option_list('o', sigc::mem_fun(c->variable(), &utils::VariableMap::set_std_string));
return optionParser.process(argc, argv); return optionParser.process(argc, argv);
+2 -2
View File
@@ -409,13 +409,13 @@ apply_view_sort_new(Control* control, const std::string& arg) {
void void
apply_import(const std::string& path) { apply_import(const std::string& path) {
if (!control->variable()->process_file(path)) if (!control->variable()->process_file(path.c_str()))
throw torrent::input_error("Could not open option file: " + path); throw torrent::input_error("Could not open option file: " + path);
} }
void void
apply_try_import(const std::string& path) { apply_try_import(const std::string& path) {
if (!control->variable()->process_file(path)) if (!control->variable()->process_file(path.c_str()))
control->core()->push_log("Could not read resource file: " + path); control->core()->push_log("Could not read resource file: " + path);
} }
+10 -10
View File
@@ -55,7 +55,7 @@ VariableMap::~VariableMap() {
} }
void void
VariableMap::insert(const std::string& key, Variable* v) { VariableMap::insert(key_type key, Variable* v) {
iterator itr = base_type::find(key); iterator itr = base_type::find(key);
if (itr != base_type::end()) if (itr != base_type::end())
@@ -65,23 +65,23 @@ VariableMap::insert(const std::string& key, Variable* v) {
} }
const VariableMap::mapped_type& const VariableMap::mapped_type&
VariableMap::get(const std::string& key) const { VariableMap::get(key_type key) const {
const_iterator itr = base_type::find(key); const_iterator itr = base_type::find(key);
if (itr == base_type::end()) if (itr == base_type::end())
throw torrent::input_error("Variable \"" + key + "\" does not exist."); throw torrent::input_error("Variable \"" + std::string(key) + "\" does not exist.");
return itr->second->get(); return itr->second->get();
} }
void void
VariableMap::set(const std::string& key, const mapped_type& arg) { VariableMap::set(key_type key, const mapped_type& arg) {
iterator itr = base_type::find(key); iterator itr = base_type::find(key);
// Later, allow the user to create new variables. Have a slot to // Later, allow the user to create new variables. Have a slot to
// register that thing. // register that thing.
if (itr == base_type::end()) if (itr == base_type::end())
throw torrent::input_error("Variable \"" + key + "\" does not exist."); throw torrent::input_error("Variable \"" + std::string(key) + "\" does not exist.");
itr->second->set(arg); itr->second->set(arg);
} }
@@ -160,17 +160,17 @@ VariableMap::process_command(const std::string& command) {
parse_args(pos + 1, command.end(), &args.as_list()); parse_args(pos + 1, command.end(), &args.as_list());
if (args.as_list().empty()) if (args.as_list().empty())
set(key, mapped_type()); set(key.c_str(), mapped_type());
else if (++args.as_list().begin() == args.as_list().end()) else if (++args.as_list().begin() == args.as_list().end())
set(key, *args.as_list().begin()); set(key.c_str(), *args.as_list().begin());
else else
set(key, args); set(key.c_str(), args);
} }
bool bool
VariableMap::process_file(const std::string& path) { VariableMap::process_file(key_type path) {
std::fstream file(rak::path_expand(path).c_str(), std::ios::in); std::fstream file(rak::path_expand(path).c_str(), std::ios::in);
if (!file.is_open()) if (!file.is_open())
@@ -188,7 +188,7 @@ VariableMap::process_file(const std::string& path) {
} }
} catch (torrent::input_error& e) { } catch (torrent::input_error& e) {
snprintf(buffer, max_size_line, "Error in option file: %s:%i: %s", path.c_str(), lineNumber, e.what()); snprintf(buffer, max_size_line, "Error in option file: %s:%i: %s", path, lineNumber, e.what());
throw torrent::input_error(buffer); throw torrent::input_error(buffer);
} }
+23 -10
View File
@@ -39,16 +39,26 @@
#include <map> #include <map>
#include <string> #include <string>
#include <cstring>
#include <iosfwd> #include <iosfwd>
#include <torrent/object.h> #include <torrent/object.h>
namespace torrent {
class Object;
}
namespace utils { namespace utils {
struct variable_map_comp : public std::binary_function<const char*, const char*, bool> {
bool operator () (const char* arg1, const char* arg2) const { return std::strcmp(arg1, arg2) < 0; }
};
class Variable; class Variable;
class VariableMap : public std::map<std::string, Variable*> { class VariableMap : public std::map<const char*, Variable*, variable_map_comp> {
public: public:
typedef std::map<std::string, Variable*> base_type; typedef std::map<const char*, Variable*, variable_map_comp> base_type;
typedef torrent::Object mapped_type; typedef torrent::Object mapped_type;
typedef mapped_type::value_type mapped_value_type; typedef mapped_type::value_type mapped_value_type;
@@ -57,27 +67,30 @@ public:
static const int max_size_line = max_size_key + max_size_opt + 64; static const int max_size_line = max_size_key + max_size_opt + 64;
using base_type::iterator; using base_type::iterator;
using base_type::key_type;
using base_type::value_type; using base_type::value_type;
VariableMap() {} VariableMap() {}
~VariableMap(); ~VariableMap();
void insert(const std::string& key, Variable* v); void insert(key_type key, Variable* v);
// Consider taking char* start and finish instead of std::string to // Consider taking char* start and finish instead of std::string to
// avoid copying. Or make a view class. // avoid copying. Or make a view class.
const mapped_type& get(const std::string& key) const; const mapped_type& get(key_type key) const;
const std::string& get_string(const std::string& key) const { return get(key).as_string(); } const std::string& get_string(key_type key) const { return get(key).as_string(); }
mapped_value_type get_value(const std::string& key) const { return get(key).as_value(); } mapped_value_type get_value(key_type key) const { return get(key).as_value(); }
void set(const std::string& key, const mapped_type& arg); void set(key_type key, const mapped_type& arg);
void set_string(const std::string& key, const std::string& arg) { set(key, mapped_type(arg)); } void set_string(key_type key, const std::string& arg) { set(key, mapped_type(arg)); }
void set_value(const std::string& key, mapped_value_type arg) { set(key, mapped_type(arg)); } void set_value(key_type key, mapped_value_type arg) { set(key, mapped_type(arg)); }
void set_std_string(const std::string& key, const std::string& arg) { set(key.c_str(), mapped_type(arg)); }
// Relocate. // Relocate.
void process_command(const std::string& command); void process_command(const std::string& command);
void process_stream(std::istream* str); void process_stream(std::istream* str);
bool process_file(const std::string& path); bool process_file(key_type path);
private: private:
VariableMap(const VariableMap&); VariableMap(const VariableMap&);