IBR-DTNSuite  0.12
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 
45  {
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  {
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  // expired after 15 minutes
94  return (_last_update + 900) < timestamp;
95  }
96 
98  {
99  return _last_update;
100  }
101 
103  {
104  _last_update = dtn::utils::Clock::getTime();
105  }
106 
108  {
109  {
111 
112  if ((_filter_expire > 0) && (_filter_expire < timestamp))
113  {
114  IBRCOMMON_LOGGER_DEBUG_TAG("NeighborDatabase", 15) << "summary vector of " << eid.getString() << " is expired" << IBRCOMMON_LOGGER_ENDL;
115 
116  // set the filter state to expired once
117  l = FILTER_EXPIRED;
118 
119  // do not expire again in the next 60 seconds
120  _filter_expire = timestamp + 60;
121  }
122  }
123 
124  _summary.expire(timestamp);
125  }
126 
128  {
129  for (neighbor_map::iterator iter = _entries.begin(); iter != _entries.end(); )
130  {
131  NeighborEntry &entry = (*iter->second);
132 
133  if (entry.isExpired(timestamp)) {
134  delete (*iter).second;
135  _entries.erase(iter++);
136  } else {
137  entry.expire(timestamp);
138  ++iter;
139  }
140  }
141  }
142 
144  {
145  // check if enough resources available to transfer the bundle
146  if (_transit_bundles.size() >= dtn::core::BundleCore::max_bundles_in_transit) throw NoMoreTransfersAvailable();
147 
148  // check if the bundle is already in transit
149  if (_transit_bundles.find(id) != _transit_bundles.end()) throw AlreadyInTransitException();
150 
151  // insert the bundle into the transit list
152  _transit_bundles.insert(id);
153 
154  IBRCOMMON_LOGGER_DEBUG_TAG("NeighborDatabase", 20) << "acquire transfer of " << id.toString() << " to " << eid.getString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL;
155  }
156 
158  {
159  const dtn::data::Size transit_bundles = _transit_bundles.size();
160 
161  if (dtn::core::BundleCore::max_bundles_in_transit <= transit_bundles) return 0;
162  return dtn::core::BundleCore::max_bundles_in_transit - transit_bundles;
163  }
164 
166  {
167  return _transit_bundles.size() <= (dtn::core::BundleCore::max_bundles_in_transit / 2);
168  }
169 
171  {
172  _transit_bundles.erase(id);
173 
174  IBRCOMMON_LOGGER_DEBUG_TAG("NeighborDatabase", 20) << "release transfer of " << id.toString() << " to " << eid.getString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL;
175  }
176 
178  {
179  pair<data_set::iterator, bool> ret = _datasets.insert( dset );
180 
181  if (!ret.second) {
182  _datasets.erase(ret.first);
183  _datasets.insert( dset );
184  }
185  }
186 
188  {
189  }
190 
192  {
193  ibrcommon::MutexLock l(*this);
194  std::set<dtn::data::EID> ret;
195 
196  for (neighbor_map::const_iterator iter = _entries.begin(); iter != _entries.end(); ++iter)
197  {
198  delete (*iter).second;
199  }
200  }
201 
203  {
204  neighbor_map::iterator iter = _entries.find(eid);
205  if (iter == _entries.end())
206  {
207  NeighborEntry *entry = new NeighborEntry(eid);
208  pair<neighbor_map::iterator,bool> itm = _entries.insert( pair<dtn::data::EID, NeighborDatabase::NeighborEntry*>(eid, entry) );
209  iter = itm.first;
210  }
211 
212  // set last update timestamp
213  (*(*iter).second).touch();
214 
215  return *(*iter).second;
216  }
217 
219  {
220  if (noCached && !dtn::core::BundleCore::getInstance().getConnectionManager().isNeighbor(eid))
222 
223  neighbor_map::iterator iter = _entries.find(eid);
224  if (iter == _entries.end())
225  {
227  }
228 
229  // set last update timestamp
230  (*(*iter).second).touch();
231 
232  return *(*iter).second;
233  }
234 
236  {
237  neighbor_map::iterator iter = _entries.find(eid);
238  if (iter == _entries.end())
239  {
240  delete (*iter).second;
241  _entries.erase(iter);
242  }
243  }
244  }
245 }