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
00019
00025 #include <PeerInfo.h>
00026 #include <NodeHandle.h>
00027
00028 #include "PeerStorage.h"
00029
00030 PeerStorage::~PeerStorage()
00031 {
00032 PeerHashMap::iterator it;
00033 for (it = peerHashMap.begin(); it != peerHashMap.end(); it++) {
00034 delete it->second.info;
00035 delete it->second.node;
00036 }
00037 }
00038
00039 size_t PeerStorage::size()
00040 {
00041 return peerHashMap.size();
00042 }
00043
00044 const PeerHashMap::iterator PeerStorage::find(const IPvXAddress& ip)
00045 {
00046 return peerHashMap.find(ip);
00047 }
00048
00049 const PeerHashMap::iterator PeerStorage::begin()
00050 {
00051 return peerHashMap.begin();
00052 }
00053
00054 const PeerHashMap::iterator PeerStorage::end()
00055 {
00056 return peerHashMap.end();
00057 }
00058
00059 size_t PeerStorage::offsetSize()
00060 {
00061 return 1<<2;
00062 }
00063
00064 uint8_t PeerStorage::calcOffset(bool bootstrapped, bool malicious)
00065 {
00066 uint8_t offset = 0;
00067 if (bootstrapped) offset += 1<<0;
00068 if (malicious) offset += 1<<1;
00069 return offset;
00070 }
00071
00072 void PeerStorage::insertMapIteratorIntoVector(PeerHashMap::iterator it)
00073 {
00074 PeerInfo* peerInfo = it->second.info;
00075 bool bootstrapped = peerInfo->isBootstrapped();
00076 bool malicious = peerInfo->isMalicious();
00077 size_t partition = peerInfo->getTypeID();
00078 size_t offset = calcOffset(bootstrapped, malicious);
00079 size_t partitionIndex = partition*offsetSize()+offset;
00080
00081 #if 0
00082 std::cout << "INSERT " << it->first << " partitionIndex:"
00083 << partitionIndex
00084 << " bootstrapped:" << bootstrapped << " malicious:"
00085 << malicious << std::endl;
00086 #endif
00087
00088 if (peerVector.size() < (partition + 1)*offsetSize()) {
00089 int i = peerVector.size();
00090 peerVector.resize(offsetSize()*(partition + 1));
00091 freeVector.resize(offsetSize()*(partition + 1));
00092 while (i < (int)(peerVector.size())) {
00093 peerVector[i++].reserve(30000);
00094 freeVector[i++].reserve(30000);
00095 }
00096 }
00097
00098 size_t index = -1;
00099
00100 if ((freeVector.size() >= (partition + 1)*offsetSize()) &&
00101 (freeVector[partitionIndex].size())) {
00102
00103 index = freeVector[partitionIndex].back();
00104 freeVector[partitionIndex].pop_back();
00105 peerVector[partitionIndex][index] = it;
00106
00107 } else {
00108 index = peerVector[partitionIndex].size();
00109 peerVector[partitionIndex].push_back(it);
00110
00111 }
00112
00113 it->second.peerVectorIndex = index;
00114 }
00115
00116 void PeerStorage::removeMapIteratorFromVector(PeerHashMap::iterator it)
00117 {
00118 PeerInfo* peerInfo = it->second.info;
00119 bool bootstrapped = peerInfo->isBootstrapped();
00120 bool malicious = peerInfo->isMalicious();
00121 size_t partition = peerInfo->getTypeID();
00122 size_t offset = calcOffset(bootstrapped, malicious);
00123 size_t index = it->second.peerVectorIndex;
00124 size_t partitionIndex = partition*offsetSize()+offset;
00125
00126 if (peerVector[partitionIndex].size() == (index + 1)) {
00127 peerVector[partitionIndex].pop_back();
00128 } else {
00129 peerVector[partitionIndex][index] = peerHashMap.end();
00130 freeVector[partitionIndex].push_back(index);
00131 }
00132
00133
00134 }
00135
00136 std::pair<const PeerHashMap::iterator, bool> PeerStorage::insert(const std::pair<IPvXAddress, BootstrapEntry>& element)
00137 {
00138 std::pair<PeerHashMap::iterator, bool> ret;
00139
00140 ret = peerHashMap.insert(element);
00141
00142 if (ret.second) {
00143 insertMapIteratorIntoVector(ret.first);
00144 }
00145
00146 return ret;
00147 }
00148
00149 void PeerStorage::erase(const PeerHashMap::iterator it)
00150 {
00151 removeMapIteratorFromVector(it);
00152 delete it->second.info;
00153 delete it->second.node;
00154 peerHashMap.erase(it);
00155 }
00156
00157 void PeerStorage::setMalicious(const PeerHashMap::iterator it, bool malicious)
00158 {
00159 if (it == peerHashMap.end()) {
00160 throw cRuntimeError("GlobalNodeList::setMalicious(): Node not found!");
00161 }
00162
00163 removeMapIteratorFromVector(it);
00164 it->second.info->setMalicious(malicious);
00165 insertMapIteratorIntoVector(it);
00166 }
00167
00168 void PeerStorage::setBootstrapped(const PeerHashMap::iterator it, bool bootstrapped)
00169 {
00170 if (it == peerHashMap.end()) {
00171 throw cRuntimeError("GlobalNodeList::setMalicious(): Node not found!");
00172 }
00173
00174 removeMapIteratorFromVector(it);
00175
00176 it->second.info->setBootstrapped(bootstrapped);
00177 insertMapIteratorIntoVector(it);
00178 }
00179
00180 const PeerHashMap::iterator PeerStorage::getRandomNode(int32_t nodeType,
00181 bool bootstrappedNeeded,
00182 bool inoffensiveNeeded)
00183 {
00184 if (peerHashMap.size() == 0) {
00185 std::cout << "getRandomNode: empty!" << std::endl;
00186 return peerHashMap.end();
00187 }
00188
00189 size_t sum = 0;
00190
00191
00192
00193
00194
00195 for (uint i = 0; i < peerVector.size(); i++) {
00196 if (((nodeType > -1) && ((uint)nodeType != i/offsetSize())) ||
00197 (bootstrappedNeeded && !(i & 1)) ||
00198 (inoffensiveNeeded && (i & 2))) {
00199 continue;
00200 }
00201
00202 sum += (peerVector[i].size() - freeVector[i].size());
00203
00204 }
00205
00206 if (sum == 0) {
00207 return peerHashMap.end();
00208 }
00209
00210 size_t random = intuniform(1, sum);
00211 uint i = 0;
00212
00213 while ((i < peerVector.size())) {
00214 if (((nodeType > -1) && ((uint)nodeType != i/offsetSize())) ||
00215 (bootstrappedNeeded && !(i & 1)) ||
00216 (inoffensiveNeeded && (i & 2))) {
00217 i++;
00218 continue;
00219 } else if ((peerVector[i].size() - freeVector[i].size()) < random) {
00220 random -= peerVector[i].size() - freeVector[i].size();
00221 i++;
00222 } else {
00223 break;
00224 }
00225 }
00226
00227 random = intuniform(1, peerVector[i].size());
00228 PeerHashMap::iterator it = peerVector[i][random-1];
00229 while (it == peerHashMap.end()) {
00230 if (random == peerVector[i].size()) {
00231 random = 0;
00232 }
00233 it = peerVector[i][(++random)-1];
00234 }
00235
00236
00237 return it;
00238 }