* Added 'method.rlookup' and 'method.rlookup.clear' commands for looking up the event handlers holding a specified key.

git-svn-id: svn://rakshasa.no/libtorrent/trunk/rtorrent@1231 e378c898-3ddf-0310-93e7-cc216c733640
This commit is contained in:
rakshasa
2011-05-26 03:38:45 +00:00
parent 5200454cf7
commit d2f328cc8e
7 changed files with 125 additions and 21 deletions
+1
View File
@@ -627,6 +627,7 @@ initialize_command_download() {
CMD2_DL_V ("d.pause", std::bind(&core::DownloadList::pause_default, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.open", std::bind(&core::DownloadList::open_throw, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.close", std::bind(&core::DownloadList::close_throw, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.close.directly", std::bind(&core::DownloadList::close_directly, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.erase", std::bind(&core::DownloadList::erase_ptr, control->core()->download_list(), std::placeholders::_1));
CMD2_DL_V ("d.check_hash", std::bind(&core::DownloadList::check_hash, control->core()->download_list(), std::placeholders::_1));
+14
View File
@@ -170,6 +170,15 @@ system_method_insert_object(const torrent::Object::list_type& args, int flags) {
cmd_flags, NULL, NULL);
}
// Not the right argument.
// if (flags & rpc::object_storage::flag_rlookup) {
// rpc::commands.insert_slot<rpc::command_base_is_type<rpc::command_base_call_string<rpc::target_type> >::type>
// (create_new_key<9>(rawKey, ".rlookup"),
// std::bind(&rpc::object_storage::rlookup_obj_list, control->object_storage(), rawKey),
// &rpc::command_base_call_string<rpc::target_type>,
// cmd_flags, NULL, NULL);
// }
// TODO: Next... Make test class for this.
// // Ehm... no proper handling if these throw.
@@ -254,6 +263,8 @@ system_method_insert(const torrent::Object::list_type& args) {
new_flags |= rpc::object_storage::flag_private;
if (options.find("const") != std::string::npos)
new_flags |= rpc::object_storage::flag_constant;
if (options.find("rlookup") != std::string::npos)
new_flags |= rpc::object_storage::flag_rlookup;
return system_method_insert_object(new_args, new_flags);
@@ -431,4 +442,7 @@ initialize_command_dynamic() {
CMD2_ANY_LIST ("method.has_key", std::bind(&system_method_has_key, std::placeholders::_2));
CMD2_ANY_LIST ("method.set_key", std::bind(&system_method_set_key, std::placeholders::_2));
CMD2_ANY_STRING ("method.list_keys", std::bind(&system_method_list_keys, std::placeholders::_2));
CMD2_ANY_STRING ("method.rlookup", std::bind(&rpc::object_storage::rlookup_obj_list, control->object_storage(), std::placeholders::_2));
CMD2_ANY_STRING_V("method.rlookup.clear", std::bind(&rpc::object_storage::rlookup_clear, control->object_storage(), std::placeholders::_2));
}
+14 -14
View File
@@ -217,21 +217,21 @@ main(int argc, char** argv) {
// "method.insert.simple = test.method.simple,((print,simple_test_,$argument.0=))\n"
// "method.insert.simple = test.method.double,((print,simple_test_,$argument.0=)),\"print=simple_test_,$argument.1=\"\n"
"method.insert = event.download.inserted,multi\n"
"method.insert = event.download.inserted_new,multi\n"
"method.insert = event.download.inserted_session,multi\n"
"method.insert = event.download.erased,multi\n"
"method.insert = event.download.opened,multi\n"
"method.insert = event.download.closed,multi\n"
"method.insert = event.download.resumed,multi\n"
"method.insert = event.download.paused,multi\n"
"method.insert = event.download.inserted,multi|rlookup|static\n"
"method.insert = event.download.inserted_new,multi|rlookup|static\n"
"method.insert = event.download.inserted_session,multi|rlookup|static\n"
"method.insert = event.download.erased,multi|rlookup|static\n"
"method.insert = event.download.opened,multi|rlookup|static\n"
"method.insert = event.download.closed,multi|rlookup|static\n"
"method.insert = event.download.resumed,multi|rlookup|static\n"
"method.insert = event.download.paused,multi|rlookup|static\n"
"method.insert = event.download.finished,multi\n"
"method.insert = event.download.hash_done,multi\n"
"method.insert = event.download.hash_failed,multi\n"
"method.insert = event.download.hash_final_failed,multi\n"
"method.insert = event.download.hash_removed,multi\n"
"method.insert = event.download.hash_queued,multi\n"
"method.insert = event.download.finished,multi|rlookup|static\n"
"method.insert = event.download.hash_done,multi|rlookup|static\n"
"method.insert = event.download.hash_failed,multi|rlookup|static\n"
"method.insert = event.download.hash_final_failed,multi|rlookup|static\n"
"method.insert = event.download.hash_removed,multi|rlookup|static\n"
"method.insert = event.download.hash_queued,multi|rlookup|static\n"
"method.set_key = event.download.inserted, 1_connect_logs, d.initialize_logs=\n"
"method.set_key = event.download.inserted_new, 1_prepare, \"branch=d.state=,view.set_visible=started,view.set_visible=stopped ;d.save_full_session=\"\n"
+8
View File
@@ -80,6 +80,9 @@ public:
bool operator == (const fixed_key_type& rhs) const { return m_size == rhs.m_size && std::memcmp(m_data, rhs.m_data, m_size) == 0; }
bool operator != (const fixed_key_type& rhs) const { return m_size != rhs.m_size || std::memcmp(m_data, rhs.m_data, m_size) != 0; }
bool operator == (const torrent::raw_string& rhs) const { return m_size == rhs.size() && std::memcmp(m_data, rhs.data(), m_size) == 0; }
bool operator != (const torrent::raw_string& rhs) const { return m_size != rhs.size() || std::memcmp(m_data, rhs.data(), m_size) != 0; }
bool operator == (const std::string& rhs) const { return m_size == rhs.size() && std::memcmp(m_data, rhs.data(), m_size) == 0; }
private:
@@ -110,6 +113,11 @@ struct hash_fixed_key_type {
}
};
template <size_t MaxSize>
bool operator == (const torrent::raw_string& lhs, const fixed_key_type<MaxSize>& rhs) {
return lhs.size() == rhs.size() && std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
}
}
#endif
+56
View File
@@ -38,6 +38,7 @@
#include "object_storage.h"
#include "rak/functional.h"
#include "parse.h"
#include "parse_commands.h"
@@ -77,6 +78,9 @@ object_storage::insert(const char* key_data, uint32_t key_size, const torrent::O
if (!(flags & mask_type))
throw torrent::input_error("No type flags set when calling object_storage::insert.");
if ((flags & flag_rlookup) && (!(flags & flag_static) || !(flags & flag_multi_type)))
throw torrent::input_error("Cannot insert non-static or non-multi-type object with rlookup enabled.");
std::pair<iterator, bool> result = base_type::insert(std::make_pair(key_type(key_data, key_size), object_storage_node()));
if (!result.second)
@@ -183,6 +187,21 @@ object_storage::erase_multi_key(const torrent::raw_string& key, const std::strin
return;
itr->second.object.erase_key(cmd_key);
if (!(itr->second.flags & flag_rlookup))
return;
// Remove the rlookup entry.
rlookup_iterator r_itr = m_rlookup.find(cmd_key);
if (r_itr == m_rlookup.end())
return;
rlookup_mapped_iterator rm_itr = std::find_if(r_itr->second.begin(), r_itr->second.end(),
rak::equal(key, rak::mem_ptr(&value_type::first)));
if (rm_itr != r_itr->second.end())
r_itr->second.erase(rm_itr);
}
void
@@ -192,7 +211,44 @@ object_storage::set_multi_key(const torrent::raw_string& key, const std::string&
if (itr == end(0) || (itr->second.flags & mask_type) != flag_multi_type)
throw torrent::input_error("Key not found or wrong type.");
if (itr->second.flags & flag_rlookup) {
rlookup_iterator r_itr = m_rlookup.find(cmd_key);
if (r_itr == m_rlookup.end())
r_itr = m_rlookup.insert(std::make_pair(cmd_key, rlookup_type::mapped_type())).first;
if (std::find_if(r_itr->second.begin(), r_itr->second.end(),
rak::equal(key, rak::mem_ptr(&value_type::first))) == r_itr->second.end())
r_itr->second.push_back(&*itr);
}
itr->second.object.insert_key(cmd_key, object);
}
torrent::Object::list_type
object_storage::rlookup_list(const std::string& cmd_key) {
torrent::Object::list_type result;
rlookup_iterator r_itr = m_rlookup.find(cmd_key);
if (r_itr != m_rlookup.end())
std::transform(r_itr->second.begin(), r_itr->second.end(), std::back_inserter(result),
std::bind(&key_type::c_str, std::bind(rak::mem_ptr(&value_type::first), std::placeholders::_1)));
return result;
}
void
object_storage::rlookup_clear(const std::string& cmd_key) {
rlookup_iterator r_itr = m_rlookup.find(cmd_key);
if (r_itr == m_rlookup.end())
return;
for (rlookup_mapped_iterator first = r_itr->second.begin(), last = r_itr->second.end(); first != last; first++)
(*first)->second.object.erase_key(cmd_key);
r_itr->second.clear();
}
}
+26 -7
View File
@@ -45,6 +45,7 @@
#include <tr1/unordered_map>
#include <torrent/object.h>
#include "rak/unordered_vector.h"
#include "command.h"
#include "fixed_key.h"
@@ -55,9 +56,13 @@ struct object_storage_node {
char flags;
};
class object_storage : private std::unordered_map<fixed_key_type<64>, object_storage_node, hash_fixed_key_type> {
typedef std::unordered_map<fixed_key_type<64>, object_storage_node, hash_fixed_key_type> object_storage_base_type;
class object_storage : private object_storage_base_type {
public:
typedef std::unordered_map<fixed_key_type<64>, object_storage_node, hash_fixed_key_type> base_type;
// Should really change rlookup_type into a set with pair values.
typedef object_storage_base_type base_type;
typedef std::map<std::string, rak::unordered_vector<base_type::value_type*> > rlookup_type;
using base_type::key_type;
using base_type::value_type;
@@ -66,6 +71,9 @@ public:
using base_type::local_iterator;
using base_type::const_local_iterator;
typedef rlookup_type::iterator rlookup_iterator;
typedef rlookup_type::mapped_type::iterator rlookup_mapped_iterator;
using base_type::begin;
using base_type::end;
using base_type::size;
@@ -76,6 +84,8 @@ public:
using base_type::max_bucket_count;
using base_type::load_factor;
// Verify rlookup is static / const.
using base_type::clear;
using base_type::find;
using base_type::erase;
@@ -90,9 +100,10 @@ public:
static const unsigned int mask_type = 0xf;
static const unsigned int flag_constant = 0x10;
static const unsigned int flag_static = 0x20;
static const unsigned int flag_private = 0x40;
static const unsigned int flag_constant = 0x10;
static const unsigned int flag_static = 0x20;
static const unsigned int flag_private = 0x40;
static const unsigned int flag_rlookup = 0x80;
static const size_t key_size = key_type::max_size;
@@ -128,8 +139,8 @@ public:
const torrent::Object& set_str_list(const std::string& str, const torrent::Object::list_type& object) { return set_list(torrent::raw_string::from_string(str), object); }
// Functions callers:
torrent::Object call_function(const torrent::raw_string& key, target_type target, const torrent::Object& object);
torrent::Object call_function_str(const std::string& key, target_type target, const torrent::Object& object);
torrent::Object call_function(const torrent::raw_string& key, target_type target, const torrent::Object& object);
torrent::Object call_function_str(const std::string& key, target_type target, const torrent::Object& object);
// Single-command function:
@@ -144,6 +155,14 @@ public:
bool has_str_multi_key(const std::string& key, const std::string& cmd_key);
void erase_str_multi_key(const std::string& key, const std::string& cmd_key);
void set_str_multi_key(const std::string& key, const std::string& cmd_key, const std::string& object);
torrent::Object::list_type rlookup_list(const std::string& cmd_key);
torrent::Object rlookup_obj_list(const std::string& cmd_key) { return torrent::Object::from_list(rlookup_list(cmd_key)); }
void rlookup_clear(const std::string& cmd_key);
private:
rlookup_type m_rlookup;
};
//
+6
View File
@@ -452,6 +452,9 @@ print_object(char* first, char* last, const torrent::Object* src, int flags) {
return std::min(first + snprintf(first, std::distance(first, last), "%lli", src->as_value()), last);
case torrent::Object::TYPE_LIST:
if (first != last)
*first = '\0';
for (torrent::Object::list_const_iterator itr = src->as_list().begin(), itrEnd = src->as_list().end(); itr != itrEnd; itr++) {
first = print_object(first, last, &*itr, flags);
@@ -462,6 +465,9 @@ print_object(char* first, char* last, const torrent::Object* src, int flags) {
return first;
case torrent::Object::TYPE_NONE:
if (first != last)
*first = '\0';
return first;
default:
throw torrent::input_error("Invalid type.");