DHTDataStorage.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 <hashWatch.h>
00026
00027 #include "DHTDataStorage.h"
00028
00029 Define_Module(DHTDataStorage);
00030
00031 using namespace std;
00032
00033 std::ostream& operator<<(std::ostream& os, const DhtDataEntry entry)
00034 {
00035 os << "Value: " << entry.value
00036 << " Kind: " << entry.kind
00037 << " ID: " << entry.id
00038 << " Endtime: " << entry.ttlMessage->getArrivalTime()
00039 << " Responsible: " << entry.responsible
00040 << " SourceNode: " << entry.sourceNode;
00041
00042 if (entry.siblingVote.size()) {
00043 os << " siblingVote:";
00044
00045 for (SiblingVoteMap::const_iterator it = entry.siblingVote.begin();
00046 it != entry.siblingVote.end(); it++) {
00047 os << " " << it->first << " (" << it->second.size() << ")";
00048 }
00049 }
00050 return os;
00051 }
00052
00053
00054 void DHTDataStorage::initialize(int stage)
00055 {
00056 if (stage != MIN_STAGE_APP)
00057 return;
00058
00059 WATCH_MULTIMAP(dataMap);
00060 }
00061
00062 void DHTDataStorage::handleMessage(cMessage* msg)
00063 {
00064 error("This module doesn't handle messages!");
00065 }
00066
00067 void DHTDataStorage::clear()
00068 {
00069 map<OverlayKey, DhtDataEntry>::iterator iter;
00070
00071 for( iter = dataMap.begin(); iter != dataMap.end(); iter++ ) {
00072 cancelAndDelete(iter->second.ttlMessage);
00073 }
00074
00075 dataMap.clear();
00076 }
00077
00078
00079 uint32_t DHTDataStorage::getSize()
00080 {
00081 return dataMap.size();
00082 }
00083
00084 DhtDataEntry* DHTDataStorage::getDataEntry(const OverlayKey& key,
00085 uint32_t kind, uint32_t id)
00086 {
00087 pair<DhtDataMap::iterator, DhtDataMap::iterator> pos =
00088 dataMap.equal_range(key);
00089
00090 while (pos.first != pos.second) {
00091 if ((pos.first->second.kind == kind) &&
00092 (pos.first->second.id == id)) {
00093 return &pos.first->second;
00094 }
00095 ++pos.first;
00096 }
00097
00098 return NULL;
00099 }
00100
00101
00102
00103 DhtDataVector* DHTDataStorage::getDataVector(const OverlayKey& key,
00104 uint32_t kind, uint32_t id)
00105 {
00106 DhtDataVector* vect = new DhtDataVector();
00107 DhtDataEntry entry;
00108
00109 pair<DhtDataMap::iterator, DhtDataMap::iterator> pos =
00110 dataMap.equal_range(key);
00111
00112 while (pos.first != pos.second) {
00113 entry = pos.first->second;
00114 vect->push_back(make_pair(key, entry));
00115 ++pos.first;
00116 }
00117
00118 return vect;
00119 }
00120
00121
00122 const NodeHandle& DHTDataStorage::getSourceNode(const OverlayKey& key,
00123 uint32_t kind, uint32_t id)
00124 {
00125 DhtDataEntry* entry = getDataEntry(key, kind, id);
00126
00127 if (entry == NULL)
00128 return NodeHandle::UNSPECIFIED_NODE;
00129 else
00130 return entry->sourceNode;
00131 }
00132
00133 const bool DHTDataStorage::isModifiable(const OverlayKey& key,
00134 uint32_t kind, uint32_t id)
00135 {
00136 DhtDataEntry* entry = getDataEntry(key, kind, id);
00137
00138 if (entry == NULL)
00139 return true;
00140 else
00141 return entry->is_modifiable;
00142 }
00143
00144
00145 const DhtDataMap::iterator DHTDataStorage::begin()
00146 {
00147 return dataMap.begin();
00148 }
00149
00150 const DhtDataMap::iterator DHTDataStorage::end()
00151 {
00152 return dataMap.end();
00153 }
00154
00155 DhtDataEntry* DHTDataStorage::addData(const OverlayKey& key, uint32_t kind,
00156 uint32_t id,
00157 BinaryValue value, cMessage* ttlMessage,
00158 bool is_modifiable, NodeHandle sourceNode,
00159 bool responsible)
00160 {
00161 DhtDataEntry entry;
00162 entry.kind = kind;
00163 entry.id = id;
00164 entry.value = value;
00165 entry.ttlMessage = ttlMessage;
00166 entry.sourceNode = sourceNode;
00167 entry.is_modifiable = is_modifiable;
00168 entry.responsible = responsible;
00169
00170 if ((kind == 0) || (id == 0)) {
00171 throw cRuntimeError("DHTDataStorage::addData(): "
00172 "Not allowed to add data with kind = 0 or id = 0!");
00173 }
00174
00175 pair<DhtDataMap::iterator, DhtDataMap::iterator> pos =
00176 dataMap.equal_range(key);
00177
00178
00179 while ((pos.first != pos.second) && (pos.first->second.kind < kind)) {
00180 ++pos.first;
00181 }
00182
00183 while ((pos.first != pos.second) && (pos.first->second.kind == kind)
00184 && (pos.first->second.id < id)) {
00185 ++pos.first;
00186 }
00187
00188 return &(dataMap.insert(pos.first, make_pair(key, entry))->second);
00189 }
00190
00191 void DHTDataStorage::removeData(const OverlayKey& key, uint32_t kind,
00192 uint32_t id)
00193 {
00194 pair<DhtDataMap::iterator, DhtDataMap::iterator> pos =
00195 dataMap.equal_range(key);
00196
00197 while (pos.first != pos.second) {
00198
00199 if (((kind == 0) || (pos.first->second.kind == kind)) &&
00200 ((id == 0) || (pos.first->second.id == id))) {
00201 cancelAndDelete(pos.first->second.ttlMessage);
00202 dataMap.erase(pos.first++);
00203 } else {
00204 ++pos.first;
00205 }
00206 }
00207 }
00208
00209 DhtDumpVector* DHTDataStorage::dumpDht(const OverlayKey& key, uint32_t kind,
00210 uint32_t id)
00211 {
00212 DhtDumpVector* vect = new DhtDumpVector();
00213 DhtDumpEntry entry;
00214
00215 DhtDataMap::iterator iter, end;
00216
00217 if (key.isUnspecified()) {
00218 iter = dataMap.begin();
00219 end = dataMap.end();
00220 } else {
00221 iter = dataMap.lower_bound(key);
00222 end = dataMap.upper_bound(key);
00223 }
00224
00225 for (; iter != end; iter++) {
00226 if (((kind == 0) || (iter->second.kind == kind)) &&
00227 ((id == 0) || (iter->second.id == id))) {
00228
00229 entry.setKey(iter->first);
00230 entry.setKind(iter->second.kind);
00231 entry.setId(iter->second.id);
00232 entry.setValue(iter->second.value);
00233 entry.setTtl((int)SIMTIME_DBL(
00234 iter->second.ttlMessage->getArrivalTime() - simTime()));
00235 entry.setOwnerNode(iter->second.sourceNode);
00236 entry.setIs_modifiable(iter->second.is_modifiable);
00237 entry.setResponsible(iter->second.responsible);
00238 vect->push_back(entry);
00239 }
00240 }
00241
00242 return vect;
00243 }
00244
00245
00246
00247 void DHTDataStorage::updateDisplayString()
00248 {
00249 if (ev.isGUI()) {
00250 char buf[80];
00251
00252 if (dataMap.size() == 1) {
00253 sprintf(buf, "1 data item");
00254 } else {
00255 sprintf(buf, "%zi data items", dataMap.size());
00256 }
00257
00258 getDisplayString().setTagArg("t", 0, buf);
00259 getDisplayString().setTagArg("t", 2, "blue");
00260 }
00261
00262 }
00263
00264
00265 void DHTDataStorage::updateTooltip()
00266 {
00267 if (ev.isGUI()) {
00268 std::stringstream str;
00269
00270 for (DhtDataMap::iterator it = dataMap.begin();
00271 it != dataMap.end(); it++) {
00272 str << it->second.value;
00273 }
00274
00275 str << endl;
00276
00277 char buf[1024];
00278 sprintf(buf, "%s", str.str().c_str());
00279 getDisplayString().setTagArg("tt", 0, buf);
00280 }
00281 }
00282
00283
00284 void DHTDataStorage::display()
00285 {
00286 cout << "Content of DHTDataStorage:" << endl;
00287 for (DhtDataMap::iterator it = dataMap.begin();
00288 it != dataMap.end(); it++) {
00289 cout << "Key: " << it->first << " Kind: " << it->second.kind
00290 << " ID: " << it->second.id << " Value: "
00291 << it->second.value << "End-time: "
00292 << it->second.ttlMessage->getArrivalTime() << endl;
00293 }
00294 }