PastryNeighborhoodSet.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 "PastryNeighborhoodSet.h"
00025 #include "PastryTypes.h"
00026 
00027 Define_Module(PastryNeighborhoodSet);
00028 
00029 void PastryNeighborhoodSet::earlyInit(void)
00030 {
00031     WATCH_VECTOR(neighbors);
00032 }
00033 
00034 void PastryNeighborhoodSet::initializeSet(uint32_t numberOfNeighbors,
00035                                           uint32_t bitsPerDigit,
00036                                           const NodeHandle& owner)
00037 {
00038     this->owner = owner;
00039     this->numberOfNeighbors = numberOfNeighbors;
00040     this->bitsPerDigit = bitsPerDigit;
00041 
00042     if (!neighbors.empty()) neighbors.clear();
00043 
00044     // fill Set with unspecified node handles
00045     for (uint32_t i = numberOfNeighbors; i>0; i--)
00046         neighbors.push_back(unspecNode());
00047 }
00048 
00049 void PastryNeighborhoodSet::dumpToStateMessage(PastryStateMessage* msg) const
00050 {
00051     uint32_t i = 0;
00052     uint32_t size = 0;
00053     std::vector<PastryExtendedNode>::const_iterator it;
00054 
00055     msg->setNeighborhoodSetArraySize(numberOfNeighbors);
00056     for (it = neighbors.begin(); it != neighbors.end(); it++) {
00057         if (!it->node.isUnspecified()) {
00058             ++size;
00059             msg->setNeighborhoodSet(i++, it->node);
00060         }
00061     }
00062     msg->setNeighborhoodSetArraySize(size);
00063 }
00064 
00065 const NodeHandle& PastryNeighborhoodSet::findCloserNode(const OverlayKey& destination,
00066                                                         bool optimize)
00067 {
00068     std::vector<PastryExtendedNode>::const_iterator it;
00069 
00070     if (optimize) {
00071         // pointer to later return value, initialize to unspecified, so
00072         // the specialCloserCondition() check will be done against our own
00073         // node as long as no node closer to the destination than our own was
00074         // found.
00075         const NodeHandle* ret = &NodeHandle::UNSPECIFIED_NODE;
00076 
00077         for (it = neighbors.begin(); it != neighbors.end(); it++) {
00078             if (it->node.isUnspecified()) break;
00079             if (specialCloserCondition(it->node, destination, *ret))
00080                 ret = &(it->node);
00081         }
00082         return *ret;
00083     } else {
00084         for (it = neighbors.begin(); it != neighbors.end(); it++) {
00085             if (it->node.isUnspecified()) break;
00086             if (specialCloserCondition(it->node, destination)) return it->node;
00087         }
00088         return NodeHandle::UNSPECIFIED_NODE;
00089     }
00090 }
00091 
00092 void PastryNeighborhoodSet::findCloserNodes(const OverlayKey& destination,
00093                                             NodeVector* nodes)
00094 {
00095     std::vector<PastryExtendedNode>::const_iterator it;
00096 
00097     for (it = neighbors.begin(); it != neighbors.end(); it++)
00098         if (! it->node.isUnspecified())
00099             nodes->add(it->node);
00100 }
00101 
00102 bool PastryNeighborhoodSet::mergeNode(const NodeHandle& node, simtime_t prox)
00103 {
00104     std::vector<PastryExtendedNode>::iterator it;
00105 
00106     bool nodeAlreadyInVector = false; // was the node already in the list?
00107     bool nodeValueWasChanged = false;  // true if the list was changed, false if the rtt was too big
00108     // look for node in the set, if it's there and the value was changed, erase it (since the position is no longer valid)
00109     for (it = neighbors.begin(); it != neighbors.end(); it++) {
00110         if (!it->node.isUnspecified() && it->node == node) {
00111             if (prox == SimTime::getMaxTime() || it->rtt == prox) return false; // nothing to do!
00112             neighbors.erase(it);
00113             nodeAlreadyInVector = true;
00114             break;
00115         }
00116     }
00117     // look for the correct position for the node
00118     for (it = neighbors.begin(); it != neighbors.end(); it++) {
00119         if (it->node.isUnspecified() || it->rtt > prox) {
00120             nodeValueWasChanged = true;
00121             break;
00122         }
00123     }
00124     neighbors.insert(it, PastryExtendedNode(node, prox)); // insert the entry there
00125     if (!nodeAlreadyInVector) neighbors.pop_back(); // if a new entry was inserted, erase the last entry
00126     return !nodeAlreadyInVector && nodeValueWasChanged; // return whether a new entry was added
00127 }
00128 
00129 void PastryNeighborhoodSet::dumpToVector(std::vector<TransportAddress>& affected) const
00130 {
00131     std::vector<PastryExtendedNode>::const_iterator it;
00132 
00133     for (it = neighbors.begin(); it != neighbors.end(); it++)
00134         if (! it->node.isUnspecified())
00135             affected.push_back(it->node);
00136 }
00137 
00138 const TransportAddress& PastryNeighborhoodSet::failedNode(const TransportAddress& failed)
00139 {
00140     std::vector<PastryExtendedNode>::iterator it;
00141 
00142     for (it = neighbors.begin(); it != neighbors.end(); it++) {
00143         if (it->node.isUnspecified()) break;
00144         if (it->node.getAddress() == failed.getAddress()) {
00145             neighbors.erase(it);
00146             neighbors.push_back(unspecNode());
00147             break;
00148         }
00149     }
00150 
00151     // never ask for repair
00152     return TransportAddress::UNSPECIFIED_NODE;
00153 }
00154 
00155 std::ostream& operator<<(std::ostream& os, const PastryExtendedNode& n)
00156 {
00157     os << n.node << ";";
00158     if (n.rtt != SimTime::getMaxTime())
00159         os << " Ping: " << n.rtt;
00160 
00161     return os;
00162 }
00163 

Generated on Tue Sep 8 17:26:53 2009 for OverSim by  doxygen 1.5.8