|
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 _bundle_lengths[bundle] = size; 00140 00141 // insert Container 00142 pair<set<dtn::data::Bundle>::iterator,bool> ret = _bundles.insert( bundle ); 00143 00144 if (ret.second) 00145 { 00146 dtn::data::BundleList::add(dtn::data::MetaBundle(bundle)); 00147 _priority_index.insert( bundle ); 00148 } 00149 else 00150 { 00151 IBRCOMMON_LOGGER_DEBUG(5) << "Storage: got bundle duplicate " << bundle.toString() << IBRCOMMON_LOGGER_ENDL; 00152 } 00153 } 00154 00155 void MemoryBundleStorage::remove(const dtn::data::BundleID &id) 00156 { 00157 ibrcommon::MutexLock l(_bundleslock); 00158 00159 for (std::set<dtn::data::Bundle>::const_iterator iter = _bundles.begin(); iter != _bundles.end(); iter++) 00160 { 00161 if ( id == (*iter) ) 00162 { 00163 // remove item in the bundlelist 00164 dtn::data::Bundle bundle = (*iter); 00165 00166 // remove it from the bundle list 00167 _priority_index.erase(bundle); 00168 dtn::data::BundleList::remove(bundle); 00169 00170 // get size of the bundle 00171 dtn::data::DefaultSerializer s(std::cout); 00172 size_t size = s.getLength(bundle); 00173 00174 // decrement the storage size 00175 _currentsize -= size; 00176 00177 // remove the container 00178 _bundles.erase(iter); 00179 00180 return; 00181 } 00182 } 00183 00184 throw BundleStorage::NoBundleFoundException(); 00185 } 00186 00187 dtn::data::MetaBundle MemoryBundleStorage::remove(const ibrcommon::BloomFilter &filter) 00188 { 00189 ibrcommon::MutexLock l(_bundleslock); 00190 00191 for (std::set<dtn::data::Bundle>::const_iterator iter = _bundles.begin(); iter != _bundles.end(); iter++) 00192 { 00193 const dtn::data::Bundle &bundle = (*iter); 00194 00195 if ( filter.contains(bundle.toString()) ) 00196 { 00197 // remove it from the bundle list 00198 _priority_index.erase(bundle); 00199 dtn::data::BundleList::remove(bundle); 00200 00201 // get size of the bundle 00202 dtn::data::DefaultSerializer s(std::cout); 00203 00204 // decrement the storage size 00205 ssize_t len = _bundle_lengths[bundle]; 00206 _bundle_lengths.erase(bundle); 00207 _currentsize -= len; 00208 00209 // remove the container 00210 _bundles.erase(iter); 00211 00212 return (MetaBundle)bundle; 00213 } 00214 } 00215 00216 throw BundleStorage::NoBundleFoundException(); 00217 } 00218 00219 size_t MemoryBundleStorage::size() const 00220 { 00221 return _currentsize; 00222 } 00223 00224 void MemoryBundleStorage::clear() 00225 { 00226 ibrcommon::MutexLock l(_bundleslock); 00227 00228 _bundles.clear(); 00229 _priority_index.clear(); 00230 dtn::data::BundleList::clear(); 00231 _bundle_lengths.clear(); 00232 00233 // set the storage size to zero 00234 _currentsize = 0; 00235 } 00236 00237 void MemoryBundleStorage::eventBundleExpired(const ExpiringBundle &b) 00238 { 00239 for (std::set<dtn::data::Bundle>::const_iterator iter = _bundles.begin(); iter != _bundles.end(); iter++) 00240 { 00241 if ( b.bundle == (*iter) ) 00242 { 00243 dtn::data::Bundle bundle = (*iter); 00244 00245 // get size of the bundle 00246 dtn::data::DefaultSerializer s(std::cout); 00247 00248 // decrement the storage size 00249 ssize_t len = _bundle_lengths[bundle]; 00250 _bundle_lengths.erase(bundle); 00251 _currentsize -= len; 00252 00253 _priority_index.erase(bundle); 00254 _bundles.erase(iter); 00255 break; 00256 } 00257 } 00258 00259 // raise bundle event 00260 dtn::core::BundleEvent::raise( b.bundle, dtn::core::BUNDLE_DELETED, dtn::data::StatusReportBlock::LIFETIME_EXPIRED); 00261 00262 // raise an event 00263 dtn::core::BundleExpiredEvent::raise( b.bundle ); 00264 } 00265 } 00266 }