OverSim
DHTDataStorage.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 <hashWatch.h>
26 
27 #include "DHTDataStorage.h"
28 
30 
31 using namespace std;
32 
33 std::ostream& operator<<(std::ostream& os, const DhtDataEntry entry)
34 {
35  os << "Value: " << entry.value
36  << " Kind: " << entry.kind
37  << " ID: " << entry.id
38  << " Endtime: " << entry.ttlMessage->getArrivalTime()
39  << " Responsible: " << entry.responsible
40  << " SourceNode: " << entry.sourceNode;
41 
42  if (entry.siblingVote.size()) {
43  os << " siblingVote:";
44 
45  for (SiblingVoteMap::const_iterator it = entry.siblingVote.begin();
46  it != entry.siblingVote.end(); it++) {
47  os << " " << it->first << " (" << it->second.size() << ")";
48  }
49  }
50  return os;
51 }
52 
53 
55 {
56  if (stage != MIN_STAGE_APP)
57  return;
58 
59  WATCH_MULTIMAP(dataMap);
60 }
61 
62 void DHTDataStorage::handleMessage(cMessage* msg)
63 {
64  error("This module doesn't handle messages!");
65 }
66 
68 {
69  map<OverlayKey, DhtDataEntry>::iterator iter;
70 
71  for( iter = dataMap.begin(); iter != dataMap.end(); iter++ ) {
72  cancelAndDelete(iter->second.ttlMessage);
73  }
74 
75  dataMap.clear();
76 }
77 
78 
80 {
81  return dataMap.size();
82 }
83 
85  uint32_t kind, uint32_t id)
86 {
87  pair<DhtDataMap::iterator, DhtDataMap::iterator> pos =
88  dataMap.equal_range(key);
89 
90  while (pos.first != pos.second) {
91  if ((pos.first->second.kind == kind) &&
92  (pos.first->second.id == id)) {
93  return &pos.first->second;
94  }
95  ++pos.first;
96  }
97 
98  return NULL;
99 }
100 
101 
102 
104  uint32_t kind, uint32_t id)
105 {
106  DhtDataVector* vect = new DhtDataVector();
107  DhtDataEntry entry;
108 
109  pair<DhtDataMap::iterator, DhtDataMap::iterator> pos =
110  dataMap.equal_range(key);
111 
112  while (pos.first != pos.second) {
113  entry = pos.first->second;
114  vect->push_back(make_pair(key, entry));
115  ++pos.first;
116  }
117 
118  return vect;
119 }
120 
121 
123  uint32_t kind, uint32_t id)
124 {
125  DhtDataEntry* entry = getDataEntry(key, kind, id);
126 
127  if (entry == NULL)
129  else
130  return entry->sourceNode;
131 }
132 
134  uint32_t kind, uint32_t id)
135 {
136  DhtDataEntry* entry = getDataEntry(key, kind, id);
137 
138  if (entry == NULL)
139  return true;
140  else
141  return entry->is_modifiable;
142 }
143 
144 
145 const DhtDataMap::iterator DHTDataStorage::begin()
146 {
147  return dataMap.begin();
148 }
149 
150 const DhtDataMap::iterator DHTDataStorage::end()
151 {
152  return dataMap.end();
153 }
154 
156  uint32_t id,
157  BinaryValue value, cMessage* ttlMessage,
158  bool is_modifiable, NodeHandle sourceNode,
159  bool responsible)
160 {
161  DhtDataEntry entry;
162  entry.kind = kind;
163  entry.id = id;
164  entry.value = value;
165  entry.ttlMessage = ttlMessage;
166  entry.sourceNode = sourceNode;
167  entry.is_modifiable = is_modifiable;
168  entry.responsible = responsible;
169 
170  if ((kind == 0) || (id == 0)) {
171  throw cRuntimeError("DHTDataStorage::addData(): "
172  "Not allowed to add data with kind = 0 or id = 0!");
173  }
174 
175  pair<DhtDataMap::iterator, DhtDataMap::iterator> pos =
176  dataMap.equal_range(key);
177 
178  // insert new record in sorted multimap (order: key, kind, id)
179  while ((pos.first != pos.second) && (pos.first->second.kind < kind)) {
180  ++pos.first;
181  }
182 
183  while ((pos.first != pos.second) && (pos.first->second.kind == kind)
184  && (pos.first->second.id < id)) {
185  ++pos.first;
186  }
187 
188  return &(dataMap.insert(pos.first, make_pair(key, entry))->second);
189 }
190 
191 void DHTDataStorage::removeData(const OverlayKey& key, uint32_t kind,
192  uint32_t id)
193 {
194  pair<DhtDataMap::iterator, DhtDataMap::iterator> pos =
195  dataMap.equal_range(key);
196 
197  while (pos.first != pos.second) {
198 
199  if (((kind == 0) || (pos.first->second.kind == kind)) &&
200  ((id == 0) || (pos.first->second.id == id))) {
201  cancelAndDelete(pos.first->second.ttlMessage);
202  dataMap.erase(pos.first++);
203  } else {
204  ++pos.first;
205  }
206  }
207 }
208 
210  uint32_t id)
211 {
212  DhtDumpVector* vect = new DhtDumpVector();
213  DhtDumpEntry entry;
214 
215  DhtDataMap::iterator iter, end;
216 
217  if (key.isUnspecified()) {
218  iter = dataMap.begin();
219  end = dataMap.end();
220  } else {
221  iter = dataMap.lower_bound(key);
222  end = dataMap.upper_bound(key);
223  }
224 
225  for (; iter != end; iter++) {
226  if (((kind == 0) || (iter->second.kind == kind)) &&
227  ((id == 0) || (iter->second.id == id))) {
228 
229  entry.setKey(iter->first);
230  entry.setKind(iter->second.kind);
231  entry.setId(iter->second.id);
232  entry.setValue(iter->second.value);
233  entry.setTtl((int)SIMTIME_DBL(
234  iter->second.ttlMessage->getArrivalTime() - simTime()));
235  entry.setOwnerNode(iter->second.sourceNode);
236  entry.setIs_modifiable(iter->second.is_modifiable);
237  entry.setResponsible(iter->second.responsible);
238  vect->push_back(entry);
239  }
240  }
241 
242  return vect;
243 }
244 
245 
246 // TODO: not used ?
248 {
249  if (ev.isGUI()) {
250  char buf[80];
251 
252  if (dataMap.size() == 1) {
253  sprintf(buf, "1 data item");
254  } else {
255  sprintf(buf, "%zi data items", dataMap.size());
256  }
257 
258  getDisplayString().setTagArg("t", 0, buf);
259  getDisplayString().setTagArg("t", 2, "blue");
260  }
261 
262 }
263 
264 // TODO: not used ?
266 {
267  if (ev.isGUI()) {
268  std::stringstream str;
269 
270  for (DhtDataMap::iterator it = dataMap.begin();
271  it != dataMap.end(); it++) {
272  str << it->second.value;
273  }
274 
275  str << endl;
276 
277  char buf[1024];
278  sprintf(buf, "%s", str.str().c_str());
279  getDisplayString().setTagArg("tt", 0, buf);
280  }
281 }
282 
283 // TODO: not used ?
285 {
286  cout << "Content of DHTDataStorage:" << endl;
287  for (DhtDataMap::iterator it = dataMap.begin();
288  it != dataMap.end(); it++) {
289  cout << "Key: " << it->first << " Kind: " << it->second.kind
290  << " ID: " << it->second.id << " Value: "
291  << it->second.value << "End-time: "
292  << it->second.ttlMessage->getArrivalTime() << endl;
293  }
294 }