OverSim
PeerStorage.cc
Go to the documentation of this file.
1 //
2 // Copyright (C) 2010 Karlsruhe Institute of Technology (KIT),
3 // Institute of Telematics
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 
25 #include <PeerInfo.h>
26 #include <NodeHandle.h>
27 
28 #include "PeerStorage.h"
29 
31 {
32  PeerHashMap::iterator it;
33  for (it = peerHashMap.begin(); it != peerHashMap.end(); it++) {
34  delete it->second.info;
35  }
36 }
37 
39 {
40  return peerHashMap.size();
41 }
42 
43 const PeerHashMap::iterator PeerStorage::find(const IPvXAddress& ip)
44 {
45  return peerHashMap.find(ip);
46 }
47 
48 const PeerHashMap::iterator PeerStorage::begin()
49 {
50  return peerHashMap.begin();
51 }
52 
53 const PeerHashMap::iterator PeerStorage::end()
54 {
55  return peerHashMap.end();
56 }
57 
59 {
60  return 1<<2;
61 }
62 
63 uint8_t PeerStorage::calcOffset(bool bootstrapped, bool malicious)
64 {
65  uint8_t offset = 0;
66  if (bootstrapped) offset += 1<<0;
67  if (malicious) offset += 1<<1;
68  return offset;
69 }
70 
72  PeerHashMap::iterator it)
73 {
74  PeerInfo* peerInfo = it->second.info;
75 
76  bool bootstrapped = false;
77  for (AddrPerOverlayVector::iterator oit = it->second.addrVector.begin();
78  oit != it->second.addrVector.end(); oit++) {
79 
80  bootstrapped |= oit->bootstrapped;
81  }
82 
83  bool malicious = peerInfo->isMalicious();
84  size_t partition = peerInfo->getTypeID();
85  size_t offset = calcOffset(bootstrapped, malicious);
86  size_t partitionIndex = partition*offsetSize()+offset;
87 
88 #if 0
89  std::cout << "INSERT " << it->first << " partitionIndex:"
90  << partitionIndex
91  << " bootstrapped:" << bootstrapped << " malicious:"
92  << malicious << std::endl;
93 #endif
94 
95  if (peerVector.size() < (partition + 1)*offsetSize()) {
96  int i = peerVector.size();
97  peerVector.resize(offsetSize()*(partition + 1));
98  freeVector.resize(offsetSize()*(partition + 1));
99  while (i < (int)(peerVector.size())) {
100  peerVector[i++].reserve(30000);
101  freeVector[i++].reserve(30000);
102  }
103  }
104 
105  size_t index = -1;
106 
107  if ((freeVector.size() >= (partition + 1)*offsetSize()) &&
108  (freeVector[partitionIndex].size())) {
109 
110  index = freeVector[partitionIndex].back();
111  freeVector[partitionIndex].pop_back();
112  peerVector[partitionIndex][index] = it;
113  //std::cout << "\t REUSING position " << index << std::endl;
114  } else {
115  index = peerVector[partitionIndex].size();
116  peerVector[partitionIndex].push_back(it);
117  //std::cout << "\t APPENDING at position " << index << std::endl;
118  }
119 
120  it->second.peerVectorIndex = index;
121 }
122 
124  PeerHashMap::iterator it)
125 {
126  PeerInfo* peerInfo = it->second.info;
127 
128  bool bootstrapped = false;
129  for (AddrPerOverlayVector::iterator oit = it->second.addrVector.begin();
130  oit != it->second.addrVector.end(); oit++) {
131 
132  bootstrapped |= oit->bootstrapped;
133  }
134 
135  bool malicious = peerInfo->isMalicious();
136  size_t partition = peerInfo->getTypeID();
137  size_t offset = calcOffset(bootstrapped, malicious);
138  size_t index = it->second.peerVectorIndex;
139  size_t partitionIndex = partition*offsetSize()+offset;
140 
141  if (peerVector[partitionIndex].size() == (index + 1)) {
142  peerVector[partitionIndex].pop_back();
143  } else {
144  peerVector[partitionIndex][index] = peerHashMap.end();
145  freeVector[partitionIndex].push_back(index);
146  }
147  //std::cout << "ERASE " << it->first << " partitionIndex:" << partitionIndex
148  // << " index: " << index << std::endl;
149 }
150 
151 std::pair<const PeerHashMap::iterator, bool> PeerStorage::insert(const std::pair<IPvXAddress, BootstrapEntry>& element)
152 {
153  std::pair<PeerHashMap::iterator, bool> ret;
154 
155  ret = peerHashMap.insert(element);
156 
157  if (ret.second) {
159  }
160 
161  return ret;
162 }
163 
164 void PeerStorage::erase(const PeerHashMap::iterator it)
165 {
167  delete it->second.info;
168  peerHashMap.erase(it);
169 }
170 
171 void PeerStorage::registerOverlay(const PeerHashMap::iterator it,
172  const NodeHandle& peer,
173  int32_t overlayId)
174 {
175  it->second.addrVector.setAddrForOverlayId(new NodeHandle(peer),
176  overlayId);
177  //if (!overlayPeerVectorMap.count(overlayId)) {
178  // PeerVector vector;
179  // overlayPeerVectorMap.insert(std::make_pair(overlayId,
180  // vector));
181  //}
182 
183  // insertMapIteratorIntoVector(overlayPeerVectorMap[overlayId], it);
184 }
185 
186 void PeerStorage::setMalicious(const PeerHashMap::iterator it, bool malicious)
187 {
188  if (it == peerHashMap.end()) {
189  throw cRuntimeError("GlobalNodeList::setMalicious(): Node not found!");
190  }
191 
193  it->second.info->setMalicious(malicious);
195 }
196 
197 void PeerStorage::setBootstrapped(const PeerHashMap::iterator it,
198  int32_t overlayId, bool bootstrapped)
199 {
200  if (it == peerHashMap.end()) {
201  throw cRuntimeError("GlobalNodeList::setBootstrapped(): Node not found!");
202  }
203 
205  //std::cout << "setBootstrapped: " << bootstrapped << " overlayId: "
206  // << overlayId << std::endl;
207 
208  AddrPerOverlayVector::iterator oit = it->
209  second.addrVector.getIterForOverlayId(overlayId);
210 
211  if (oit != it->second.addrVector.end()) {
212  oit->bootstrapped = bootstrapped;
213  } else if (bootstrapped) {
214  throw cRuntimeError("PeerStorage::setBootstrapped: No valid entry found!");
215  }
216 
218 }
219 
220 const PeerHashMap::iterator PeerStorage::getRandomNode(int32_t overlayId,
221  int32_t nodeType,
222  bool bootstrappedNeeded,
223  bool inoffensiveNeeded)
224 {
225  if (peerHashMap.size() == 0) {
226  std::cout << "getRandomNode: empty!" << std::endl;
227  return peerHashMap.end();
228  }
229 
230  PeerVector& peerVector = globalPeerVector;
231 
232  size_t sum = 0;
233 
234  //std::cout << "getRandomNode(): nodeType: " << nodeType << " boostrapped: "
235  // << bootstrappedNeeded << " inoffensive: " << inoffensiveNeeded
236  // << std::endl;
237 
238  for (uint i = 0; i < peerVector.size(); i++) {
239  if (((nodeType > -1) && ((uint)nodeType != i/offsetSize())) ||
240  (bootstrappedNeeded && !(i & 1)) ||
241  (inoffensiveNeeded && (i & 2))) {
242  continue;
243  }
244  //std::cout << "Using i=" << i << std::endl;
245  sum += (peerVector[i].size() - freeVector[i].size());
246  //std::cout << "new sum: " << sum << std::endl;
247  }
248 
249  if (sum == 0) {
250  return peerHashMap.end();
251  }
252 
253  size_t random = intuniform(1, sum);
254  uint i = 0;
255 
256  while ((i < peerVector.size())) {
257  if (((nodeType > -1) && ((uint)nodeType != i/offsetSize())) ||
258  (bootstrappedNeeded && !(i & 1)) ||
259  (inoffensiveNeeded && (i & 2))) {
260  i++;
261  continue;
262  } else if ((peerVector[i].size() - freeVector[i].size()) < random) {
263  random -= peerVector[i].size() - freeVector[i].size();
264  i++;
265  } else {
266  break;
267  }
268  }
269 
270  random = intuniform(1, peerVector[i].size());
271  PeerHashMap::iterator it = peerVector[i][random-1];
272  while (it == peerHashMap.end()) {
273  if (random == peerVector[i].size()) {
274  random = 0;
275  }
276  it = peerVector[i][(++random)-1];
277  }
278  //std::cout << "Using node from vector i=" << i << " and position=" << random-1 << std::endl;
279 
280  return it;
281 }