Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Small cleanups in kademlia::Answer.
authorArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Thu, 2 Jan 2020 11:03:51 +0000 (12:03 +0100)
committerArnaud Giersch <arnaud.giersch@univ-fcomte.fr>
Thu, 2 Jan 2020 15:48:37 +0000 (16:48 +0100)
Make field nodes_ private; remove field size_.

examples/s4u/dht-kademlia/answer.cpp
examples/s4u/dht-kademlia/answer.hpp
examples/s4u/dht-kademlia/node.cpp

index 22e0eb9..7fa8655 100644 (file)
@@ -10,17 +10,12 @@ XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(kademlia_node);
 
 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);
 }
 
@@ -33,14 +28,12 @@ unsigned int Answer::merge(const Answer* source)
     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;
 }
@@ -48,22 +41,21 @@ unsigned int Answer::merge(const Answer* source)
 /** @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.
@@ -73,10 +65,9 @@ void Answer::addBucket(const Bucket* bucket)
 {
   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));
   }
 }
 }
index 7920e55..34896d6 100644 (file)
 #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);
 };
 }
index fa61fef..9b09d69 100644 (file)
@@ -44,7 +44,7 @@ bool Node::join(unsigned int known_id)
       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);
@@ -98,7 +98,7 @@ unsigned int Node::sendFindNodeToBest(const Answer* node_list)
   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 */
@@ -168,7 +168,6 @@ Answer* Node::findClosest(unsigned int destination_id)
     }
   }
   /* 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;
@@ -211,13 +210,13 @@ bool Node::findNode(unsigned int id_to_find, bool count_in_stats)
         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_);