Wiselib
wiselib.testing/algorithms/topology/cbtc/cbtc_topology_neighbours.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  ** This file is part of the generic algorithm library Wiselib.           **
00003  ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project.      **
00004  **                                                                       **
00005  ** The Wiselib is free software: you can redistribute it and/or modify   **
00006  ** it under the terms of the GNU Lesser General Public License as        **
00007  ** published by the Free Software Foundation, either version 3 of the    **
00008  ** License, or (at your option) any later version.                       **
00009  **                                                                       **
00010  ** The Wiselib is distributed in the hope that it will be useful,        **
00011  ** but WITHOUT ANY WARRANTY; without even the implied warranty of        **
00012  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         **
00013  ** GNU Lesser General Public License for more details.                   **
00014  **                                                                       **
00015  ** You should have received a copy of the GNU Lesser General Public      **
00016  ** License along with the Wiselib.                                       **
00017  ** If not, see <http://www.gnu.org/licenses/>.                           **
00018  ***************************************************************************/
00019 #ifndef __ALGORITHMS_TOPOLOGY_CBTC_TOPOLOGY_NEIGHBOURS_H__
00020 #define __ALGORITHMS_TOPOLOGY_CBTC_TOPOLOGY_NEIGHBOURS_H__
00021 
00022 #define DEBUG_CBTC_TOPOLOGY
00023 
00024 #include "util/pstl/vector_static.h"
00025 
00026 namespace wiselib
00027 {
00028    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00029    class CbtcTopologyNeighbours
00030    {
00031    public:
00032       typedef OsModel_P OsModel;
00033       typedef Radio_P Radio;
00034 #ifdef DEBUG_CBTC_TOPOLOGY
00035       typedef typename OsModel::Debug Debug;
00036 #endif
00037    
00038       typedef typename OsModel_P::size_t size_type;
00039 
00040       typedef typename Radio::node_id_t node_id_t;
00041       
00042       typedef struct triplet_t{
00043          double angle;
00044          node_id_t id;
00045          int power;
00046          bool asymmetric;
00047       } TIPA_t;
00048       
00049       typedef struct ndp_struct{
00050          node_id_t id;
00051          int power;
00052          bool first_time_seen;
00053          uint8_t ndp_counter;
00054       } ndp_t;
00055       
00056       typedef vector_static<OsModel, TIPA_t, MAX_NODES> Nodes;
00057       Nodes N;
00058       typedef normal_iterator<OsModel, TIPA_t*, Nodes> Niter;
00059       
00060       //Asymmetric Nodes to be removed
00061       vector_static<OsModel, node_id_t, MAX_NODES> ATR;
00062       vector_static<OsModel, ndp_t, MAX_NODES> NDP;
00063       
00064       bool first_phase_done;
00065       
00066       CbtcTopologyNeighbours();
00067       
00068       inline void set_id(node_id_t id) {id_ = id; }
00069       
00070       inline size_type size(){ return N.size(); }
00071       inline TIPA_t& operator[](size_type n) { return N[n];}
00072       
00073       void add_update_neighbour(node_id_t id, int p, double angle, bool asymmetric);
00074       inline void delete_by_id(node_id_t id);
00075       inline void delete_by_index(size_type index);
00076       bool add_update_ndp(node_id_t id, int p, double angle);
00077       bool ndp_update();
00078       
00079       inline void delete_by_power(int p){
00080          size_type i;
00081          for ( i = 0; i < N.size(); ++i ){
00082             if(N[i].power == p){
00083                delete_by_index(i);
00084                i--;
00085             }
00086          }
00087       }
00088       
00089       inline void add_asymmetric_to_remove(node_id_t from){
00090          size_type i;
00091          for(i = 0; i < ATR.size(); i++)
00092             if(ATR[i] == from)
00093                break;
00094          
00095          if(i == ATR.size())
00096             ATR.push_back(from);
00097       }
00098       
00099       inline void copy_to_NDP();
00100       
00101 #ifdef DEBUG_CBTC_TOPOLOGY
00102       inline void print_basic();
00103       inline void print_optimization(const char *s);
00104 #endif
00105       
00106    private:
00107       node_id_t id_;
00108    };
00109    
00110    // -----------------------------------------------------------------------
00111    // -----------------------------------------------------------------------
00112    // -----------------------------------------------------------------------
00113    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00114    CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>::
00115 	CbtcTopologyNeighbours()
00116    {
00117       first_phase_done = false;
00118    };
00119    
00120 
00121    // -----------------------------------------------------------------------
00122    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00123    void
00124    CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>::
00125 	add_update_neighbour(node_id_t id, int p, double angle, bool asymmetric){
00126       size_type i, j;
00127       
00128       if(first_phase_done){
00129          //Add it to NDP or update it if it's already there
00130          for ( i = 0; i < NDP.size(); ++i ){
00131             if(NDP[i].id == id) {
00132                NDP[i].first_time_seen = true;
00133                if(NDP[i].power > p) NDP[i].power = p;
00134             }
00135          }
00136          if(i == NDP.size()){
00137             ndp_t ndp;
00138             ndp.id = N[i].id;
00139             ndp.power = N[i].power;
00140             ndp.ndp_counter = 0;
00141             ndp.first_time_seen = true;
00142             NDP.push_back(ndp);
00143          }
00144       }
00145       
00146       
00147       //Remove from ATR if it's there and if now is symmetric
00148       if(!first_phase_done and !asymmetric){
00149          for ( i = 0; i < ATR.size(); ++i )
00150             if(ATR[i] == id)
00151                break;
00152          
00153          if(i < ATR.size()){
00154             for(; i < ATR.size() - 1; i++)
00155                ATR[i] = ATR[i+1];
00156          
00157             ATR.pop_back();
00158          }
00159       }
00160       
00161       //Update it in N
00162       //If we are in second phase just update don't add it to N if
00163       //it's not there
00164       for ( i = 0; i < N.size(); ++i ){
00165          if (N[i].id == id) {
00166             if (N[i].power >  p ) N[i].power = p;
00167             N[i].angle = angle;
00168             N[i].asymmetric = N[i].asymmetric && asymmetric;
00169             break;
00170          }
00171       }
00172       
00173       if(first_phase_done or i < N.size())
00174          return;
00175       
00176       //Add it to N (just if we are in first phase)
00177       TIPA_t t;
00178       t.id = id;
00179       t.power = p;
00180       t.angle = angle;
00181       t.asymmetric = asymmetric;
00182       
00183       for ( i = 0; i < N.size(); ++i ){
00184          if (angle < N[i].angle) {
00185             N.push_back(t);
00186             
00187             for(j = N.size() - 1; j > i; j--){
00188                N[j] = N[j-1];
00189             }
00190             N[i] = t;
00191             return;
00192          }
00193       }
00194       
00195       N.push_back(t);
00196    }
00197    
00198    
00199    // -----------------------------------------------------------------------
00200    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00201    inline void 
00202    CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>::
00203 	delete_by_id(node_id_t id){
00204       size_type i;
00205       
00206       for( i = 0; i < N.size(); i++) 
00207          if(N[i].id == id)
00208             break;
00209       
00210       for(; i < N.size() - 1; i++) 
00211          N[i] = N[i+1];
00212          
00213       N.pop_back();
00214    }
00215    
00216    // -----------------------------------------------------------------------
00217    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00218    inline void 
00219    CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>::
00220 	delete_by_index(size_type index){
00221       size_type i;
00222       
00223       for(i = index; i < N.size() - 1; i++) 
00224          N[i] = N[i+1];
00225          
00226       N.pop_back();
00227    }
00228    
00229    // -----------------------------------------------------------------------
00230    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00231    inline void 
00232    CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>::
00233 	copy_to_NDP(){
00234       size_type i;
00235       ndp_t ndp;
00236       for(i = 0; i < N.size(); i++){
00237          ndp.id = N[i].id;
00238          ndp.power = N[i].power;
00239          ndp.ndp_counter = 0;
00240          ndp.first_time_seen = true;
00241          NDP.push_back(ndp);
00242       }
00243    }
00244    
00245    // -----------------------------------------------------------------------
00246    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00247    bool
00248    CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>::
00249 	add_update_ndp(node_id_t id, int p, double angle){
00250       size_type i, j;
00251       ndp_t ndp;
00252       bool has_to_check_gap = false;
00253       
00254       //Update it in NDP
00255       for(i = 0; i < NDP.size(); i++){
00256          if(id == NDP[i].id){
00257             NDP[i].ndp_counter += 1;
00258             break;
00259          }
00260       }
00261       
00262       //If it's not in NDP add it
00263       if(i == NDP.size()){
00264          ndp.id = id;
00265          ndp.power = p;
00266          ndp.ndp_counter = 0;
00267          ndp.first_time_seen = true;
00268          NDP.push_back(ndp);
00269       }
00270       
00271       //Update it in N
00272       for(j = 0; j < N.size(); j++){
00273          if(id == N[j].id){
00274             if(N[j].angle != angle)
00275                has_to_check_gap = true;
00276             N[j].angle = angle;
00277             break;
00278          }
00279       }
00280       
00281       //If it's not in N add it sorted
00282       if(j == N.size()){
00283          TIPA_t t;
00284          t.id = id;
00285          t.power = NDP[i].power;
00286          t.angle = angle;
00287          t.asymmetric = false;
00288 
00289          Niter it;
00290          
00291          for(it = N.begin(); it != N.end(); it++){
00292             if(angle < (*it).angle){
00293                N.insert(it, t);
00294                break;
00295             }
00296          }
00297          if(it == N.end()){
00298             N.push_back(t);
00299          }
00300       }
00301 
00302       return has_to_check_gap;
00303    }
00304    
00305    // -----------------------------------------------------------------------
00306    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00307    bool
00308    CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>::
00309 	ndp_update(){
00310       size_type i, j;
00311       bool check_for_gap = false;
00312       node_id_t id;
00313       
00314       for(i = 0; i < NDP.size(); i++){
00315          if(NDP[i].first_time_seen){
00316             NDP[i].first_time_seen = false;
00317             NDP[i].ndp_counter = 0;
00318          } else {
00319             if(NDP[i].ndp_counter) {
00320                NDP[i].ndp_counter = 0;
00321             } else {
00322                id = NDP[i].id;
00323                for(j = i; j < NDP.size() - 1; j++) {
00324                   NDP[j] = NDP[j+1];
00325                }
00326                NDP.pop_back();
00327                for(j = 0; j < N.size(); j++){
00328                   if(N[j].id == id) {
00329                      check_for_gap = true;
00330                      delete_by_index(j);
00331                      break;
00332                   }
00333                }
00334             }
00335          }
00336       }
00337       
00338       return check_for_gap;
00339    }
00340 
00341 
00342 #ifdef DEBUG_CBTC_TOPOLOGY
00343    // -----------------------------------------------------------------------
00344    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00345    inline void 
00346    CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>::
00347 	print_basic(){
00348       size_type i;
00349       char nodes[MAX_NODES*7+1];
00350       int n = 0;
00351 
00352       for ( i = 0; i < N.size(); ++i )
00353          n += snprintf(nodes + n, 7, "%5i ", N[i].id );
00354       //Debug::debug( os(), "%i: Nodes[Firstphase]: %s\n", id_, nodes );
00355       
00356       n = 0;
00357       for ( i = 0; i < N.size(); ++i )
00358          n += sprintf(nodes + n, "%5.2f ", N[i].angle );
00359       //Debug::debug( os(), "%i: Nodes[Angles]:     %s\n", id_, nodes );
00360       
00361       n = 0;
00362       for ( i = 0; i < N.size(); ++i )
00363          n += sprintf(nodes + n, "%5i ", N[i].power );
00364       //Debug::debug( os(), "%i: Nodes[Powers]:     %s\n", id_, nodes );
00365       
00366       n = 0;
00367       for ( i = 0; i < N.size(); ++i )
00368          n += sprintf(nodes + n, "%s ", N[i].asymmetric? "  yes": "   no");
00369       //Debug::debug( os(), "%i: Nodes[asymmetry]:  %s\n", id_, nodes );
00370    }
00371 
00372    // -----------------------------------------------------------------------
00373    template<typename OsModel_P, typename Radio_P, uint16_t MAX_NODES>
00374    inline void 
00375    CbtcTopologyNeighbours<OsModel_P, Radio_P, MAX_NODES>::
00376 	print_optimization(const char *s){
00377       size_type i;
00378       char nodes[MAX_NODES*7+1];
00379       int n = 0;
00380       
00381       for ( i = 0; i < N.size(); ++i )
00382          n += snprintf(nodes + n, 7, "%5i ", N[i].id );
00383       //Debug::debug( os(), "%i: %s %s\n", id_, s, nodes );
00384    }
00385 #endif
00386 
00387 }
00388 
00389 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines