IBR-DTNSuite  0.10
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 (_filter.contains(id.toString()))
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  ibrcommon::MutexLock l(_transit_lock);
146 
147  // check if enough resources available to transfer the bundle
148  if (_transit_bundles.size() >= dtn::core::BundleCore::max_bundles_in_transit) throw NoMoreTransfersAvailable();
149 
150  // check if the bundle is already in transit
151  if (_transit_bundles.find(id) != _transit_bundles.end()) throw AlreadyInTransitException();
152 
153  // insert the bundle into the transit list
154  _transit_bundles.insert(id);
155 
156  IBRCOMMON_LOGGER_DEBUG_TAG("NeighborDatabase", 20) << "acquire transfer of " << id.toString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL;
157  }
158 
160  {
161  const dtn::data::Size transit_bundles = _transit_bundles.size();
162 
163  if (dtn::core::BundleCore::max_bundles_in_transit <= transit_bundles) return 0;
164  return dtn::core::BundleCore::max_bundles_in_transit - transit_bundles;
165  }
166 
168  {
169  return _transit_bundles.size() <= (dtn::core::BundleCore::max_bundles_in_transit / 2);
170  }
171 
173  {
174  ibrcommon::MutexLock l(_transit_lock);
175  _transit_bundles.erase(id);
176 
177  IBRCOMMON_LOGGER_DEBUG_TAG("NeighborDatabase", 20) << "release transfer of " << id.toString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL;
178  }
179 
181  {
182  pair<data_set::iterator, bool> ret = _datasets.insert( dset );
183 
184  if (!ret.second) {
185  _datasets.erase(ret.first);
186  _datasets.insert( dset );
187  }
188  }
189 
191  {
192  }
193 
195  {
196  ibrcommon::MutexLock l(*this);
197  std::set<dtn::data::EID> ret;
198 
199  for (neighbor_map::const_iterator iter = _entries.begin(); iter != _entries.end(); ++iter)
200  {
201  delete (*iter).second;
202  }
203  }
204 
206  {
207  neighbor_map::iterator iter = _entries.find(eid);
208  if (iter == _entries.end())
209  {
210  NeighborEntry *entry = new NeighborEntry(eid);
211  pair<neighbor_map::iterator,bool> itm = _entries.insert( pair<dtn::data::EID, NeighborDatabase::NeighborEntry*>(eid, entry) );
212  iter = itm.first;
213  }
214 
215  // set last update timestamp
216  (*(*iter).second).touch();
217 
218  return *(*iter).second;
219  }
220 
222  {
223  if (!dtn::core::BundleCore::getInstance().getConnectionManager().isNeighbor(eid))
225 
226  neighbor_map::iterator iter = _entries.find(eid);
227  if (iter == _entries.end())
228  {
230  }
231 
232  // set last update timestamp
233  (*(*iter).second).touch();
234 
235  return *(*iter).second;
236  }
237 
239  {
240  neighbor_map::iterator iter = _entries.find(eid);
241  if (iter == _entries.end())
242  {
243  delete (*iter).second;
244  _entries.erase(iter);
245  }
246  }
247  }
248 }