1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
/* Copyright (c) 2012-2025. The SimGrid Team. All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "answer.hpp"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(kademlia_node);
namespace kademlia {
/** @brief Prints an Answer, for debugging purposes */
void Answer::print() const
{
XBT_INFO("Searching %08x, size %zu", destination_id_, nodes_.size());
unsigned int i = 0;
for (auto const& [contact, distance] : nodes_)
XBT_INFO("Node %08x: %08x is at distance %u", i++, contact, distance);
}
/** @brief Merge two answers together, only keeping the best nodes
* @param source the source of the nodes to add
*/
unsigned int Answer::merge(const Answer* source)
{
if (this == source)
return 0;
unsigned int nb_added = 0;
for (auto const& contact : source->nodes_) {
if (std::find(nodes_.begin(), nodes_.end(), contact) == nodes_.end()) {
nodes_.push_back(contact);
nb_added++;
}
}
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()
{
// 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() const
{
return not nodes_.empty() && nodes_.begin()->second == 0;
}
/** @brief Adds the content of a bucket unsigned into an answer object.
* @param bucket the bucket we have to had unsigned into
*/
void Answer::addBucket(const Bucket* bucket)
{
xbt_assert((bucket != nullptr), "Provided a NULL bucket");
for (auto const& id : bucket->nodes_) {
unsigned int distance = id ^ destination_id_;
nodes_.emplace_back(id, distance);
}
}
} // namespace kademlia
|