IBR-DTN  1.0.0
NeighborDatabase.cpp
Go to the documentation of this file.
1 /*
2  * NeighborDatabase.cpp
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
23 #include "core/BundleCore.h"
24 #include <ibrdtn/utils/Clock.h>
25 #include <ibrcommon/Logger.h>
26 #include <limits>
27 
28 namespace dtn
29 {
30  namespace routing
31  {
33  : eid(), _filter(), _filter_expire(0), _filter_state(FILTER_EXPIRED, FILTER_FINAL)
34  {}
35 
37  : eid(e), _filter(), _filter_expire(0), _filter_state(FILTER_EXPIRED, FILTER_FINAL)
38  { }
39 
41  {
42  }
43 
44  void NeighborDatabase::NeighborEntry::update(const ibrcommon::BloomFilter &bf, const dtn::data::Number &lifetime)
45  {
46  ibrcommon::ThreadsafeState<FILTER_REQUEST_STATE>::Locked l = _filter_state.lock();
47  _filter = bf;
48 
49  if (lifetime == 0)
50  {
51  _filter_expire = std::numeric_limits<dtn::data::Size>::max();
52  }
53  else
54  {
55  _filter_expire = dtn::utils::Clock::getExpireTime(lifetime);
56  }
57 
58  l = FILTER_AVAILABLE;
59  }
60 
62  {
63  ibrcommon::ThreadsafeState<FILTER_REQUEST_STATE>::Locked l = _filter_state.lock();
64 
65  l = FILTER_EXPIRED;
66 
67  // do not expire again in the next 60 seconds
68  _filter_expire = dtn::utils::Clock::getTime() + 60;
69  }
70 
72  {
73  _summary.add(bundle);
74  }
75 
76  bool NeighborDatabase::NeighborEntry::has(const dtn::data::BundleID &id, const bool require_bloomfilter) const
77  {
78  if (_filter_state == FILTER_AVAILABLE)
79  {
80  if (id.isIn(_filter))
81  return true;
82  }
83  else if (require_bloomfilter)
84  {
86  }
87 
88  return _summary.has(id);
89  }
90 
92  {
93  return (_filter_state == FILTER_AVAILABLE);
94  }
95 
97  {
98  // expired after 15 minutes
99  return (_last_update + 900) < timestamp;
100  }
101 
103  {
104  return _last_update;
105  }
106 
108  {
109  _last_update = dtn::utils::Clock::getTime();
110  }
111 
113  {
114  {
115  ibrcommon::ThreadsafeState<FILTER_REQUEST_STATE>::Locked l = _filter_state.lock();
116 
117  if ((_filter_expire > 0) && (_filter_expire < timestamp))
118  {
119  IBRCOMMON_LOGGER_DEBUG_TAG("NeighborDatabase", 15) << "summary vector of " << eid.getString() << " is expired" << IBRCOMMON_LOGGER_ENDL;
120 
121  // set the filter state to expired once
122  l = FILTER_EXPIRED;
123 
124  // do not expire again in the next 60 seconds
125  _filter_expire = timestamp + 60;
126  }
127  }
128 
129  _summary.expire(timestamp);
130  }
131 
133  {
134  for (neighbor_map::iterator iter = _entries.begin(); iter != _entries.end(); )
135  {
136  NeighborEntry &entry = (*iter->second);
137 
138  if (entry.isExpired(timestamp)) {
139  delete (*iter).second;
140  _entries.erase(iter++);
141  } else {
142  entry.expire(timestamp);
143  ++iter;
144  }
145  }
146  }
147 
149  {
150  // check if enough resources available to transfer the bundle
151  if (_transit_bundles.size() >= dtn::core::BundleCore::max_bundles_in_transit) throw NoMoreTransfersAvailable();
152 
153  // check if the bundle is already in transit
154  if (_transit_bundles.find(id) != _transit_bundles.end()) throw AlreadyInTransitException();
155 
156  // insert the bundle into the transit list
157  _transit_bundles.insert(id);
158 
159  IBRCOMMON_LOGGER_DEBUG_TAG("NeighborDatabase", 20) << "acquire transfer of " << id.toString() << " to " << eid.getString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL;
160  }
161 
163  {
164  const dtn::data::Size transit_bundles = _transit_bundles.size();
165 
166  if (dtn::core::BundleCore::max_bundles_in_transit <= transit_bundles) return 0;
167  return dtn::core::BundleCore::max_bundles_in_transit - transit_bundles;
168  }
169 
171  {
172  return _transit_bundles.size() <= (dtn::core::BundleCore::max_bundles_in_transit / 2);
173  }
174 
176  {
177  _transit_bundles.erase(id);
178 
179  IBRCOMMON_LOGGER_DEBUG_TAG("NeighborDatabase", 20) << "release transfer of " << id.toString() << " to " << eid.getString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL;
180  }
181 
183  {
184  pair<data_set::iterator, bool> ret = _datasets.insert( dset );
185 
186  if (!ret.second) {
187  _datasets.erase(ret.first);
188  _datasets.insert( dset );
189  }
190  }
191 
193  {
194  }
195 
197  {
198  ibrcommon::MutexLock l(*this);
199  std::set<dtn::data::EID> ret;
200 
201  for (neighbor_map::const_iterator iter = _entries.begin(); iter != _entries.end(); ++iter)
202  {
203  delete (*iter).second;
204  }
205  }
206 
208  {
209  neighbor_map::iterator iter = _entries.find(eid);
210  if (iter == _entries.end())
211  {
212  NeighborEntry *entry = new NeighborEntry(eid);
213  pair<neighbor_map::iterator,bool> itm = _entries.insert( pair<dtn::data::EID, NeighborDatabase::NeighborEntry*>(eid, entry) );
214  iter = itm.first;
215  }
216 
217  // set last update timestamp
218  (*(*iter).second).touch();
219 
220  return *(*iter).second;
221  }
222 
224  {
225  if (noCached && !dtn::core::BundleCore::getInstance().getConnectionManager().isNeighbor(eid))
227 
228  neighbor_map::iterator iter = _entries.find(eid);
229  if (iter == _entries.end())
230  {
231  throw EntryNotFoundException();
232  }
233 
234  // set last update timestamp
235  (*(*iter).second).touch();
236 
237  return *(*iter).second;
238  }
239 
241  {
242  neighbor_map::iterator iter = _entries.find(eid);
243  if (iter == _entries.end())
244  {
245  delete (*iter).second;
246  _entries.erase(iter);
247  }
248  }
249  }
250 }
bool isExpired(const dtn::data::Timestamp &timestamp) const
void add(const dtn::data::MetaBundle &)
const dtn::data::Timestamp & getLastUpdate() const
void remove(const dtn::data::EID &eid)
void expire(const dtn::data::Timestamp &timestamp)
void update(const ibrcommon::BloomFilter &bf, const dtn::data::Number &lifetime=0)
static dtn::data::Timestamp getExpireTime(const dtn::data::Bundle &b)
Definition: Clock.cpp:91
bool has(const dtn::data::BundleID &, const bool require_bloomfilter=false) const
NeighborDatabase::NeighborEntry & get(const dtn::data::EID &eid, bool noCached=false)
void acquireTransfer(const dtn::data::BundleID &id)
static dtn::data::Size max_bundles_in_transit
Definition: BundleCore.h:179
static dtn::data::Timestamp getTime()
Definition: Clock.cpp:167
size_t Size
Definition: Number.h:34
void expire(const dtn::data::Timestamp &timestamp)
NeighborDatabase::NeighborEntry & create(const dtn::data::EID &eid)
static BundleCore & getInstance()
Definition: BundleCore.cpp:82
void releaseTransfer(const dtn::data::BundleID &id)