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