|
IBR-DTNSuite 0.6
|
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 }