ChordSuccessorList.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 <cassert>
00025 
00026 #include "ChordSuccessorList.h"
00027 
00028 #include "Chord.h"
00029 
00030 namespace oversim {
00031 
00032 Define_Module(ChordSuccessorList);
00033 
00034 using namespace std;
00035 
00036 std::ostream& operator<<(std::ostream& os, const SuccessorListEntry& e)
00037 {
00038     os << e.nodeHandle << " " << e.newEntry;
00039     return os;
00040 };
00041 
00042 void ChordSuccessorList::initialize(int stage)
00043 {
00044     // because of IPAddressResolver, we need to wait until interfaces
00045     // are registered, address auto-assignment takes place etc.
00046     if (stage != MIN_STAGE_OVERLAY)
00047         return;
00048 
00049     WATCH_MAP(successorMap);
00050 }
00051 
00052 void ChordSuccessorList::handleMessage(cMessage* msg)
00053 {
00054     error("this module doesn't handle messages, it runs only in initialize()");
00055 }
00056 
00057 void ChordSuccessorList::initializeList(uint32_t size, NodeHandle owner,
00058                                         Chord *overlay)
00059 {
00060     successorMap.clear();
00061     successorListSize = size;
00062     thisNode = owner;
00063     this->overlay = overlay;
00064     addSuccessor(thisNode);
00065 }
00066 
00067 uint32_t ChordSuccessorList::getSize()
00068 {
00069     return successorMap.size();
00070 }
00071 
00072 bool ChordSuccessorList::isEmpty()
00073 {
00074     if (successorMap.size() == 1 && getSuccessor() == thisNode)
00075         return true;
00076     else
00077         return false;
00078 }
00079 
00080 const NodeHandle& ChordSuccessorList::getSuccessor(uint32_t pos)
00081 {
00082     // check boundaries
00083     if (pos == 0 && successorMap.size() == 0)
00084         return NodeHandle::UNSPECIFIED_NODE;
00085 
00086     if (pos >= successorMap.size()) {
00087         error("Index out of bound (ChordSuccessorList, getSuccessor())");
00088     }
00089 
00090     std::map<OverlayKey, SuccessorListEntry>::iterator it =
00091         successorMap.begin();
00092 
00093     for (uint32_t i= 0; i < pos; i++) {
00094         it++;
00095         if (i == (pos-1))
00096             return it->second.nodeHandle;
00097     }
00098     return it->second.nodeHandle;
00099 }
00100 
00101 void ChordSuccessorList::updateList(NotifyResponse* notifyResponse)
00102 {
00103     addSuccessor(notifyResponse->getSrcNode(), false);
00104 
00105     for (uint32_t k = 0; ((k < static_cast<uint32_t>(notifyResponse->getSucNum()))
00106                      && (k < (successorListSize - 1))); k++) {
00107         NodeHandle successor = notifyResponse->getSucNode(k);
00108 
00109         // don't add nodes, if this would change our successor
00110         if (successor.getKey().isBetweenLR(thisNode.getKey(),
00111                                       notifyResponse->getSrcNode().getKey()))
00112             continue;
00113 
00114         addSuccessor(successor, false);
00115     }
00116 
00117     removeOldSuccessors();
00118     assert(!isEmpty());
00119 }
00120 
00121 
00122 void ChordSuccessorList::addSuccessor(NodeHandle successor, bool resize)
00123 {
00124     OverlayKey sum = successor.getKey() - (thisNode.getKey() + OverlayKey::ONE);
00125 
00126     std::map<OverlayKey, SuccessorListEntry>::iterator it =
00127         successorMap.find(sum);
00128 
00129     // Make a CommonAPI update() upcall to inform application
00130     // about our new neighbor in the successor list
00131 
00132     if (it == successorMap.end()) {
00133         overlay->callUpdate(successor, true);
00134     } else {
00135         successorMap.erase(it);
00136     }
00137 
00138     SuccessorListEntry entry;
00139     entry.nodeHandle = successor;
00140     entry.newEntry = true;
00141 
00142     successorMap.insert(make_pair(sum, entry));
00143 
00144     if ((resize == true) && (successorMap.size() > (uint32_t)successorListSize)) {
00145         it = successorMap.end();
00146         it--;
00147         overlay->callUpdate(it->second.nodeHandle, false);
00148         successorMap.erase(it);
00149     }
00150 }
00151 
00152 bool ChordSuccessorList::handleFailedNode(const TransportAddress& failed)
00153 {
00154     assert(failed != thisNode);
00155     for (std::map<OverlayKey, SuccessorListEntry>::iterator iter =
00156          successorMap.begin(); iter != successorMap.end(); ++iter) {
00157         if (failed == iter->second.nodeHandle) {
00158             successorMap.erase(iter);
00159             overlay->callUpdate(failed, false);
00160             // ensure that thisNode is always in the successor list
00161             if (getSize() == 0)
00162                 addSuccessor(thisNode);
00163             return true;
00164         }
00165     }
00166     return false;
00167 }
00168 
00169 void ChordSuccessorList::removeOldSuccessors()
00170 {
00171     std::map<OverlayKey,SuccessorListEntry>::iterator it;
00172 
00173     for (it = successorMap.begin(); it != successorMap.end();) {
00174 
00175         if (it->second.newEntry == false) {
00176             overlay->callUpdate(it->second.nodeHandle, false);
00177             successorMap.erase(it++);
00178         } else {
00179             it->second.newEntry = false;
00180             it++;
00181         }
00182     }
00183 
00184     it = successorMap.end();
00185     it--;
00186 
00187     while (successorMap.size() > successorListSize) {
00188         successorMap.erase(it--);
00189     }
00190 
00191     if (getSize() == 0)
00192         addSuccessor(thisNode);
00193 }
00194 
00195 
00196 void ChordSuccessorList::updateDisplayString()
00197 {
00198     // FIXME: doesn't work without tcl/tk
00199     //          if (ev.isGUI()) {
00200     if (1) {
00201         char buf[80];
00202 
00203         if (successorMap.size() == 1) {
00204             sprintf(buf, "1 successor");
00205         } else {
00206             sprintf(buf, "%zi successors", successorMap.size());
00207         }
00208 
00209         getDisplayString().setTagArg("t", 0, buf);
00210         getDisplayString().setTagArg("t", 2, "blue");
00211     }
00212 
00213 }
00214 
00215 void ChordSuccessorList::updateTooltip()
00216 {
00217     if (ev.isGUI()) {
00218         std::stringstream str;
00219         for (uint32_t i = 0; i < successorMap.size(); i++)      {
00220             str << getSuccessor(i);
00221             if ( i != successorMap.size() - 1 )
00222                 str << endl;
00223         }
00224 
00225 
00226         char buf[1024];
00227         sprintf(buf, "%s", str.str().c_str());
00228         getDisplayString().setTagArg("tt", 0, buf);
00229     }
00230 }
00231 
00232 void ChordSuccessorList::display()
00233 {
00234     cout << "Content of ChordSuccessorList:" << endl;
00235     for (std::map<OverlayKey,SuccessorListEntry>::iterator it =
00236         successorMap.begin(); it != successorMap.end(); it++)
00237         cout << it->first << " with Node: " << it->second.nodeHandle << endl;
00238 }
00239 
00240 }; //namespace

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