namespace kademlia {
-bool sortbydistance(const std::pair<unsigned int, unsigned int>& a, const std::pair<unsigned int, unsigned int>& b)
-{
- return (a.second < b.second);
-}
-
/** @brief Prints a answer_t, for debugging purposes */
void Answer::print()
{
- XBT_INFO("Searching %08x, size %u", destination_id_, size_);
+ XBT_INFO("Searching %08x, size %zu", destination_id_, nodes_.size());
unsigned int i = 0;
- for (auto contact : nodes)
+ for (auto const& contact : nodes_)
XBT_INFO("Node %08x: %08x is at distance %u", i++, contact.first, contact.second);
}
return 0;
unsigned int nb_added = 0;
- for (auto contact : source->nodes) {
- if (std::find(nodes.begin(), nodes.end(), contact) == nodes.end()) {
- nodes.push_back(contact);
- size_++;
+ for (auto const& contact : source->nodes_) {
+ if (std::find(nodes_.begin(), nodes_.end(), contact) == nodes_.end()) {
+ nodes_.push_back(contact);
nb_added++;
}
}
- std::sort(nodes.begin(), nodes.end(), sortbydistance);
trim();
return nb_added;
}
/** @brief Trims an Answer, in order for it to have a size of less or equal to "bucket_size" */
void Answer::trim()
{
- while (size_ > BUCKET_SIZE) {
- nodes.pop_back();
- size_--;
- }
- xbt_assert(nodes.size() == size_, "Wrong size for the answer");
+ // sort by distance
+ std::sort(nodes_.begin(), nodes_.end(),
+ [](const std::pair<unsigned int, unsigned int>& a, const std::pair<unsigned int, unsigned int>& b) {
+ return (a.second < b.second);
+ });
+ if (nodes_.size() > BUCKET_SIZE)
+ nodes_.resize(BUCKET_SIZE);
}
/** @brief Returns if the destination we are trying to find is found
* @return if the destination is found.
*/
-bool Answer::destinationFound()
+bool Answer::destinationFound() const
{
- if (nodes.empty())
- return 0;
-
- return (*nodes.begin()).second == 0;
+ return not nodes_.empty() && nodes_.begin()->second == 0;
}
/** @brief Adds the content of a bucket unsigned into a answer object.
{
xbt_assert((bucket != nullptr), "Provided a NULL bucket");
- for (auto id : bucket->nodes) {
+ for (auto const& id : bucket->nodes) {
unsigned int distance = id ^ destination_id_;
- nodes.push_back(std::pair<unsigned int, unsigned int>(id, distance));
- size_++;
+ nodes_.push_back(std::pair<unsigned int, unsigned int>(id, distance));
}
}
}
#include <set>
namespace kademlia {
-bool sortbydistance(const std::pair<unsigned int, unsigned int>& a, const std::pair<unsigned int, unsigned int>& b);
-
/* Node query answer. contains the elements closest to the id given. */
class Answer {
unsigned int destination_id_;
- unsigned int size_ = 0;
+ std::vector<std::pair<unsigned int, unsigned int>> nodes_;
public:
- std::vector<std::pair<unsigned int, unsigned int>> nodes;
explicit Answer(unsigned int destination_id) : destination_id_(destination_id) {}
virtual ~Answer() = default;
unsigned int getDestinationId() const { return destination_id_; }
- unsigned int getSize() { return size_; }
+ size_t getSize() const { return nodes_.size(); }
+ const std::vector<std::pair<unsigned int, unsigned int>>& getNodes() const { return nodes_; }
void print();
unsigned int merge(const Answer* a);
void trim();
- bool destinationFound();
+ bool destinationFound() const;
void addBucket(const kademlia::Bucket* bucket);
};
}
const Message* msg = static_cast<Message*>(received_msg);
node_list = msg->answer_;
if (node_list) {
- for (auto contact : node_list->nodes)
+ for (auto const& contact : node_list->getNodes())
routingTableUpdate(contact.first);
} else {
handleFindNode(msg);
unsigned int i = 0;
unsigned int j = 0;
unsigned int destination = node_list->getDestinationId();
- for (auto node_to_query : node_list->nodes) {
+ for (auto const& node_to_query : node_list->getNodes()) {
/* We need to have at most "KADEMLIA_ALPHA" requests each time, according to the protocol */
/* Gets the node we want to send the query to */
if (node_to_query.first != id_) { /* No need to query ourselves */
}
}
/* We trim the array to have only BUCKET_SIZE or less elements */
- std::sort(answer->nodes.begin(), answer->nodes.end(), sortbydistance);
answer->trim();
return answer;
if (msg->answer_ && msg->answer_->getDestinationId() == id_to_find) {
routingTableUpdate(msg->sender_id_);
// Handle the answer
- for (auto contact : node_list->nodes)
+ for (auto const& contact : node_list->getNodes())
routingTableUpdate(contact.first);
answers++;
nodes_added = node_list->merge(msg->answer_);
XBT_DEBUG("Received an answer from %s (%s) with %zu nodes on it", msg->answer_to_->get_cname(),
- msg->issuer_host_name_.c_str(), msg->answer_->nodes.size());
+ msg->issuer_host_name_.c_str(), msg->answer_->getSize());
} else {
if (msg->answer_) {
routingTableUpdate(msg->sender_id_);