IBR-DTNSuite  0.10
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 
159  void DeliveryPredictabilityMap::update(const dtn::data::EID &origin, const DeliveryPredictabilityMap &dpm, const float &p_encounter_first)
160  {
161  float neighbor_dp = p_encounter_first;
162 
163  try {
164  neighbor_dp = this->get(origin);
166 
170  for (predictmap::const_iterator it = dpm._predictmap.begin(); it != dpm._predictmap.end(); ++it)
171  {
172  if ((it->first != origin) && (it->first != dtn::core::BundleCore::local))
173  {
174  float dp = 0;
175 
176  predictmap::iterator dp_it;
177  if((dp_it = _predictmap.find(it->first)) != _predictmap.end())
178  dp = dp_it->second;
179 
180  dp = max(dp, neighbor_dp * it->second * _beta);
181 
182  if(dp_it != _predictmap.end())
183  dp_it->second = dp;
184  else
185  _predictmap[it->first] = dp;
186  }
187  }
188  }
189 
190  void DeliveryPredictabilityMap::age(const float &p_first_threshold)
191  {
193 
194  // prevent double aging
195  if (current_time <= _lastAgingTime) return;
196 
197  const dtn::data::Timestamp k = (current_time - _lastAgingTime) / _time_unit;
198 
199  predictmap::iterator it;
200  for(it = _predictmap.begin(); it != _predictmap.end();)
201  {
202  if(it->first == dtn::core::BundleCore::local)
203  {
204  ++it;
205  continue;
206  }
207 
208  it->second *= pow(_gamma, k.get<int>());
209 
210  if(it->second < p_first_threshold)
211  {
212  _predictmap.erase(it++);
213  } else {
214  ++it;
215  }
216  }
217 
218  _lastAgingTime = current_time;
219  }
220 
221  void DeliveryPredictabilityMap::toString(std::ostream &stream) const
222  {
223  predictmap::const_iterator it;
224  for (it = _predictmap.begin(); it != _predictmap.end(); ++it)
225  {
226  stream << it->first.getString() << ": " << it->second << std::endl;
227  }
228  }
229 
230  std::ostream& operator<<(std::ostream& stream, const DeliveryPredictabilityMap& map)
231  {
232  map.toString(stream);
233  return stream;
234  }
235  } /* namespace routing */
236 } /* namespace dtn */