Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Dig through git history, and update copyright lines.
[simgrid.git] / examples / msg / kademlia / routing_table.c
1 /* Copyright (c) 2012-2013. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6 #include "routing_table.h"
7 #include "node.h"
8 #include "msg/msg.h"
9 #include "xbt/log.h"
10 #include "xbt/asserts.h"
11 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_kademlia_routing_table,
12                              "Messages specific for this msg example");
13 /**
14   * \brief Initialization of a node routing table.
15   */
16 routing_table_t routing_table_init(unsigned int node_id)
17 {
18   unsigned int i;
19   routing_table_t table = xbt_new(s_routing_table_t, 1);
20   table->buckets = xbt_new(s_bucket_t, identifier_size + 1);
21   for (i = 0; i < identifier_size + 1; i++) {
22     table->buckets[i].nodes = xbt_dynar_new(sizeof(unsigned int), NULL);
23     table->buckets[i].id = i;
24   }
25   table->id = node_id;
26   return table;
27 }
28
29 /**
30   * \brief Frees the routing table
31   */
32 void routing_table_free(routing_table_t table)
33 {
34   unsigned int i;
35   //Free the buckets.
36   for (i = 0; i <= identifier_size; i++) {
37     xbt_dynar_free(&table->buckets[i].nodes);
38   }
39   xbt_free(table->buckets);
40   xbt_free(table);
41 }
42
43 /**
44   * Returns if the routing table contains the id.
45   */
46 unsigned int routing_table_contains(routing_table_t table, unsigned int node_id)
47 {
48   bucket_t bucket = routing_table_find_bucket(table, node_id);
49   return bucket_contains(bucket, node_id);
50 }
51
52 /**
53   * @brief prints the routing table, to debug stuff.
54   */
55 void routing_table_print(routing_table_t table)
56 {
57   unsigned int i, j, value;
58   XBT_INFO("Routing table of %08x:", table->id);
59
60   for (i = 0; i <= identifier_size; i++) {
61     if (!xbt_dynar_is_empty(table->buckets[i].nodes)) {
62       XBT_INFO("Bucket number %d: ", i);
63       xbt_dynar_foreach(table->buckets[i].nodes, j, value) {
64         XBT_INFO("Element %d: %08x", j, value);
65       }
66     }
67   }
68 }
69
70 /**
71   * Finds an identifier in a bucket and returns its position
72   * or returns -1 if it doesn't exists
73   * @param bucket the bucket in which we try to find our identifier
74   * @param id the id
75   */
76 unsigned int bucket_find_id(bucket_t bucket, unsigned int id)
77 {
78   unsigned int i, length = xbt_dynar_length(bucket->nodes);
79   for (i = 0; i < length; i++) {        //TODO: Use foreach maybe ?
80     if (id == xbt_dynar_get_as(bucket->nodes, i, unsigned int)) {
81       return i;
82     }
83   }
84   return -1;
85 }
86
87 /**
88   * Returns if the bucket contains an identifier.
89   */
90 unsigned int bucket_contains(bucket_t bucket, unsigned int id)
91 {
92   unsigned int length = xbt_dynar_length(bucket->nodes), i = 0;
93   for (i = 0; i < length; i++) {
94     if (id == xbt_dynar_get_as(bucket->nodes, i, unsigned int)) {
95       return 1;
96     }
97   }
98   return 0;
99 }
100
101 /**
102   * Fins the corresponding bucket in a routing table for a given identifier
103   * @param table the routing table
104   * @param id the identifier
105   * @return the bucket in which the the identifier would be.
106   */
107 bucket_t routing_table_find_bucket(routing_table_t table, unsigned int id)
108 {
109   unsigned int xor_number = table->id ^ id;
110   unsigned int prefix = get_node_prefix(xor_number, identifier_size);
111   xbt_assert(prefix >= 0
112              && prefix <= identifier_size,
113              "Tried to return a  bucket that doesn't exist.");
114   bucket_t bucket = &table->buckets[prefix];
115   return bucket;
116 }