OverSim
BrooseBucket.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2007 Institut fuer Telematik, Universitaet Karlsruhe (TH)
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 //
18 
24 #include <omnetpp.h>
25 #include "BrooseBucket.h"
26 #include "BrooseHandle.h"
27 
28 using namespace std;
29 
31 
33 
34 const int MAXBITS = 1024;
35 
36 void BrooseBucket::initialize(int stage)
37 {
38  if(stage != MIN_STAGE_OVERLAY)
39  return;
40 
41  WATCH_MAP(bucket);
42 }
43 
44 void BrooseBucket::handleMessage(cMessage* msg)
45 {
46  error("BrooseBucket::handleMessage() shouldn't be called!");
47 }
48 
49 void BrooseBucket::initializeBucket(int shiftingBits, uint32_t prefix,
50  int size, Broose* overlay, bool isBBucket)
51 {
52  maxSize = size;
53  this->overlay = overlay;
54  this->isBBucket = isBBucket;
55 
56  if (shiftingBits < 0) {
57  key = overlay->getThisNode().getKey() << -shiftingBits;
58  } else {
59  key = overlay->getThisNode().getKey() >> shiftingBits;
60  }
61 
62  if (prefix != 0) {
63  OverlayKey tmp(prefix); // constraint
64  tmp = tmp << (overlay->getThisNode().getKey().getLength() - shiftingBits);
65  key = key + tmp;
66  }
67  bucket.clear();
68 }
69 
70 bool BrooseBucket::add(const NodeHandle& node, bool isAlive, simtime_t rtt)
71 {
72  OverlayKey tmp = key ^ node.getKey();
73 
74  bucketIter = bucket.find(tmp);
75 
76  if (bucketIter == bucket.end()) {
77  // new node
78  if (bucket.size() < maxSize) {
79  bucketIter = bucket.insert(make_pair(tmp,node)).first;
80  } else {
81  std::map<OverlayKey, BrooseHandle>::iterator back = --bucket.end();
82 
83  // is the new node closer than the one farthest away,
84  // remove the one and add the other
85  if (back->first > tmp) {
86  if (isBBucket) {
87  // call update() for removed sibling
88  overlay->callUpdate(back->second, false);
89  }
90 
91  bucket.erase(back);
92  bucketIter = bucket.insert(make_pair(tmp,node)).first;
93  } else {
94  // doesn't fit into bucket
95  return false;
96  }
97  }
98 
99  if (isBBucket) {
100  // call update() for new sibling
101  overlay->callUpdate(node, true);
102  }
103  }
104 
105  if (isAlive) {
106  bucketIter->second.failedResponses = 0;
107  bucketIter->second.lastSeen = simTime();
108  }
109 
110  if (rtt != MAXTIME) {
111  bucketIter->second.rtt = rtt;
112  }
113 
114  return true;
115 }
116 
118 {
119  unsigned int i = 0;
120  for (bucketIter = bucket.begin(); bucketIter != bucket.end(); i++) {
121  if (bucketIter->second.getIp() == node.getIp()) {
122  if (isBBucket && (i < (maxSize/7))) {
123  // call update() for removed sibling
124  overlay->callUpdate(node, false);
125  if (bucket.size() > (maxSize/7)) {
126  // new replacement sibling
127  overlay->callUpdate(get(maxSize/7), true);
128  }
129  }
130  bucket.erase(bucketIter++);
131  } else {
132  ++bucketIter;
133  }
134  }
135 }
136 
137 const BrooseHandle& BrooseBucket::get(uint32_t pos)
138 {
139  if (pos > bucket.size()) {
140  error("Index out of bounds(BrooseBucket).");
141  }
142 
143  uint32_t i = 0;
144  std::map<OverlayKey, BrooseHandle>::iterator it;
145 
146  for (it = bucket.begin(); it != bucket.end(); it++, i++) {
147  if (pos == i) {
148  return it->second;
149  }
150  }
151 
153 }
154 
155 const OverlayKey& BrooseBucket::getDist(uint32_t pos)
156 {
157  if (pos > bucket.size()) {
158  error("Index out of bounds(BrooseBucket).");
159  }
160 
161  uint32_t i = 0;
162  std::map<OverlayKey, BrooseHandle>::iterator it;
163 
164  for (it = bucket.begin(); it != bucket.end(); it++, i++) {
165  if (pos == i) {
166  return it->first;
167  }
168  }
169 
171 }
172 
173 
175 {
176  return bucket.size();
177 }
178 
180 {
181  return maxSize;
182 }
183 
185 {
186  return bucket.empty();
187 }
188 
190 {
191  bucket.clear();
192 }
193 
195 {
196  for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
197  result->add(bucketIter->second);
198  }
199 }
200 
201 
203 {
204  if (bucket.size() < 2)
205  return 0;
206 
207  return bucket.begin()->second.getKey().sharedPrefixLength(
208  (--bucket.end())->second.getKey());
209 }
210 
211 void BrooseBucket::output(int maxEntries)
212 {
213  BrooseHandle node;
214  OverlayKey dist;
215 
216  EV << "[BrooseBucket::output() @ " << overlay->getThisNode().getIp()
217  << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
218  << " BucketSize/MaxSize: " << bucket.size() << "/" << maxSize
219  << endl;
220 
221  int max;
222  max = bucket.size();
223 
224  if (maxEntries != 0 && maxEntries < max) {
225  max = maxEntries;
226  }
227 
228  int i;
229 
230  for (bucketIter = bucket.begin(), i = 0; i < max; bucketIter++, i++) {
231  dist = bucketIter->first;
232  node = bucketIter->second;
233  EV << " " << dist << " " << node.getKey() << " " << node.getIp() << " RTT: "
234  << node.rtt << " LS: " << node.lastSeen
235  << endl;
236  }
237 }
238 
240 {
241  OverlayKey dist;
242 
243  if (bucket.size() == 0)
244  return false;
245 
246  // check if the function was called to perform on a B bucket
247  if (isBBucket) {
248  if (bucket.size() <= (maxSize / 7))
249  return true;
250  else
251  dist = getDist((maxSize / 7) - 1);
252  } else
253  dist = getDist(bucket.size()-1);
254 
255  if ((key ^ overlay->getThisNode().getKey()) <= dist)
256  return true;
257  else
258  return false;
259 
260 }
261 
263 {
264  int i = -1;
265  std::map<OverlayKey, BrooseHandle>::iterator it;
266  for (it = bucket.begin(); it != bucket.end(); it++, i++) {
267  if (node.getIp() == it->second.getIp())
268  return i;
269  }
270  return i;
271 }
272 
274 {
275  for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
276  if (node.getIp() == bucketIter->second.getIp())
277  return bucketIter->second.failedResponses;
278  }
279  return -1;
280 }
281 
283 {
284  for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
285  if (node.getIp() == bucketIter->second.getIp())
286  bucketIter->second.failedResponses++;
287  }
288 }
289 
291 {
292  for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
293  if (node.getIp() == bucketIter->second.getIp())
294  bucketIter->second.failedResponses = 0;
295  }
296 }
297 
298 
299 void BrooseBucket::setRTT(const NodeHandle& node, simtime_t rpcRTT)
300 {
301  for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
302  if (node.getIp() == bucketIter->second.getIp()) {
303  bucketIter->second.rtt = rpcRTT;
304  }
305  }
306 }
307 
308 simtime_t BrooseBucket::getRTT(const NodeHandle& node)
309 {
310  for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
311  if (node.getIp() == bucketIter->second.getIp())
312  return bucketIter->second.rtt;
313  }
314  return -2;
315 }
316 
317 void BrooseBucket::setLastSeen(const NodeHandle& node, simtime_t time)
318 {
319  for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
320  if (node.getIp() == bucketIter->second.getIp())
321  bucketIter->second.lastSeen = time;
322  }
323 }
324 
325 simtime_t BrooseBucket::getLastSeen(const NodeHandle& node)
326 {
327  for (bucketIter = bucket.begin(); bucketIter!=bucket.end(); bucketIter++) {
328  if (node.getIp() == bucketIter->second.getIp())
329  return bucketIter->second.lastSeen;
330  }
331  return -2;
332 }