BrooseBucket.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2007 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 <omnetpp.h>
00025 #include "BrooseBucket.h"
00026 #include "BrooseHandle.h"
00027 
00028 using namespace std;
00029 
00030 const BrooseHandle* BrooseHandle::_unspecifiedNode = NULL;
00031 
00032 Define_Module(BrooseBucket);
00033 
00034 const int MAXBITS = 1024;
00035 
00036 void BrooseBucket::initialize(int stage)
00037 {
00038     if(stage != MIN_STAGE_OVERLAY)
00039         return;
00040 
00041     WATCH_MAP(bucket);
00042 }
00043 
00044 void BrooseBucket::handleMessage(cMessage* msg)
00045 {
00046     error("BrooseBucket::handleMessage() shouldn't be called!");
00047 }
00048 
00049 void BrooseBucket::initializeBucket(int shiftingBits, uint32_t prefix,
00050                                     int size, Broose* overlay, bool isBBucket)
00051 {
00052     maxSize = size;
00053     this->overlay = overlay;
00054     this->isBBucket = isBBucket;
00055 
00056     if (shiftingBits < 0) {
00057         key = overlay->getThisNode().getKey() << -shiftingBits;
00058     } else {
00059         key = overlay->getThisNode().getKey() >> shiftingBits;
00060     }
00061 
00062     if (prefix != 0) {
00063         OverlayKey tmp(prefix); // constraint
00064         tmp = tmp << (overlay->getThisNode().getKey().getLength() - shiftingBits);
00065         key = key + tmp;
00066     }
00067     bucket.clear();
00068 }
00069 
00070 bool BrooseBucket::add(const NodeHandle& node, bool isAlive, simtime_t rtt)
00071 {
00072     OverlayKey tmp = key ^ node.getKey();
00073 
00074     bucketIter = bucket.find(tmp);
00075 
00076     if (bucketIter == bucket.end()) {
00077         // new node
00078         if (bucket.size() < maxSize) {
00079              bucketIter = bucket.insert(make_pair(tmp,node)).first;
00080         } else {
00081             std::map<OverlayKey, BrooseHandle>::iterator back = --bucket.end();
00082 
00083             // is the new node closer than the one farthest away,
00084             // remove the one and add the other
00085             if (back->first > tmp) {
00086                 if (isBBucket) {
00087                     // call update() for removed sibling
00088                     overlay->callUpdate(back->second, false);
00089                 }
00090 
00091                 bucket.erase(back);
00092                 bucketIter = bucket.insert(make_pair(tmp,node)).first;
00093             } else {
00094                 // doesn't fit into bucket
00095                 return false;
00096             }
00097         }
00098 
00099         if (isBBucket) {
00100             // call update() for new sibling
00101             overlay->callUpdate(node, true);
00102         }
00103     }
00104 
00105     if (isAlive) {
00106         bucketIter->second.failedResponses = 0;
00107         bucketIter->second.lastSeen = simTime();
00108     }
00109 
00110     if (rtt != MAXTIME) {
00111         bucketIter->second.rtt = rtt;
00112     }
00113 
00114     return true;
00115 }
00116 
00117 void BrooseBucket::remove(const NodeHandle& node)
00118 {
00119     unsigned int i = 0;
00120     for (bucketIter = bucket.begin(); bucketIter != bucket.end(); i++) {
00121         if (bucketIter->second.getAddress() == node.getAddress()) {
00122             if (isBBucket && (i < (maxSize/7))) {
00123                 // call update() for removed sibling
00124                 overlay->callUpdate(node, false);
00125                 if (bucket.size() > (maxSize/7)) {
00126                     // new replacement sibling
00127                     overlay->callUpdate(get(maxSize/7), true);
00128                 }
00129             }
00130             bucket.erase(bucketIter++);
00131         } else {
00132             ++bucketIter;
00133         }
00134     }
00135 }
00136 
00137 const BrooseHandle& BrooseBucket::get(uint32_t pos)
00138 {
00139     if (pos > bucket.size()) {
00140         error("Index out of bounds(BrooseBucket).");
00141     }
00142 
00143     uint32_t i = 0;
00144     std::map<OverlayKey, BrooseHandle>::iterator it;
00145 
00146     for (it = bucket.begin(); it != bucket.end(); it++, i++) {
00147         if (pos == i) {
00148             return it->second;
00149         }
00150     }
00151 
00152     return BrooseHandle::unspecifiedNode();
00153 }
00154 
00155 const OverlayKey& BrooseBucket::getDist(uint32_t pos)
00156 {
00157     if (pos > bucket.size()) {
00158         error("Index out of bounds(BrooseBucket).");
00159     }
00160 
00161     uint32_t i = 0;
00162     std::map<OverlayKey, BrooseHandle>::iterator it;
00163 
00164     for (it = bucket.begin(); it != bucket.end(); it++, i++) {
00165         if (pos == i) {
00166             return it->first;
00167         }
00168     }
00169 
00170     return OverlayKey::UNSPECIFIED_KEY;
00171 }
00172 
00173 
00174 uint32_t BrooseBucket::getSize()
00175 {
00176     return bucket.size();
00177 }
00178 
00179 uint32_t BrooseBucket::getMaxSize()
00180 {
00181     return maxSize;
00182 }
00183 
00184 bool BrooseBucket::isEmpty()
00185 {
00186     return bucket.empty();
00187 }
00188 
00189 void BrooseBucket::clear()
00190 {
00191     bucket.clear();
00192 }
00193 
00194 void BrooseBucket::fillVector(NodeVector* result)
00195 {
00196     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00197         result->add(bucketIter->second);
00198     }
00199 }
00200 
00201 
00202 int BrooseBucket::longestPrefix()
00203 {
00204     if (bucket.size() < 2)
00205         return 0;
00206 
00207     return bucket.begin()->second.getKey().sharedPrefixLength(
00208                                              (--bucket.end())->second.getKey());
00209 }
00210 
00211 void BrooseBucket::output(int maxEntries)
00212 {
00213     BrooseHandle node;
00214     OverlayKey dist;
00215 
00216     EV << "[BrooseBucket::output() @ " << overlay->getThisNode().getAddress()
00217        << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00218        << "    BucketSize/MaxSize: " << bucket.size() << "/" << maxSize
00219        << endl;
00220 
00221     int max;
00222     max = bucket.size();
00223 
00224     if (maxEntries != 0 && maxEntries < max) {
00225         max = maxEntries;
00226     }
00227 
00228     int i;
00229 
00230     for (bucketIter = bucket.begin(), i = 0; i < max; bucketIter++, i++) {
00231         dist = bucketIter->first;
00232         node = bucketIter->second;
00233         EV << "    " << dist << " " << node.getKey() << " " << node.getAddress() << " RTT: "
00234            << node.rtt << " LS: " << node.lastSeen
00235            << endl;
00236     }
00237 }
00238 
00239 bool BrooseBucket::keyInRange(const OverlayKey& key)
00240 {
00241     OverlayKey dist;
00242 
00243     if (bucket.size() == 0)
00244         return false;
00245 
00246     // check if the function was called to perform on a B bucket
00247     if (isBBucket) {
00248         if (bucket.size() <=  (maxSize / 7))
00249             return true;
00250         else
00251             dist = getDist((maxSize / 7) - 1);
00252     } else
00253         dist = getDist(bucket.size()-1);
00254 
00255     if ((key ^ overlay->getThisNode().getKey()) <= dist)
00256         return true;
00257     else
00258         return false;
00259 
00260 }
00261 
00262 int BrooseBucket::getPos(const NodeHandle& node)
00263 {
00264     int i = -1;
00265     std::map<OverlayKey, BrooseHandle>::iterator it;
00266     for (it = bucket.begin(); it != bucket.end(); it++, i++) {
00267         if (node.getAddress() == it->second.getAddress())
00268             return i;
00269     }
00270     return i;
00271 }
00272 
00273 int BrooseBucket::getFailedResponses (const NodeHandle& node)
00274 {
00275     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00276         if (node.getAddress() == bucketIter->second.getAddress())
00277             return bucketIter->second.failedResponses;
00278     }
00279     return -1;
00280 }
00281 
00282 void BrooseBucket::increaseFailedResponses (const NodeHandle& node)
00283 {
00284     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00285         if (node.getAddress() == bucketIter->second.getAddress())
00286             bucketIter->second.failedResponses++;
00287     }
00288 }
00289 
00290 void BrooseBucket::resetFailedResponses (const NodeHandle& node)
00291 {
00292     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00293         if (node.getAddress() == bucketIter->second.getAddress())
00294             bucketIter->second.failedResponses = 0;
00295     }
00296 }
00297 
00298 
00299 void BrooseBucket::setRTT(const NodeHandle& node, simtime_t rpcRTT)
00300 {
00301     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00302         if (node.getAddress() == bucketIter->second.getAddress()) {
00303             bucketIter->second.rtt = rpcRTT;
00304         }
00305     }
00306 }
00307 
00308 simtime_t BrooseBucket::getRTT(const NodeHandle& node)
00309 {
00310     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00311         if (node.getAddress() == bucketIter->second.getAddress())
00312             return bucketIter->second.rtt;
00313     }
00314     return -2;
00315 }
00316 
00317 void BrooseBucket::setLastSeen(const NodeHandle& node, simtime_t time)
00318 {
00319     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00320         if (node.getAddress() == bucketIter->second.getAddress())
00321             bucketIter->second.lastSeen = time;
00322     }
00323 }
00324 
00325 simtime_t BrooseBucket::getLastSeen(const NodeHandle& node)
00326 {
00327     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00328         if (node.getAddress() == bucketIter->second.getAddress())
00329             return bucketIter->second.lastSeen;
00330     }
00331     return -2;
00332 }
Generated on Wed May 26 16:21:13 2010 for OverSim by  doxygen 1.6.3