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                 bucket.erase(back);
00087                 bucketIter = bucket.insert(make_pair(tmp,node)).first;
00088             } else {
00089                 // doesn't fit into bucket
00090                 return false;
00091             }
00092         }
00093 
00094         if (isBBucket && (getPos(node) < (maxSize/7))) {
00095             // node is a new sibling
00096             if (bucket.size() > (maxSize/7)) {
00097                 // call update() for removed sibling
00098                 overlay->callUpdate(get(maxSize/7), false);
00099             }
00100 
00101             // call update() for new sibling
00102             overlay->callUpdate(node, true);
00103         }
00104     }
00105 
00106     if (isAlive) {
00107         bucketIter->second.failedResponses = 0;
00108         bucketIter->second.lastSeen = simTime();
00109     }
00110 
00111     if (rtt != MAXTIME) {
00112         bucketIter->second.rtt = rtt;
00113     }
00114 
00115     return true;
00116 }
00117 
00118 void BrooseBucket::remove(const NodeHandle& node)
00119 {
00120     int i = 0;
00121     for (bucketIter = bucket.begin(); bucketIter != bucket.end(); i++) {
00122         if (bucketIter->second.getAddress() == node.getAddress()) {
00123             if (isBBucket && (i < (maxSize/7))) {
00124                 // call update() for removed sibling
00125                 overlay->callUpdate(node, false);
00126                 if (bucket.size() > (maxSize/7)) {
00127                     // new replacement sibling
00128                     overlay->callUpdate(get(maxSize/7), true);
00129                 }
00130             }
00131             bucket.erase(bucketIter++);
00132         } else {
00133             ++bucketIter;
00134         }
00135     }
00136 }
00137 
00138 const BrooseHandle& BrooseBucket::get(uint32_t pos)
00139 {
00140     if (pos > bucket.size()) {
00141         error("Index out of bounds(BrooseBucket).");
00142     }
00143 
00144     uint32_t i = 0;
00145     for (bucketIter = bucket.begin(); bucketIter != bucket.end(); bucketIter++) {
00146         if (pos == i) {
00147             return bucketIter->second;
00148         }
00149         i++;
00150     }
00151     return BrooseHandle::unspecifiedNode();
00152 }
00153 
00154 const OverlayKey& BrooseBucket::getDist(uint32_t pos)
00155 {
00156     if(pos > bucket.size()) {
00157         error("Index out of bounds(BrooseBucket).");
00158     }
00159 
00160     uint32_t i = 0;
00161     for (bucketIter = bucket.begin(); bucketIter != bucket.end(); bucketIter++) {
00162         if (pos == i) {
00163             return bucketIter->first;
00164         }
00165         i++;
00166     }
00167     return OverlayKey::UNSPECIFIED_KEY;
00168 }
00169 
00170 
00171 uint32_t BrooseBucket::getSize()
00172 {
00173     return bucket.size();
00174 }
00175 
00176 uint32_t BrooseBucket::getMaxSize()
00177 {
00178     return maxSize;
00179 }
00180 
00181 bool BrooseBucket::isEmpty()
00182 {
00183     return bucket.empty();
00184 }
00185 
00186 void BrooseBucket::clear()
00187 {
00188     bucket.clear();
00189 }
00190 
00191 void BrooseBucket::fillVector(NodeVector* result)
00192 {
00193     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00194         result->add(bucketIter->second);
00195     }
00196 }
00197 
00198 
00199 int BrooseBucket::longestPrefix()
00200 {
00201     if (bucket.size() < 2)
00202         return 0;
00203 
00204     return bucket.begin()->second.getKey().sharedPrefixLength(
00205                                              (--bucket.end())->second.getKey());
00206 }
00207 
00208 void BrooseBucket::output(int maxEntries)
00209 {
00210     BrooseHandle node;
00211     OverlayKey dist;
00212 
00213     EV << "[BrooseBucket::output() @ " << overlay->getThisNode().getAddress()
00214        << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00215        << "    BucketSize/MaxSize: " << bucket.size() << "/" << maxSize
00216        << endl;
00217 
00218     int max;
00219     max = bucket.size();
00220 
00221     if (maxEntries != 0 && maxEntries < max) {
00222         max = maxEntries;
00223     }
00224 
00225     int i;
00226 
00227     for (bucketIter = bucket.begin(), i = 0; i < max; bucketIter++, i++) {
00228         dist = bucketIter->first;
00229         node = bucketIter->second;
00230         EV << "    " << dist << " " << node.getKey() << " " << node.getAddress() << " RTT: "
00231            << node.rtt << " LS: " << node.lastSeen
00232            << endl;
00233     }
00234 }
00235 
00236 bool BrooseBucket::keyInRange(const OverlayKey& key)
00237 {
00238     OverlayKey dist;
00239 
00240     if (bucket.size() == 0)
00241         return false;
00242 
00243     // check if the function was called to perform on a B bucket
00244     if (isBBucket) {
00245         if (bucket.size() <=  (maxSize / 7))
00246             return true;
00247         else
00248             dist = getDist((maxSize / 7) - 1);
00249     } else
00250         dist = getDist(bucket.size()-1);
00251 
00252     if ((key ^ overlay->getThisNode().getKey()) <= dist)
00253         return true;
00254     else
00255         return false;
00256 
00257 }
00258 
00259 int BrooseBucket::getPos(const NodeHandle& node)
00260 {
00261     int i = -1;
00262     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++, i++) {
00263         if (node.getAddress() == bucketIter->second.getAddress())
00264             return i;
00265     }
00266     return i;
00267 }
00268 
00269 int BrooseBucket::getFailedResponses (const NodeHandle& node)
00270 {
00271     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00272         if (node.getAddress() == bucketIter->second.getAddress())
00273             return bucketIter->second.failedResponses;
00274     }
00275     return -1;
00276 }
00277 
00278 void BrooseBucket::increaseFailedResponses (const NodeHandle& node)
00279 {
00280     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00281         if (node.getAddress() == bucketIter->second.getAddress())
00282             bucketIter->second.failedResponses++;
00283     }
00284 }
00285 
00286 void BrooseBucket::resetFailedResponses (const NodeHandle& node)
00287 {
00288     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00289         if (node.getAddress() == bucketIter->second.getAddress())
00290             bucketIter->second.failedResponses = 0;
00291     }
00292 }
00293 
00294 
00295 void BrooseBucket::setRTT(const NodeHandle& node, simtime_t rpcRTT)
00296 {
00297     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00298         if (node.getAddress() == bucketIter->second.getAddress()) {
00299             bucketIter->second.rtt = rpcRTT;
00300         }
00301     }
00302 }
00303 
00304 simtime_t BrooseBucket::getRTT(const NodeHandle& node)
00305 {
00306     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00307         if (node.getAddress() == bucketIter->second.getAddress())
00308             return bucketIter->second.rtt;
00309     }
00310     return -2;
00311 }
00312 
00313 void BrooseBucket::setLastSeen(const NodeHandle& node, simtime_t time)
00314 {
00315     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00316         if (node.getAddress() == bucketIter->second.getAddress())
00317             bucketIter->second.lastSeen = time;
00318     }
00319 }
00320 
00321 simtime_t BrooseBucket::getLastSeen(const NodeHandle& node)
00322 {
00323     for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
00324         if (node.getAddress() == bucketIter->second.getAddress())
00325             return bucketIter->second.lastSeen;
00326     }
00327     return -2;
00328 }

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