IBR-DTN  1.0.0
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"
25 #include "core/BundleEvent.h"
26 
27 #include <ibrdtn/utils/Clock.h>
28 
29 #include <ibrcommon/Logger.h>
30 #include <ibrcommon/thread/MutexLock.h>
31 
32 namespace dtn
33 {
34  namespace storage
35  {
36  const std::string MemoryBundleStorage::TAG = "MemoryBundleStorage";
37 
39  : BundleStorage(maxsize), _list(this)
40  {
41  }
42 
44  {
45  }
46 
48  {
49  // routine checked for throw() on 15.02.2013
51  }
52 
54  {
55  // routine checked for throw() on 15.02.2013
57  }
58 
60  {
61  if (time.getAction() == dtn::core::TIME_SECOND_TICK)
62  {
63  // do expiration of bundles
64  ibrcommon::MutexLock l(_bundleslock);
65  _list.expire(time.getTimestamp());
66  }
67  }
68 
69  const std::string MemoryBundleStorage::getName() const
70  {
71  return MemoryBundleStorage::TAG;
72  }
73 
75  {
76  ibrcommon::MutexLock l(_bundleslock);
77  return _bundles.empty();
78  }
79 
81  {
82  // custody is successful transferred to another node.
83  // it is safe to delete this bundle now. (depending on the routing algorithm.)
84  }
85 
87  {
88  ibrcommon::MutexLock l(_bundleslock);
89  return _bundles.size();
90  }
91 
93  {
94  size_t items_added = 0;
95 
96  // we have to iterate through all bundles
97  ibrcommon::MutexLock l(_bundleslock);
98 
99  for (prio_bundle_set::const_iterator iter = _priority_index.begin(); (iter != _priority_index.end()) && ((cb.limit() == 0) || (items_added < cb.limit())); ++iter)
100  {
101  const dtn::data::MetaBundle &bundle = (*iter);
102 
103  // skip expired bundles
104  if ( dtn::utils::Clock::isExpired( bundle ) ) continue;
105 
106  if ( cb.addIfSelected(result, bundle) ) items_added++;
107  }
108 
109  if (items_added == 0) throw NoBundleFoundException();
110  }
111 
113  {
114  try {
115  ibrcommon::MutexLock l(_bundleslock);
116 
117  for (bundle_list::const_iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
118  {
119  const dtn::data::Bundle &bundle = (*iter);
120  if (id == bundle)
121  {
122  if (_faulty) {
123  throw dtn::SerializationFailedException("bundle get failed due to faulty setting");
124  }
125 
126  return bundle;
127  }
128  }
129  } catch (const dtn::SerializationFailedException &ex) {
130  // bundle loading failed
131  IBRCOMMON_LOGGER_TAG(MemoryBundleStorage::TAG, error) << "Error while loading bundle data: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
132 
133  // the bundle is broken, delete it
134  remove(id);
135 
137  }
138 
139  throw NoBundleFoundException();
140  }
141 
143  {
144  std::set<dtn::data::EID> ret;
145 
146  ibrcommon::MutexLock l(_bundleslock);
147 
148  for (bundle_list::const_iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
149  {
150  const dtn::data::Bundle &bundle = (*iter);
151  ret.insert(bundle.destination);
152  }
153 
154  return ret;
155  }
156 
158  {
159  ibrcommon::MutexLock l(_bundleslock);
160 
161  if (_faulty) return;
162 
163  // get size of the bundle
164  dtn::data::DefaultSerializer s(std::cout);
165  dtn::data::Length size = s.getLength(bundle);
166 
167  // increment the storage size
168  allocSpace(size);
169 
170  // insert Container
171  pair<set<dtn::data::Bundle>::iterator,bool> ret = _bundles.insert( bundle );
172 
173  if (ret.second)
174  {
176  _list.add(m);
177  _priority_index.insert(m);
178 
179  _bundle_lengths[m] = size;
180 
181  // raise bundle added event
182  eventBundleAdded(m);
183  }
184  else
185  {
186  // free the previously allocated space
187  freeSpace(size);
188 
189  IBRCOMMON_LOGGER_DEBUG_TAG(MemoryBundleStorage::TAG, 5) << "got bundle duplicate " << bundle.toString() << IBRCOMMON_LOGGER_ENDL;
190  }
191  }
192 
194  {
195  ibrcommon::MutexLock l(_bundleslock);
196  return (_bundle_lengths.find(id) != _bundle_lengths.end());
197  }
198 
200  {
201  ibrcommon::MutexLock l(_bundleslock);
202 
203  for (dtn::data::BundleList::const_iterator iter = _list.begin(); iter != _list.end(); ++iter)
204  {
205  const dtn::data::MetaBundle &meta = (*iter);
206  if (id == meta)
207  {
208  return meta;
209  }
210  }
211 
212  throw NoBundleFoundException();
213  }
214 
216  {
217  ibrcommon::MutexLock l(_bundleslock);
218 
219  // search for the bundle in the bundle list
220  const bundle_list::const_iterator iter = find(_bundles.begin(), _bundles.end(), id);
221 
222  // if no bundle was found throw an exception
223  if (iter == _bundles.end()) throw NoBundleFoundException();
224 
225  // remove item in the bundlelist
227  _list.remove(m);
228 
229  // raise bundle removed event
231 
232  // erase the bundle
233  __erase(iter);
234  }
235 
237  {
238  ibrcommon::MutexLock l(_bundleslock);
239 
240  for (bundle_list::const_iterator iter = _bundles.begin(); iter != _bundles.end(); ++iter)
241  {
242  const dtn::data::Bundle &bundle = (*iter);
243 
244  // raise bundle removed event
245  eventBundleRemoved(bundle);
246  }
247 
248  _bundles.clear();
249  _priority_index.clear();
250  _list.clear();
251  _bundle_lengths.clear();
252 
253  // set the storage size to zero
254  clearSpace();
255  }
256 
258  {
259  // search for the bundle in the bundle list
260  const bundle_list::iterator iter = find(_bundles.begin(), _bundles.end(), b);
261 
262  // if the bundle was found ...
263  if (iter != _bundles.end())
264  {
265  // raise bundle removed event
266  eventBundleRemoved(b);
267 
268  // raise bundle event
270 
271  // raise an event
273 
274  // erase the bundle
275  __erase(iter);
276  }
277  }
278 
279  void MemoryBundleStorage::__erase(const bundle_list::iterator &iter)
280  {
282 
283  // erase the bundle out of the priority index
284  _priority_index.erase(m);
285 
286  // get the storage size of this bundle
287  dtn::data::Length len = _bundle_lengths[m];
288  _bundle_lengths.erase(m);
289 
290  // decrement the storage size
291  freeSpace(len);
292 
293  // remove bundle from bundle list
294  _bundles.erase(iter);
295  }
296  }
297 }
std::string toString() const
Definition: BundleID.cpp:190
virtual dtn::data::MetaBundle info(const dtn::data::BundleID &id)
static void add(EventReceiver< E > *receiver)
std::set< dtn::data::EID > eid_set
Definition: BundleSeeker.h:39
dtn::data::Length size() const
virtual dtn::data::Bundle get(const dtn::data::BundleID &id)
virtual Length getLength(const dtn::data::Bundle &obj)
Definition: Serializer.cpp:382
size_t Length
Definition: Number.h:33
void remove(const dtn::data::BundleID &id)
virtual void store(const dtn::data::Bundle &bundle)
MemoryBundleStorage(const dtn::data::Length maxsize=0)
static void remove(const EventReceiver< E > *receiver)
void releaseCustody(const dtn::data::EID &custodian, const dtn::data::BundleID &id)
virtual const eid_set getDistinctDestinations()
virtual bool contains(const dtn::data::BundleID &id)
void freeSpace(const dtn::data::Length &size)
T & insert(iterator before)
Definition: Bundle.h:200
static void raise(const dtn::data::Bundle &bundle)
void allocSpace(const dtn::data::Length &size)
void eventBundleAdded(const dtn::data::MetaBundle &b)
virtual void remove(const dtn::data::MetaBundle &bundle)
Definition: BundleList.cpp:49
virtual const std::string getName() const
void eventBundleRemoved(const dtn::data::BundleID &id)
size_t Size
Definition: Number.h:34
static void raise(const dtn::data::MetaBundle &bundle, EventBundleAction action, dtn::data::StatusReportBlock::REASON_CODE reason=dtn::data::StatusReportBlock::NO_ADDITIONAL_INFORMATION)
Definition: BundleEvent.cpp:78
static MetaBundle create(const dtn::data::BundleID &id)
Definition: MetaBundle.cpp:34
virtual void add(const dtn::data::MetaBundle &bundle)
Definition: BundleList.cpp:38
virtual void eventBundleExpired(const dtn::data::MetaBundle &b)
void raiseEvent(const dtn::core::TimeEvent &evt)
static bool isExpired(const dtn::data::Timestamp &timestamp, const dtn::data::Number &lifetime)
Definition: Clock.cpp:155
meta_set::const_iterator const_iterator
Definition: BundleList.h:53
virtual void clear()
Definition: BundleList.cpp:65