Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix doxygen comments.
[simgrid.git] / examples / java / kademlia / RoutingTable.java
1 /* Copyright (c) 2012. 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 package kademlia;
7 import java.util.Collections;
8 import java.util.Vector;
9
10 import org.simgrid.msg.Msg;
11 /**
12  * @brief Contains the various data of a routing table.
13  */
14 public class RoutingTable {
15         /**
16          * Bucket list
17          */
18         private Vector<Bucket> buckets;
19         /**
20          * Id of the routing table owner
21          */
22         private int id;
23         /**
24          * Constructor
25          */
26         public RoutingTable(int id) {
27                 this.id = id;
28                 buckets = new Vector<Bucket>();
29                 for (int i = 0; i < Common.IDENTIFIER_SIZE + 1; i++) {
30                         buckets.add(new Bucket(i));
31                 }               
32         }
33         /**
34          * Returns an identifier which is in a specific bucket of a routing table
35          * @brief id id of the routing table owner
36          * @brief prefix id of the bucket where we want that identifier to be
37          */
38         public int getIdInPrefix(int id, int prefix) {
39                 if (prefix == 0) {
40                         return 0;
41                 }
42                 int identifier = 1;
43                 identifier = identifier << (prefix - 1);
44                 identifier = identifier ^ id;
45                 return identifier;
46         }
47         /**
48          * Returns the corresponding node prefix for a given id
49          */
50         public int getNodePrefix(int id) {
51                 for (int j = 0; j < 32; j++) {
52                         if ((id >> (32 - 1 - j) & 0x1) != 0) {
53                                 return 32 - j;
54                         }
55                 }
56                 return 0;
57         }
58         /**
59           * Fins the corresponding bucket in a routing table for a given identifier
60           */
61         public Bucket findBucket(int id) {
62                 int xorNumber = id ^ this.id;
63 //              Msg.info("Number:" + xorNumber.toString(16));
64                 int prefix = this.getNodePrefix(xorNumber);                             
65                 
66                 return buckets.get(prefix);
67         }
68         /**
69          * Updates the routing table with a new value.
70          */
71         public void update(int id) {
72
73                 Bucket bucket = this.findBucket(id);
74                 if (bucket.contains(id)) {
75                         Msg.debug("Updating " + Integer.toString(id) + " in my routing table");
76                         //If the element is already in the bucket, we update it.
77                         bucket.pushToFront(id);
78                 }
79                 else {
80                         Msg.debug("Adding " + id + " to my routing table");
81                         bucket.add(id);
82                         if (bucket.size() > Common.BUCKET_SIZE)  {
83                                 //TODO: Ping the least seen guy and remove him if he is offline.
84                         }
85                 }
86         }
87         /**
88          * Returns the closest notes we know to a given id 
89          */
90         public Answer findClosest(int destinationId) {
91                 Answer answer = new Answer(destinationId);
92
93                 
94                 Bucket bucket = this.findBucket(destinationId);
95                 bucket.addToAnswer(answer,destinationId);
96                 
97                 for (int i = 1; answer.size() < Common.BUCKET_SIZE && 
98                 ((bucket.getId() - i) >= 0 ||
99                 (bucket.getId() + i) <= Common.IDENTIFIER_SIZE); i++) {
100                         //Check the previous buckets
101                         if (bucket.getId() - i >= 0) {
102                                 Bucket bucketP = this.buckets.get(bucket.getId() - i);
103                                 bucketP.addToAnswer(answer,destinationId);
104                         }
105                         //Check the next buckets
106                         if (bucket.getId() + i <= Common.IDENTIFIER_SIZE) {
107                                 Bucket bucketN = this.buckets.get(bucket.getId() + i);
108                                 bucketN.addToAnswer(answer, destinationId);
109                         }
110                 }
111                 //We sort the list
112                 Collections.sort(answer.getNodes());
113                 //We trim the list
114                 while (answer.size() > Common.BUCKET_SIZE) {
115                         answer.remove(answer.size() - 1); //TODO: Not the best thing.
116                 }
117                 
118                 return answer;
119         }
120         
121         @Override
122         public String toString() {
123                 String string = "RoutingTable [ id=" + id + " " ;
124                 for (int i = 0; i < buckets.size(); i++) {
125                         if (buckets.get(i).size() > 0) {
126                                 string += buckets.get(i) + " ";
127                         }
128                 }
129                 return string;
130         }
131
132 }