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         // TODO: first add node and than call update()
00134         overlay->callUpdate(successor, true);
00135     } else {
00136         successorMap.erase(it);
00137     }
00138 
00139     SuccessorListEntry entry;
00140     entry.nodeHandle = successor;
00141     entry.newEntry = true;
00142 
00143     successorMap.insert(make_pair(sum, entry));
00144 
00145     if ((resize == true) && (successorMap.size() > (uint32_t)successorListSize)) {
00146         it = successorMap.end();
00147         it--;
00148         overlay->callUpdate(it->second.nodeHandle, false);
00149         successorMap.erase(it);
00150     }
00151 }
00152 
00153 bool ChordSuccessorList::handleFailedNode(const TransportAddress& failed)
00154 {
00155     assert(failed != thisNode);
00156     for (std::map<OverlayKey, SuccessorListEntry>::iterator iter =
00157          successorMap.begin(); iter != successorMap.end(); ++iter) {
00158         if (failed == iter->second.nodeHandle) {
00159             successorMap.erase(iter);
00160             overlay->callUpdate(failed, false);
00161             // ensure that thisNode is always in the successor list
00162             if (getSize() == 0)
00163                 addSuccessor(thisNode);
00164             return true;
00165         }
00166     }
00167     return false;
00168 }
00169 
00170 void ChordSuccessorList::removeOldSuccessors()
00171 {
00172     std::map<OverlayKey,SuccessorListEntry>::iterator it;
00173 
00174     for (it = successorMap.begin(); it != successorMap.end();) {
00175 
00176         if (it->second.newEntry == false) {
00177             overlay->callUpdate(it->second.nodeHandle, false);
00178             successorMap.erase(it++);
00179         } else {
00180             it->second.newEntry = false;
00181             it++;
00182         }
00183     }
00184 
00185     it = successorMap.end();
00186     it--;
00187 
00188     while (successorMap.size() > successorListSize) {
00189         successorMap.erase(it--);
00190     }
00191 
00192     if (getSize() == 0)
00193         addSuccessor(thisNode);
00194 }
00195 
00196 
00197 void ChordSuccessorList::updateDisplayString()
00198 {
00199     // FIXME: doesn't work without tcl/tk
00200     //          if (ev.isGUI()) {
00201     if (1) {
00202         char buf[80];
00203 
00204         if (successorMap.size() == 1) {
00205             sprintf(buf, "1 successor");
00206         } else {
00207             sprintf(buf, "%zi successors", successorMap.size());
00208         }
00209 
00210         getDisplayString().setTagArg("t", 0, buf);
00211         getDisplayString().setTagArg("t", 2, "blue");
00212     }
00213 
00214 }
00215 
00216 void ChordSuccessorList::updateTooltip()
00217 {
00218     if (ev.isGUI()) {
00219         std::stringstream str;
00220         for (uint32_t i = 0; i < successorMap.size(); i++)      {
00221             str << getSuccessor(i);
00222             if ( i != successorMap.size() - 1 )
00223                 str << endl;
00224         }
00225 
00226 
00227         char buf[1024];
00228         sprintf(buf, "%s", str.str().c_str());
00229         getDisplayString().setTagArg("tt", 0, buf);
00230     }
00231 }
00232 
00233 void ChordSuccessorList::display()
00234 {
00235     cout << "Content of ChordSuccessorList:" << endl;
00236     for (std::map<OverlayKey,SuccessorListEntry>::iterator it =
00237         successorMap.begin(); it != successorMap.end(); it++)
00238         cout << it->first << " with Node: " << it->second.nodeHandle << endl;
00239 }
00240 
00241 }; //namespace
Generated on Wed May 26 16:21:14 2010 for OverSim by  doxygen 1.6.3