Wiselib
wiselib.testing/algorithms/cluster/modules/chd/maxmind_chd.h
Go to the documentation of this file.
00001 /*
00002  * File:   maxmind_chd.h
00003  * Author: Amaxilatis
00004  */
00005 
00006 #ifndef __MAXMIND_CLUSTER_HEAD_DECISION_H_
00007 #define __MAXMIND_CLUSTER_HEAD_DECISION_H_
00008 
00009 #include "util/delegates/delegate.hpp"
00010 
00011 
00012 namespace wiselib {
00018     template<    typename OsModel_P    >
00019     class MaxmindClusterHeadDecision {
00020     public:
00021 
00022 
00023         //TYPEDEFS
00024         typedef OsModel_P OsModel;
00025         typedef typename OsModel::Radio Radio;
00026         typedef typename OsModel::Debug Debug;
00027 
00028         //DATA TYPES
00029         typedef int cluster_id_t;
00030         typedef typename Radio::node_id_t node_id_t;
00031 
00032 
00033         //delegate
00034         typedef delegate1<void, node_id_t*> chd_delegate_t;
00035         
00036         /*
00037          * Constructor
00038          * */
00039         MaxmindClusterHeadDecision() :
00040         d_(0), // Maxmind Parameter
00041         id_(-1),
00042         cluster_id_(-1),
00043         parent_(-1),
00044         cluster_head_(false) {
00045 
00046         };
00047 
00048         /*
00049          * Destructor
00050          * */
00051         ~MaxmindClusterHeadDecision() {
00052         };
00053 
00054         /*
00055          * INIT
00056          * initializes the values of radio timer and debug
00057          */
00058         void init(Radio& radio, Debug & debug) {
00059             radio_ = &radio;
00060             debug_ = &debug;
00061         };
00062 
00063 
00064         /*
00065          * Calculates if node is a Cluster Head
00066          * Returns   True: if a cluster_head
00067          *     False: if not cluster_head
00068          * */
00069         bool calculate_head() {
00070 
00071             // winner and sender arrays
00072 
00073             node_id_t local_winner_[2 * d_];
00074             winner_ = local_winner_;
00075             node_id_t local_sender_[2 * d_];
00076             sender_ = local_sender_;
00077 
00078             bool decided = false;
00079 
00080             // get the winner adn sender arrays from join decision
00081             winner_callback_(winner_);
00082             sender_callback_(sender_);
00083 
00084 #ifdef DEBUG
00085             // print the arrays for debuging
00086             debug().debug("CHD(%x) is now deciding\n winner[", id_);
00087             // print the winner array
00088             for (int i = 0; i < 2 * d_; i++) {
00089                 if (i == d_) debug().debug("|");
00090                 debug().debug("%x ", winner_[i]);
00091             }
00092             debug().debug("]\n sender[");
00093             // print the sender array
00094             for (int i = 0; i < 2 * d_; i++) {
00095                 if (i == d_) debug().debug("|");
00096                 debug().debug("%x ", sender_[i]);
00097             }
00098             debug().debug("]\n");
00099 #endif
00100             // RULE_1 of MAXMIND
00101             // check if received own id in the second d rounds of flooding (RULE_1)
00102             if (!decided) {
00103                 // check all the second d values of the winner list for my id_
00104                 // [ - - - - - - | C C C C C C ]
00105                 for (int i = d_; i < 2 * d_; i++) {
00106                     // if you find your id then you are cluster_head (RULE_1)
00107                     if (winner_[i] == id_) {
00108                         // set myself as cluster_head_
00109                         cluster_head_ = true;
00110                         // set my cluster_id_to my id
00111                         cluster_id_ = id_;
00112                         // set my parent_ to -1 , as i am cluster_head
00113                         parent_ = id_;
00114                         // set as decided
00115                         decided = true;
00116 #ifdef DEBUG
00117                         debug().debug("%x now is head (Rule1)\n", id_);
00118                         debug().debug("checking rule 2\n");
00119 #endif
00120 
00121 
00122 
00123 
00124                         break;
00125                     }
00126                 }
00127             }
00128             // RULE_2 of MAXMIND
00129             // check if a node pair exists in the winner list (RULE_2)
00130             if (!decided) {
00131 
00132                 // check all the first d values of the winner list for a pair with the second d values
00133                 // [ A - B - C - D - E | a - b - c - d - e ]
00134                 // if node pairs were found : true else false
00135                 bool found = false;
00136                 // contains the pair id and the node currently checked
00137                 int pair = -1, node;
00138                 // contains my parent_if a pair was found
00139                 int parent_node = sender_[0];
00140                 // check all nodes of the first d rounds for their possible pair
00141                 for (int i = 0; i < d_; i++) {
00142                     node = winner_[i];
00143 
00144                     // for each node in the first d rounds check second d rounds for pair
00145                     for (int j = d_; j < 2 * d_; j++) {
00146                         // if a pair exists
00147 
00148                         if (node == winner_[j]) {
00149                             // if not the first pair
00150                             if (found) {
00151                                 // keep only the minimum pair
00152                                 if (node < pair) {
00153                                     // if the minimum pair so far
00154                                     pair = node;
00155                                     // find the sender closer to my pair
00156                                     // the first node i received the pair id from is my parent
00157                                     for (int l = 0; l < 2 * d_; l++) {
00158                                         if (winner_[l] == node) {
00159                                             parent_node = sender_[l];
00160                                             break;
00161                                         }
00162 
00163                                     }
00164 
00165 
00166                                 }
00167                             }// if the first pair keep it imediately
00168                             else {
00169                                 pair = node;
00170                                 // find the sender closer to my pair
00171                                 // the first node i received the pair id from is my parent
00172                                 for (int l = 0; l < 2 * d_; l++) {
00173                                     if (winner_[l] == node) {
00174                                         parent_node = sender_[l];
00175                                         break;
00176                                     }
00177 
00178                                 }
00179 
00180 
00181 
00182                                 // now i have a pair value , avoid nulls- memory faults
00183                                 found = true;
00184                             }
00185                         }
00186                     }
00187                 }
00188                 // if found any pairs elect its node id as cluster_head
00189                 if (found) {
00190                     // set as decided for cluster_head
00191                     decided = true;
00192                     // set as not cluster_head
00193                     cluster_head_ = false;
00194                     // save the cluster_id
00195                     cluster_id_ = pair;
00196                     // set my parent_as the parent_node calculated above
00197                     parent_ = parent_node;
00198 #ifdef DEBUG
00199                     debug().debug("%x has now head %x and parent %x (Rule2)\n", id_, cluster_id_, parent_);
00200 #endif
00201                 }
00202             }
00203             // RULE_3 of MAXMIND
00204             // check and find the max value of the first d rounds as cluster_head (RULE_3)
00205             if (!decided) {
00206                 // check all the first d values of the winner list for the maximum node_id
00207                 // [ C C C C C | - - - - - ]
00208                 cluster_id_ = winner_[0];
00209                 parent_ = sender_[0];
00210                 for (int i = 0; i < d_; i++) {
00211                     // find the max of the winner list
00212                     if (winner_[i] > cluster_id_) {
00213                         cluster_id_ = winner_[i];
00214                         for (int l = 0; l < 2 * d_; l++) {
00215                             // find the sender closer to my pair
00216                             // the first node i received the pair id from is my parent
00217                             if (winner_[l] == cluster_id_) {
00218                                 parent_ = sender_[l];
00219                                 break;
00220                             }
00221                         }
00222                     }
00223                 }
00224                 // set as decided for cluster_head
00225                 decided = true;
00226                 // set the cluster_head (not sure if head here)
00227                 if (cluster_id_ != id_) {
00228 #ifdef DEBUG
00229                     debug().debug("%x has now head %x and parent %x (Rule3)\n", id_, cluster_id_, parent_);
00230 #endif
00231                     cluster_head_ = false;
00232                 } else {
00233 #ifdef DEBUG
00234                     debug().debug("%x now is head (Rule3)", id_);
00235 #endif
00236                     cluster_head_ = true;
00237                 }
00238             }
00239 
00240 #ifdef DEBUG
00241             debug().debug("%x cluster head decided\n", id_);
00242 #endif
00243 
00244             return cluster_head_;
00245         };
00246 
00247 
00248         // Returns if Cluster Head
00249 
00250         bool is_cluster_head(void) {
00251             return cluster_head_;
00252         };
00253 
00254         cluster_id_t cluster_id() {
00255             return cluster_id_;
00256         }
00257 
00258         node_id_t parent() {
00259             return parent_;
00260         }
00261 
00262         // Set the theta value
00263 
00264         void set_theta(int theta) {
00265             d_ = theta;
00266 
00267         };
00268 
00269         // Set my id
00270 
00271         void set_id(node_id_t id) {
00272             id_ = id;
00273         };
00274 
00275         // winner callback
00276 
00277         template<class T, void (T::*TMethod)(node_id_t*) >
00278         inline int reg_winner_callback(T * obj_pnt) {
00279             winner_callback_ = chd_delegate_t::template from_method<T, TMethod > (obj_pnt);
00280             return winner_callback_;
00281         };
00282 
00283         void unreg_winner_callback(int idx) {
00284             winner_callback_ = chd_delegate_t();
00285         };
00286 
00287         // winner callback
00288 
00289         template<class T, void (T::*TMethod)(node_id_t*) >
00290         inline int reg_sender_callback(T * obj_pnt) {
00291             sender_callback_ = chd_delegate_t::template from_method<T, TMethod > (obj_pnt);
00292             return sender_callback_;
00293         };
00294 
00295         void unreg_sender_callback(int idx) {
00296             sender_callback_ = chd_delegate_t();
00297         };
00298 
00299         void enable() {
00300             d_ = 0;
00301             id_ = -1;
00302             cluster_id_ = -1;
00303             parent_ = -1;
00304             cluster_head_ = false;
00305         }
00306 
00307 
00308 
00309     private:
00310         // winner list
00311         node_id_t * winner_;
00312         // sender list
00313         node_id_t * sender_;
00314         // d range
00315         int d_;
00316         // node id
00317         node_id_t id_;
00318         cluster_id_t cluster_id_;
00319         node_id_t parent_;
00320         // is cluster head?
00321         bool cluster_head_;
00322 
00323         // delegate for callbacks
00324         chd_delegate_t winner_callback_;
00325         chd_delegate_t sender_callback_;
00326 
00327 
00328         Radio * radio_;
00329 
00330         Radio & radio() {
00331             return *radio_;
00332         }
00333         Debug * debug_;
00334 
00335         Debug & debug() {
00336             return *debug_;
00337         }
00338     };
00339 
00340 }
00341 
00342 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines