DHTDataStorage.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2007 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
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     // insert new record in sorted multimap (order: key, kind, id)
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 // TODO: not used ?
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 // TODO: not used ?
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 // TODO: not used ?
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 }
Generated on Wed May 26 16:21:14 2010 for OverSim by  doxygen 1.6.3