IBR-DTNSuite  0.12
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  {
76  return MemoryBundleStorage::TAG;
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 ) ) 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  {
185  _list.add(m);
186  _priority_index.insert(m);
187 
188  _bundle_lengths[m] = size;
189 
190  // raise bundle added event
191  eventBundleAdded(m);
192  }
193  else
194  {
195  // free the previously allocated space
196  freeSpace(size);
197 
198  IBRCOMMON_LOGGER_DEBUG_TAG(MemoryBundleStorage::TAG, 5) << "got bundle duplicate " << bundle.toString() << IBRCOMMON_LOGGER_ENDL;
199  }
200  }
201 
203  {
204  ibrcommon::MutexLock l(_bundleslock);
205  return (_bundle_lengths.find(id) != _bundle_lengths.end());
206  }
207 
209  {
210  ibrcommon::MutexLock l(_bundleslock);
211 
212  for (dtn::data::BundleList::const_iterator iter = _list.begin(); iter != _list.end(); ++iter)
213  {
214  const dtn::data::MetaBundle &meta = (*iter);
215  if (id == meta)
216  {
217  return meta;
218  }
219  }
220 
221  throw NoBundleFoundException();
222  }
223 
225  {
226  ibrcommon::MutexLock l(_bundleslock);
227 
228  // search for the bundle in the bundle list
229  const bundle_list::const_iterator iter = find(_bundles.begin(), _bundles.end(), id);
230 
231  // if no bundle was found throw an exception
232  if (iter == _bundles.end()) throw NoBundleFoundException();
233 
234  // remove item in the bundlelist
236  _list.remove(m);
237 
238  // raise bundle removed event
240 
241  // erase the bundle
242  __erase(iter);
243  }
244 
246  {
247  ibrcommon::MutexLock l(_bundleslock);
248 
249  for (bundle_list::const_iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
250  {
251  const dtn::data::Bundle &bundle = (*iter);
252 
253  // raise bundle removed event
254  eventBundleRemoved(bundle);
255  }
256 
257  _bundles.clear();
258  _priority_index.clear();
259  _list.clear();
260  _bundle_lengths.clear();
261 
262  // set the storage size to zero
263  clearSpace();
264  }
265 
267  {
268  // search for the bundle in the bundle list
269  const bundle_list::iterator iter = find(_bundles.begin(), _bundles.end(), b);
270 
271  // if the bundle was found ...
272  if (iter != _bundles.end())
273  {
274  // raise bundle removed event
275  eventBundleRemoved(b);
276 
277  // raise bundle event
279 
280  // raise an event
282 
283  // erase the bundle
284  __erase(iter);
285  }
286  }
287 
288  void MemoryBundleStorage::__erase(const bundle_list::iterator &iter)
289  {
291 
292  // erase the bundle out of the priority index
293  _priority_index.erase(m);
294 
295  // get the storage size of this bundle
296  dtn::data::Length len = _bundle_lengths[m];
297  _bundle_lengths.erase(m);
298 
299  // decrement the storage size
300  freeSpace(len);
301 
302  // remove bundle from bundle list
303  _bundles.erase(iter);
304  }
305  }
306 }