* 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
+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();
}
}