IBR-DTNSuite 0.6

daemon/src/core/MemoryBundleStorage.cpp

Go to the documentation of this file.
00001 /*
00002  * MemoryBundleStorage.cpp
00003  *
00004  *  Created on: 22.11.2010
00005  *      Author: morgenro
00006  */
00007 
00008 #include "core/MemoryBundleStorage.h"
00009 #include "core/TimeEvent.h"
00010 #include "core/GlobalEvent.h"
00011 #include "core/BundleExpiredEvent.h"
00012 #include "core/BundleEvent.h"
00013 
00014 #include <ibrcommon/Logger.h>
00015 #include <ibrcommon/thread/MutexLock.h>
00016 
00017 namespace dtn
00018 {
00019         namespace core
00020         {
00021                 MemoryBundleStorage::MemoryBundleStorage(size_t maxsize)
00022                  : _maxsize(maxsize), _currentsize(0)
00023                 {
00024                 }
00025 
00026                 MemoryBundleStorage::~MemoryBundleStorage()
00027                 {
00028                 }
00029 
00030                 void MemoryBundleStorage::componentUp()
00031                 {
00032                         bindEvent(TimeEvent::className);
00033                 }
00034 
00035                 void MemoryBundleStorage::componentDown()
00036                 {
00037                         unbindEvent(TimeEvent::className);
00038                 }
00039 
00040                 void MemoryBundleStorage::raiseEvent(const Event *evt)
00041                 {
00042                         try {
00043                                 const TimeEvent &time = dynamic_cast<const TimeEvent&>(*evt);
00044                                 if (time.getAction() == dtn::core::TIME_SECOND_TICK)
00045                                 {
00046                                         // do expiration of bundles
00047                                         ibrcommon::MutexLock l(_bundleslock);
00048                                         dtn::data::BundleList::expire(time.getTimestamp());
00049                                 }
00050                         } catch (const std::bad_cast&) { }
00051                 }
00052 
00053                 const std::string MemoryBundleStorage::getName() const
00054                 {
00055                         return "MemoryBundleStorage";
00056                 }
00057 
00058                 bool MemoryBundleStorage::empty()
00059                 {
00060                         ibrcommon::MutexLock l(_bundleslock);
00061                         return _bundles.empty();
00062                 }
00063 
00064                 void MemoryBundleStorage::releaseCustody(const dtn::data::EID&, const dtn::data::BundleID&)
00065                 {
00066                         // custody is successful transferred to another node.
00067                         // it is safe to delete this bundle now. (depending on the routing algorithm.)
00068                 }
00069 
00070                 unsigned int MemoryBundleStorage::count()
00071                 {
00072                         ibrcommon::MutexLock l(_bundleslock);
00073                         return _bundles.size();
00074                 }
00075 
00076                 const std::list<dtn::data::MetaBundle> MemoryBundleStorage::get(BundleFilterCallback &cb)
00077                 {
00078                         // result list
00079                         std::list<dtn::data::MetaBundle> result;
00080 
00081                         // we have to iterate through all bundles
00082                         ibrcommon::MutexLock l(_bundleslock);
00083 
00084                         for (std::set<dtn::data::MetaBundle>::const_iterator iter = _priority_index.begin(); (iter != _priority_index.end()) && (result.size() < cb.limit()); iter++)
00085                         {
00086                                 const dtn::data::MetaBundle &bundle = (*iter);
00087 
00088                                 if ( cb.shouldAdd(bundle) )
00089                                 {
00090                                         result.push_back(bundle);
00091                                 }
00092                         }
00093 
00094                         return result;
00095                 }
00096 
00097                 dtn::data::Bundle MemoryBundleStorage::get(const dtn::data::BundleID &id)
00098                 {
00099                         try {
00100                                 ibrcommon::MutexLock l(_bundleslock);
00101 
00102                                 for (std::set<dtn::data::Bundle>::const_iterator iter = _bundles.begin(); iter != _bundles.end(); iter++)
00103                                 {
00104                                         const dtn::data::Bundle &bundle = (*iter);
00105                                         if (id == bundle)
00106                                         {
00107                                                 return bundle;
00108                                         }
00109                                 }
00110                         } catch (const dtn::SerializationFailedException &ex) {
00111                                 // bundle loading failed
00112                                 IBRCOMMON_LOGGER(error) << "Error while loading bundle data: " << ex.what() << IBRCOMMON_LOGGER_ENDL;
00113 
00114                                 // the bundle is broken, delete it
00115                                 remove(id);
00116 
00117                                 throw BundleStorage::BundleLoadException();
00118                         }
00119 
00120                         throw BundleStorage::NoBundleFoundException();
00121                 }
00122 
00123                 void MemoryBundleStorage::store(const dtn::data::Bundle &bundle)
00124                 {
00125                         ibrcommon::MutexLock l(_bundleslock);
00126 
00127                         // get size of the bundle
00128                         dtn::data::DefaultSerializer s(std::cout);
00129                         size_t size = s.getLength(bundle);
00130 
00131                         // check if this container is too big for us.
00132                         if ((_maxsize > 0) && (_currentsize + size > _maxsize))
00133                         {
00134                                 throw StorageSizeExeededException();
00135                         }
00136 
00137                         // increment the storage size
00138                         _currentsize += size;
00139 
00140                         // insert Container
00141                         pair<set<dtn::data::Bundle>::iterator,bool> ret = _bundles.insert( bundle );
00142 
00143                         if (ret.second)
00144                         {
00145                                 dtn::data::BundleList::add(dtn::data::MetaBundle(bundle));
00146                                 _priority_index.insert( bundle );
00147                         }
00148                         else
00149                         {
00150                                 IBRCOMMON_LOGGER_DEBUG(5) << "Storage: got bundle duplicate " << bundle.toString() << IBRCOMMON_LOGGER_ENDL;
00151                         }
00152                 }
00153 
00154                 void MemoryBundleStorage::remove(const dtn::data::BundleID &id)
00155                 {
00156                         ibrcommon::MutexLock l(_bundleslock);
00157 
00158                         for (std::set<dtn::data::Bundle>::const_iterator iter = _bundles.begin(); iter != _bundles.end(); iter++)
00159                         {
00160                                 if ( id == (*iter) )
00161                                 {
00162                                         // remove item in the bundlelist
00163                                         dtn::data::Bundle bundle = (*iter);
00164 
00165                                         // remove it from the bundle list
00166                                         _priority_index.erase(bundle);
00167                                         dtn::data::BundleList::remove(bundle);
00168 
00169                                         // get size of the bundle
00170                                         dtn::data::DefaultSerializer s(std::cout);
00171                                         size_t size = s.getLength(bundle);
00172 
00173                                         // decrement the storage size
00174                                         _currentsize -= size;
00175 
00176                                         // remove the container
00177                                         _bundles.erase(iter);
00178 
00179                                         return;
00180                                 }
00181                         }
00182 
00183                         throw BundleStorage::NoBundleFoundException();
00184                 }
00185 
00186                 dtn::data::MetaBundle MemoryBundleStorage::remove(const ibrcommon::BloomFilter &filter)
00187                 {
00188                         ibrcommon::MutexLock l(_bundleslock);
00189 
00190                         for (std::set<dtn::data::Bundle>::const_iterator iter = _bundles.begin(); iter != _bundles.end(); iter++)
00191                         {
00192                                 const dtn::data::Bundle &bundle = (*iter);
00193 
00194                                 if ( filter.contains(bundle.toString()) )
00195                                 {
00196                                         // remove it from the bundle list
00197                                         _priority_index.erase(bundle);
00198                                         dtn::data::BundleList::remove(bundle);
00199 
00200                                         // get size of the bundle
00201                                         dtn::data::DefaultSerializer s(std::cout);
00202 
00203                                         // decrement the storage size
00204                                         _currentsize -= s.getLength(bundle);
00205 
00206                                         // remove the container
00207                                         _bundles.erase(iter);
00208 
00209                                         return (MetaBundle)bundle;
00210                                 }
00211                         }
00212 
00213                         throw BundleStorage::NoBundleFoundException();
00214                 }
00215 
00216                 size_t MemoryBundleStorage::size() const
00217                 {
00218                         return _currentsize;
00219                 }
00220 
00221                 void MemoryBundleStorage::clear()
00222                 {
00223                         ibrcommon::MutexLock l(_bundleslock);
00224 
00225                         _bundles.clear();
00226                         _priority_index.clear();
00227                         dtn::data::BundleList::clear();
00228 
00229                         // set the storage size to zero
00230                         _currentsize = 0;
00231                 }
00232 
00233                 void MemoryBundleStorage::eventBundleExpired(const ExpiringBundle &b)
00234                 {
00235                         for (std::set<dtn::data::Bundle>::const_iterator iter = _bundles.begin(); iter != _bundles.end(); iter++)
00236                         {
00237                                 if ( b.bundle == (*iter) )
00238                                 {
00239                                         dtn::data::Bundle bundle = (*iter);
00240 
00241                                         // get size of the bundle
00242                                         dtn::data::DefaultSerializer s(std::cout);
00243 
00244                                         // decrement the storage size
00245                                         _currentsize -= s.getLength(bundle);
00246 
00247                                         _priority_index.erase(bundle);
00248                                         _bundles.erase(iter);
00249                                         break;
00250                                 }
00251                         }
00252 
00253                         // raise bundle event
00254                         dtn::core::BundleEvent::raise( b.bundle, dtn::core::BUNDLE_DELETED, dtn::data::StatusReportBlock::LIFETIME_EXPIRED);
00255 
00256                         // raise an event
00257                         dtn::core::BundleExpiredEvent::raise( b.bundle );
00258                 }
00259         }
00260 }