IBR-DTNSuite  0.10
MemoryBundleStorage.cpp
Go to the documentation of this file.
1 /*
2  * MemoryBundleStorage.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/EventDispatcher.h"
24 #include "core/TimeEvent.h"
25 #include "core/GlobalEvent.h"
27 #include "core/BundleEvent.h"
28 
29 #include <ibrdtn/utils/Clock.h>
30 
31 #include <ibrcommon/Logger.h>
33 
34 namespace dtn
35 {
36  namespace storage
37  {
38  const std::string MemoryBundleStorage::TAG = "MemoryBundleStorage";
39 
41  : BundleStorage(maxsize), _list(this)
42  {
43  }
44 
46  {
47  }
48 
50  {
51  // routine checked for throw() on 15.02.2013
53  }
54 
56  {
57  // routine checked for throw() on 15.02.2013
59  }
60 
62  {
63  try {
64  const dtn::core::TimeEvent &time = dynamic_cast<const dtn::core::TimeEvent&>(*evt);
66  {
67  // do expiration of bundles
68  ibrcommon::MutexLock l(_bundleslock);
69  _list.expire(time.getTimestamp());
70  }
71  } catch (const std::bad_cast&) { }
72  }
73 
74  const std::string MemoryBundleStorage::getName() const
75  {
77  }
78 
80  {
81  ibrcommon::MutexLock l(_bundleslock);
82  return _bundles.empty();
83  }
84 
86  {
87  // custody is successful transferred to another node.
88  // it is safe to delete this bundle now. (depending on the routing algorithm.)
89  }
90 
92  {
93  ibrcommon::MutexLock l(_bundleslock);
94  return _bundles.size();
95  }
96 
98  {
99  size_t items_added = 0;
100 
101  // we have to iterate through all bundles
102  ibrcommon::MutexLock l(_bundleslock);
103 
104  for (prio_bundle_set::const_iterator iter = _priority_index.begin(); (iter != _priority_index.end()) && ((cb.limit() == 0) || (items_added < cb.limit())); ++iter)
105  {
106  const dtn::data::MetaBundle &bundle = (*iter);
107 
108  // skip expired bundles
109  if ( dtn::utils::Clock::isExpired( bundle.timestamp, bundle.lifetime ) ) continue;
110 
111  if ( cb.shouldAdd(bundle) )
112  {
113  result.put(bundle);
114  items_added++;
115  }
116  }
117 
118  if (items_added == 0) throw NoBundleFoundException();
119  }
120 
122  {
123  try {
124  ibrcommon::MutexLock l(_bundleslock);
125 
126  for (bundle_list::const_iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
127  {
128  const dtn::data::Bundle &bundle = (*iter);
129  if (id == bundle)
130  {
131  if (_faulty) {
132  throw dtn::SerializationFailedException("bundle get failed due to faulty setting");
133  }
134 
135  return bundle;
136  }
137  }
138  } catch (const dtn::SerializationFailedException &ex) {
139  // bundle loading failed
140  IBRCOMMON_LOGGER_TAG(MemoryBundleStorage::TAG, error) << "Error while loading bundle data: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
141 
142  // the bundle is broken, delete it
143  remove(id);
144 
146  }
147 
148  throw NoBundleFoundException();
149  }
150 
152  {
153  std::set<dtn::data::EID> ret;
154 
155  ibrcommon::MutexLock l(_bundleslock);
156 
157  for (bundle_list::const_iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
158  {
159  const dtn::data::Bundle &bundle = (*iter);
160  ret.insert(bundle.destination);
161  }
162 
163  return ret;
164  }
165 
167  {
168  ibrcommon::MutexLock l(_bundleslock);
169 
170  if (_faulty) return;
171 
172  // get size of the bundle
173  dtn::data::DefaultSerializer s(std::cout);
174  dtn::data::Length size = s.getLength(bundle);
175 
176  // increment the storage size
177  allocSpace(size);
178 
179  // insert Container
180  pair<set<dtn::data::Bundle>::iterator,bool> ret = _bundles.insert( bundle );
181 
182  if (ret.second)
183  {
184  _list.add(dtn::data::MetaBundle(bundle));
185  _priority_index.insert( bundle );
186 
187  _bundle_lengths[bundle] = size;
188 
189  // raise bundle added event
190  eventBundleAdded(bundle);
191  }
192  else
193  {
194  // free the previously allocated space
195  freeSpace(size);
196 
197  IBRCOMMON_LOGGER_DEBUG_TAG(MemoryBundleStorage::TAG, 5) << "got bundle duplicate " << bundle.toString() << IBRCOMMON_LOGGER_ENDL;
198  }
199  }
200 
202  {
203  ibrcommon::MutexLock l(_bundleslock);
204 
205  // search for the bundle in the bundle list
206  const bundle_list::const_iterator iter = find(_bundles.begin(), _bundles.end(), id);
207 
208  // if no bundle was found throw an exception
209  if (iter == _bundles.end()) throw NoBundleFoundException();
210 
211  // remove item in the bundlelist
212  const dtn::data::Bundle &bundle = (*iter);
213  _list.remove(bundle);
214 
215  // raise bundle removed event
216  eventBundleRemoved(bundle);
217 
218  // erase the bundle
219  __erase(iter);
220  }
221 
223  {
224  ibrcommon::MutexLock l(_bundleslock);
225 
226  for (bundle_list::iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
227  {
228  if ( filter.contains((*iter).toString()) )
229  {
230  const dtn::data::MetaBundle bundle = (*iter);
231 
232  // remove item in the bundlelist
233  _list.remove(bundle);
234 
235  // raise bundle removed event
236  eventBundleRemoved(bundle);
237 
238  // erase the bundle
239  __erase(iter);
240 
241  return bundle;
242  }
243  }
244 
245  throw NoBundleFoundException();
246  }
247 
249  {
250  ibrcommon::MutexLock l(_bundleslock);
251 
252  for (bundle_list::const_iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
253  {
254  const dtn::data::Bundle &bundle = (*iter);
255 
256  // raise bundle removed event
257  eventBundleRemoved(bundle);
258  }
259 
260  _bundles.clear();
261  _priority_index.clear();
262  _list.clear();
263  _bundle_lengths.clear();
264 
265  // set the storage size to zero
266  clearSpace();
267  }
268 
270  {
271  // search for the bundle in the bundle list
272  const bundle_list::iterator iter = find(_bundles.begin(), _bundles.end(), b);
273 
274  // if the bundle was found ...
275  if (iter != _bundles.end())
276  {
277  // raise bundle removed event
278  eventBundleRemoved(b);
279 
280  // raise bundle event
282 
283  // raise an event
285 
286  // erase the bundle
287  __erase(iter);
288  }
289  }
290 
291  void MemoryBundleStorage::__erase(const bundle_list::iterator &iter)
292  {
293  const dtn::data::Bundle &bundle = (*iter);
294 
295  // erase the bundle out of the priority index
296  _priority_index.erase(bundle);
297 
298  // get the storage size of this bundle
299  dtn::data::Length len = _bundle_lengths[bundle];
300  _bundle_lengths.erase(bundle);
301 
302  // decrement the storage size
303  freeSpace(len);
304 
305  // remove bundle from bundle list
306  _bundles.erase(iter);
307  }
308  }
309 }