PastryStateObject.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00024 #include <InitStages.h>
00025 
00026 #include "PastryStateObject.h"
00027 #include "PastryTypes.h"
00028 
00029 const PastryExtendedNode* PastryStateObject::_unspecNode = NULL;
00030 
00031 int PastryStateObject::numInitStages() const
00032 {
00033     return MAX_STAGE_OVERLAY;
00034 }
00035 
00036 void PastryStateObject::initialize(int stage)
00037 {
00038     if (stage != MIN_STAGE_OVERLAY)
00039         return;
00040     earlyInit();
00041 }
00042 
00043 void PastryStateObject::handleMessage(cMessage* msg)
00044 {
00045     throw "a PastryStateObject should never receive a message.";
00046 }
00047 
00048 const NodeHandle& PastryStateObject::getDestinationNode(const OverlayKey&
00049                                                             destination)
00050 {
00051     return NodeHandle::UNSPECIFIED_NODE;
00052 }
00053 
00054 const TransportAddress& PastryStateObject::repair(const PastryStateMessage* msg,
00055                                                   const PastryStateMsgProximity&
00056                                                       prox)
00057 {
00058     return TransportAddress::UNSPECIFIED_NODE;
00059 }
00060 
00061 bool PastryStateObject::mergeState(const PastryStateMessage* msg,
00062                                    const PastryStateMsgProximity* prox)
00063 {
00064     bool ret = false;
00065     int lsSize = msg->getLeafSetArraySize();
00066     int rtSize = msg->getRoutingTableArraySize();
00067     int nsSize = msg->getNeighborhoodSetArraySize();
00068     const NodeHandle* node;
00069     simtime_t rtt;
00070 
00071     // walk through msg's LeafSet
00072     for (int i = 0; i < lsSize; i++) {
00073         node = &(msg->getLeafSet(i));
00074         rtt = prox ? (*(prox->pr_ls.begin() + i)) : SimTime::getMaxTime();
00075 
00076         // unspecified nodes, own node and dead nodes not considered
00077         if (!(rtt < 0 || node->isUnspecified() || *node == owner)) {
00078             if (mergeNode(*node, rtt)) ret = true;
00079         }
00080     }
00081 
00082     // walk through msg's IRoutingTable
00083     for (int i = 0; i < rtSize; i++) {
00084         node = &(msg->getRoutingTable(i));
00085         rtt = prox ? (*(prox->pr_rt.begin() + i)) : SimTime::getMaxTime();
00086 
00087         // unspecified nodes, own node and dead nodes not considered
00088         if (!(rtt < 0 || node->isUnspecified() || *node == owner)) {
00089             if (mergeNode(*node, rtt)) ret = true;
00090         }
00091     }
00092 
00093     // walk through msg's NeighborhoodSet
00094     for (int i = 0; i < nsSize; i++) {
00095         node = &(msg->getNeighborhoodSet(i));
00096         rtt = prox ? (*(prox->pr_ns.begin() + i)) : SimTime::getMaxTime();
00097 
00098         // unspecified nodes, own node and dead nodes not considered
00099         if (!(rtt < 0 || node->isUnspecified() || *node == owner)) {
00100             if (mergeNode(*node, rtt)) ret = true;
00101         }
00102     }
00103 
00104     return ret;
00105 }
00106 
00107 const OverlayKey* PastryStateObject::keyDist(const OverlayKey& a,
00108                                              const OverlayKey& b) const
00109 {
00110     const OverlayKey* smaller;
00111     const OverlayKey* bigger;
00112 
00113     if (a > b) {
00114         smaller = &b;
00115         bigger = &a;
00116     } else {
00117         smaller = &a;
00118         bigger = &b;
00119     }
00120 
00121     OverlayKey diff1(*bigger - *smaller);
00122     OverlayKey diff2(*smaller + (OverlayKey::getMax() - *bigger) + 1);
00123 
00124     const OverlayKey* dist;
00125     if (diff1 > diff2) {
00126         dist = new OverlayKey(diff2);
00127     } else {
00128         dist = new OverlayKey(diff1);
00129     }
00130 
00131     return dist;
00132 }
00133 
00134 bool PastryStateObject::isCloser(const NodeHandle& test,
00135                                  const OverlayKey& destination,
00136                                  const NodeHandle& reference) const
00137 {
00138     // assert: (! test.isUnspecified()) && (! owner.isUnspecified())
00139 
00140     const NodeHandle* ref = &reference;
00141     if (ref->isUnspecified()) ref = &owner;
00142 
00143     if ((ref->getKey() == destination) || (test == *ref)) {
00144         return false;
00145     }
00146 
00147     bool closer = false;
00148     const OverlayKey* refDist = keyDist(ref->getKey(), destination);
00149     const OverlayKey* testDist = keyDist(test.getKey(), destination);
00150     if (*testDist < *refDist)
00151         closer = true;
00152     delete refDist;
00153     delete testDist;
00154     return closer;
00155 }
00156 
00157 bool PastryStateObject::specialCloserCondition(const NodeHandle& test,
00158                                                const OverlayKey& destination,
00159                                                const NodeHandle& reference)
00160                                                const
00161 {
00162 //    std::cout << ((test.getKey().sharedPrefixLength(destination, bitsPerDigit)
00163 //                  < owner.getKey().sharedPrefixLength(destination, bitsPerDigit))
00164 //                  != (test.getKey().sharedPrefixLength(destination)
00165 //                      < owner.getKey().sharedPrefixLength(destination)) ? "X\n" : "");
00166 
00167     if (test.getKey().sharedPrefixLength(destination, bitsPerDigit)
00168             < owner.getKey().sharedPrefixLength(destination, bitsPerDigit)) {
00169         return false;
00170     }
00171 
00172     return isCloser(test, destination, reference);
00173 }
Generated on Wed May 26 16:21:14 2010 for OverSim by  doxygen 1.6.3