BrooseBucket.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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);
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
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
00084
00085 if (back->first > tmp) {
00086 if (isBBucket) {
00087
00088 overlay->callUpdate(back->second, false);
00089 }
00090
00091 bucket.erase(back);
00092 bucketIter = bucket.insert(make_pair(tmp,node)).first;
00093 } else {
00094
00095 return false;
00096 }
00097 }
00098
00099 if (isBBucket) {
00100
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
00124 overlay->callUpdate(node, false);
00125 if (bucket.size() > (maxSize/7)) {
00126
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
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 }