IBR-DTN  1.0.0
DeliveryPredictabilityMap.cpp
Go to the documentation of this file.
1 /*
2  * DeliveryPredictabilityMap.cpp
3  *
4  * Created on: 08.01.2013
5  * Author: morgenro
6  */
7 
9 #include "core/BundleCore.h"
10 #include <ibrdtn/utils/Clock.h>
11 #include <ibrcommon/Logger.h>
12 #include <vector>
13 
14 namespace dtn
15 {
16  namespace routing
17  {
19 
21  : NeighborDataSetImpl(DeliveryPredictabilityMap::identifier), _beta(0.0), _gamma(0.0), _lastAgingTime(0), _time_unit(0)
22  {
23  }
24 
25  DeliveryPredictabilityMap::DeliveryPredictabilityMap(const size_t &time_unit, const float &beta, const float &gamma)
26  : NeighborDataSetImpl(DeliveryPredictabilityMap::identifier), _beta(beta), _gamma(gamma), _lastAgingTime(0), _time_unit(time_unit)
27  {
28  }
29 
31  }
32 
34  {
35  return identifier;
36  }
37 
39  {
40  dtn::data::Length len = 0;
41  for(predictmap::const_iterator it = _predictmap.begin(); it != _predictmap.end(); ++it)
42  {
43  /* calculate length of the EID */
44  const std::string eid = it->first.getString();
45  dtn::data::Length eid_len = eid.length();
46  len += data::Number(eid_len).getLength() + eid_len;
47 
48  /* calculate length of the float in fixed notation */
49  const float& f = it->second;
50  std::stringstream ss;
51  ss << f << std::flush;
52 
53  dtn::data::Length float_len = ss.str().length();
54  len += data::Number(float_len).getLength() + float_len;
55  }
56  return data::Number(_predictmap.size()).getLength() + len;
57  }
58 
59  std::ostream& DeliveryPredictabilityMap::serialize(std::ostream& stream) const
60  {
61  stream << data::Number(_predictmap.size());
62  for(predictmap::const_iterator it = _predictmap.begin(); it != _predictmap.end(); ++it)
63  {
64  const std::string eid = it->first.getString();
65  stream << data::Number(eid.length()) << eid;
66 
67  const float& f = it->second;
68  /* write f into a stringstream to get final length */
69  std::stringstream ss;
70  ss << f << std::flush;
71 
72  stream << data::Number(ss.str().length());
73  stream << ss.str();
74  }
75  IBRCOMMON_LOGGER_DEBUG_TAG("DeliveryPredictabilityMap", 20) << "Serialized with " << _predictmap.size() << " items." << IBRCOMMON_LOGGER_ENDL;
76  IBRCOMMON_LOGGER_DEBUG_TAG("DeliveryPredictabilityMap", 60) << *this << IBRCOMMON_LOGGER_ENDL;
77  return stream;
78  }
79 
80  std::istream& DeliveryPredictabilityMap::deserialize(std::istream& stream)
81  {
82  data::Number elements_read(0);
83  data::Number map_size;
84  stream >> map_size;
85 
86  while(elements_read < map_size)
87  {
88  /* read the EID */
89  data::Number eid_len;
90  stream >> eid_len;
91 
92  // create a buffer for the EID
93  std::vector<char> eid_cstr(eid_len.get<size_t>());
94 
95  // read the EID string
96  stream.read(&eid_cstr[0], eid_cstr.size());
97 
98  // convert the string into an EID object
99  dtn::data::EID eid(std::string(eid_cstr.begin(), eid_cstr.end()));
100 
101  if(eid == data::EID())
102  throw dtn::InvalidDataException("EID could not be casted, while parsing a dp_map.");
103 
104  /* read the probability (float) */
105  float f;
106  dtn::data::Number float_len;
107  stream >> float_len;
108 
109  // create a buffer for the data string
110  std::vector<char> f_cstr(float_len.get<size_t>());
111 
112  // read the data string
113  stream.read(&f_cstr[0], f_cstr.size());
114 
115  // convert string data into a stringstream
116  std::stringstream ss(std::string(f_cstr.begin(), f_cstr.end()));
117 
118  // convert string data into a float
119  ss >> f;
120  if(ss.fail())
121  throw dtn::InvalidDataException("Float could not be casted, while parsing a dp_map.");
122 
123  /* check if f is in a proper range */
124  if(f < 0 || f > 1)
125  continue;
126 
127  /* insert the data into the map */
128  _predictmap[eid] = f;
129 
130  elements_read += 1;
131  }
132 
133  IBRCOMMON_LOGGER_DEBUG_TAG("DeliveryPredictabilityMap", 20) << "Deserialized with " << _predictmap.size() << " items." << IBRCOMMON_LOGGER_ENDL;
134  IBRCOMMON_LOGGER_DEBUG_TAG("DeliveryPredictabilityMap", 60) << *this << IBRCOMMON_LOGGER_ENDL;
135  return stream;
136  }
137 
139  {
140  predictmap::const_iterator it;
141  if ((it = _predictmap.find(neighbor)) != _predictmap.end())
142  {
143  return it->second;
144  }
145 
146  throw ValueNotFoundException();
147  }
148 
149  void DeliveryPredictabilityMap::set(const dtn::data::EID &neighbor, float value)
150  {
151  _predictmap[neighbor] = value;
152  }
153 
155  {
156  _predictmap.clear();
157  }
158 
160  {
161  return _predictmap.size();
162  }
163 
164  void DeliveryPredictabilityMap::update(const dtn::data::EID &host_b, const DeliveryPredictabilityMap &dpm, const float &p_encounter_first)
165  {
166  float p_ab = 0.0f;
167 
168  try {
169  p_ab = get(host_b);
171  p_ab = p_encounter_first;
172  }
173 
177  for (predictmap::const_iterator it = dpm._predictmap.begin(); it != dpm._predictmap.end(); ++it)
178  {
179  const dtn::data::EID &host_c = it->first;
180  const float &p_bc = it->second;
181 
182  // do not update values for the origin host
183  if (host_b.sameHost(host_c)) continue;
184 
185  // do not process values with our own EID
186  if (dtn::core::BundleCore::local.sameHost(host_c)) continue;
187 
188  predictmap::iterator dp_it;
189  if ((dp_it = _predictmap.find(host_c)) != _predictmap.end()) {
190  dp_it->second = max(dp_it->second, p_ab * p_bc * _beta);
191  } else {
192  _predictmap[host_c] = p_ab * p_bc * _beta;
193  }
194  }
195  }
196 
197  void DeliveryPredictabilityMap::age(const float &p_first_threshold)
198  {
200 
201  // prevent double aging
202  if (current_time <= _lastAgingTime) return;
203 
204  const dtn::data::Timestamp k = (current_time - _lastAgingTime) / _time_unit;
205 
206  predictmap::iterator it;
207  for(it = _predictmap.begin(); it != _predictmap.end();)
208  {
209  if(it->first == dtn::core::BundleCore::local)
210  {
211  ++it;
212  continue;
213  }
214 
215  it->second *= pow(_gamma, k.get<int>());
216 
217  if(it->second < p_first_threshold)
218  {
219  _predictmap.erase(it++);
220  } else {
221  ++it;
222  }
223  }
224 
225  _lastAgingTime = current_time;
226  }
227 
228  void DeliveryPredictabilityMap::toString(std::ostream &stream) const
229  {
230  predictmap::const_iterator it;
231  for (it = _predictmap.begin(); it != _predictmap.end(); ++it)
232  {
233  stream << it->first.getString() << ": " << it->second << std::endl;
234  }
235  }
236 
237  std::ostream& operator<<(std::ostream& stream, const DeliveryPredictabilityMap& map)
238  {
239  map.toString(stream);
240  return stream;
241  }
242 
243  void DeliveryPredictabilityMap::store(std::ostream &output) const
244  {
245  // get the current monotonic time-stamp difference
247 
248  // get a absolute time-stamp
249  const dtn::data::Timestamp absAgingTime = monotonic_diff + _lastAgingTime;
250 
251  // write last aged time-stamp
252  output << absAgingTime;
253 
254  // store the number of map entries
255  output << dtn::data::Number(_predictmap.size());
256 
257  for (predictmap::const_iterator it = _predictmap.begin(); it != _predictmap.end(); ++it)
258  {
259  const dtn::data::EID &peer = it->first;
260  const float &p_value = it->second;
261 
262  dtn::data::BundleString peer_entry(peer.getString());
263 
264  // write EID
265  output << peer_entry;
266 
267  // write float value
268  output.write(static_cast<const char*>((const char*)&p_value), sizeof(p_value));
269  }
270  }
271 
272  void DeliveryPredictabilityMap::restore(std::istream &input)
273  {
274  // clear the map
275  _predictmap.clear();
276 
277  // get a absolute time-stamp
278  dtn::data::Timestamp absAgingTime;
279 
280  // read last aged time-stamp
281  input >> absAgingTime;
282 
283  // get the current monotonic time-stamp difference
286 
287  // eliminate time-stamp which are in the future
288  if (monotonic_now >= (absAgingTime - monotonic_diff))
289  {
290  // add entry to the map
291  _lastAgingTime = absAgingTime - monotonic_diff;
292  }
293  else
294  {
295  // add entry to the map
296  _lastAgingTime = monotonic_now;
297  }
298 
299  dtn::data::Number num_entries;
300  input >> num_entries;
301 
302  // silently fail
303  while (input.good() && num_entries > 0)
304  {
305  dtn::data::BundleString peer_entry;
306  float p_value = 0.0;
307 
308  input >> peer_entry;
309  input.read(static_cast<char*>((char*)&p_value), sizeof(p_value));
310 
311  // add entry to the map
312  _predictmap[dtn::data::EID(peer_entry)] = p_value;
313 
314  num_entries--;
315  }
316  }
317  } /* namespace routing */
318 } /* namespace dtn */
void update(const dtn::data::EID &origin, const DeliveryPredictabilityMap &dpm, const float &p_encounter_first)
static dtn::data::EID local
Definition: BundleCore.h:79
bool sameHost(const std::string &other) const
Definition: EID.cpp:322
size_t Length
Definition: Number.h:33
void set(const dtn::data::EID &neighbor, float value)
This class keeps track of the predictablities to see a specific EID.
virtual std::ostream & serialize(std::ostream &stream) const
size_t getLength() const
Definition: SDNV.h:99
virtual dtn::data::Length getLength() const
T get() const
Definition: SDNV.h:113
static dtn::data::Timestamp getTime()
Definition: Clock.cpp:167
virtual const dtn::data::Number & getIdentifier() const
std::string getString() const
Definition: EID.cpp:374
std::ostream & operator<<(std::ostream &stream, const NodeHandshake &hs)
void age(const float &p_first_threshold)
static dtn::data::Timestamp getMonotonicTimestamp()
Definition: Clock.cpp:175
virtual std::istream & deserialize(std::istream &stream)
dtn::data::SDNV< Size > Number
Definition: Number.h:38
float get(const dtn::data::EID &neighbor) const