IBR-DTNSuite
0.8
|
00001 /* 00002 * NeighborDatabase.cpp 00003 * 00004 * Created on: 23.07.2010 00005 * Author: morgenro 00006 */ 00007 00008 #include "routing/NeighborDatabase.h" 00009 #include <ibrdtn/utils/Clock.h> 00010 #include <ibrcommon/Logger.h> 00011 #include <limits> 00012 00013 namespace dtn 00014 { 00015 namespace routing 00016 { 00017 NeighborDatabase::NeighborEntry::NeighborEntry() 00018 : eid(), _transit_max(5), _filter(), _filter_expire(0), _filter_state(FILTER_EXPIRED, FILTER_FINAL) 00019 {}; 00020 00021 NeighborDatabase::NeighborEntry::NeighborEntry(const dtn::data::EID &e) 00022 : eid(e), _transit_max(5), _filter(), _filter_expire(0), _filter_state(FILTER_EXPIRED, FILTER_FINAL) 00023 { } 00024 00025 NeighborDatabase::NeighborEntry::~NeighborEntry() 00026 { } 00027 00028 void NeighborDatabase::NeighborEntry::update(const ibrcommon::BloomFilter &bf, const size_t lifetime) 00029 { 00030 ibrcommon::ThreadsafeState<FILTER_REQUEST_STATE>::Locked l = _filter_state.lock(); 00031 _filter = bf; 00032 00033 if (lifetime == 0) 00034 { 00035 _filter_expire = std::numeric_limits<std::size_t>::max(); 00036 } 00037 else 00038 { 00039 _filter_expire = dtn::utils::Clock::getExpireTime(lifetime); 00040 } 00041 00042 l = FILTER_AVAILABLE; 00043 } 00044 00045 void NeighborDatabase::NeighborEntry::reset() 00046 { 00047 ibrcommon::ThreadsafeState<FILTER_REQUEST_STATE>::Locked l = _filter_state.lock(); 00048 00049 l = FILTER_EXPIRED; 00050 00051 // do not expire again in the next 60 seconds 00052 _filter_expire = dtn::utils::Clock::getTime() + 60; 00053 } 00054 00055 void NeighborDatabase::NeighborEntry::add(const dtn::data::MetaBundle &bundle) 00056 { 00057 _summary.add(bundle); 00058 } 00059 00060 bool NeighborDatabase::NeighborEntry::has(const dtn::data::BundleID &id, const bool require_bloomfilter) const 00061 { 00062 if (require_bloomfilter && (_filter_state != FILTER_AVAILABLE)) 00063 throw BloomfilterNotAvailableException(eid); 00064 00065 if (_filter_state == FILTER_AVAILABLE) 00066 { 00067 if (_filter.contains(id.toString())) 00068 return true; 00069 } 00070 00071 if (_summary.contains(id)) 00072 return true; 00073 00074 return false; 00075 } 00076 00077 void NeighborDatabase::NeighborEntry::expire(const size_t timestamp) 00078 { 00079 { 00080 ibrcommon::ThreadsafeState<FILTER_REQUEST_STATE>::Locked l = _filter_state.lock(); 00081 00082 if ((_filter_expire > 0) && (_filter_expire < timestamp)) 00083 { 00084 IBRCOMMON_LOGGER_DEBUG(15) << "summary vector of " << eid.getString() << " is expired" << IBRCOMMON_LOGGER_ENDL; 00085 00086 // set the filter state to expired once 00087 l = FILTER_EXPIRED; 00088 00089 // do not expire again in the next 60 seconds 00090 _filter_expire = timestamp + 60; 00091 } 00092 } 00093 00094 _summary.expire(timestamp); 00095 } 00096 00097 void NeighborDatabase::expire(const size_t timestamp) 00098 { 00099 for (std::map<dtn::data::EID, NeighborDatabase::NeighborEntry* >::const_iterator iter = _entries.begin(); iter != _entries.end(); iter++) 00100 { 00101 (*iter).second->expire(timestamp); 00102 } 00103 } 00104 00105 void NeighborDatabase::NeighborEntry::acquireFilterRequest() throw (NoMoreTransfersAvailable) 00106 { 00107 ibrcommon::ThreadsafeState<FILTER_REQUEST_STATE>::Locked l = _filter_state.lock(); 00108 00109 if (l != FILTER_EXPIRED) 00110 throw NoMoreTransfersAvailable(); 00111 00112 // set the state to zero 00113 l = FILTER_AWAITING; 00114 } 00115 00116 void NeighborDatabase::NeighborEntry::acquireTransfer(const dtn::data::BundleID &id) throw (NoMoreTransfersAvailable, AlreadyInTransitException) 00117 { 00118 ibrcommon::MutexLock l(_transit_lock); 00119 00120 // check if the bundle is already in transit 00121 if (_transit_bundles.find(id) != _transit_bundles.end()) throw AlreadyInTransitException(); 00122 00123 // check if enough resources available to transfer the bundle 00124 if (_transit_bundles.size() >= _transit_max) throw NoMoreTransfersAvailable(); 00125 00126 // insert the bundle into the transit list 00127 _transit_bundles.insert(id); 00128 00129 IBRCOMMON_LOGGER_DEBUG(20) << "acquire transfer of " << id.toString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL; 00130 } 00131 00132 void NeighborDatabase::NeighborEntry::releaseTransfer(const dtn::data::BundleID &id) 00133 { 00134 ibrcommon::MutexLock l(_transit_lock); 00135 _transit_bundles.erase(id); 00136 00137 IBRCOMMON_LOGGER_DEBUG(20) << "release transfer of " << id.toString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL; 00138 } 00139 00140 NeighborDatabase::NeighborDatabase() 00141 { 00142 } 00143 00144 NeighborDatabase::~NeighborDatabase() 00145 { 00146 std::set<dtn::data::EID> ret; 00147 00148 for (std::map<dtn::data::EID, NeighborDatabase::NeighborEntry* >::const_iterator iter = _entries.begin(); iter != _entries.end(); iter++) 00149 { 00150 delete (*iter).second; 00151 } 00152 } 00153 00154 NeighborDatabase::NeighborEntry& NeighborDatabase::create(const dtn::data::EID &eid) 00155 { 00156 if (_entries.find(eid) == _entries.end()) 00157 { 00158 NeighborEntry *entry = new NeighborEntry(eid); 00159 _entries[eid] = entry; 00160 } 00161 00162 return (*_entries[eid]); 00163 } 00164 00165 NeighborDatabase::NeighborEntry& NeighborDatabase::get(const dtn::data::EID &eid) throw (NeighborNotAvailableException) 00166 { 00167 if (_entries.find(eid) == _entries.end()) 00168 { 00169 throw NeighborNotAvailableException(); 00170 } 00171 00172 return (*_entries[eid]); 00173 } 00174 00175 NeighborDatabase::NeighborEntry& NeighborDatabase::reset(const dtn::data::EID &eid) 00176 { 00177 NeighborDatabase::NeighborEntry &e = get(eid); 00178 e.reset(); 00179 return e; 00180 } 00181 00182 void NeighborDatabase::remove(const dtn::data::EID &eid) 00183 { 00184 _entries.erase(eid); 00185 } 00186 00187 void NeighborDatabase::addBundle(const dtn::data::EID &neighbor, const dtn::data::MetaBundle &b) 00188 { 00189 try { 00190 NeighborDatabase::NeighborEntry &entry = get(neighbor); 00191 entry.add(b); 00192 } catch (const NeighborDatabase::NeighborNotAvailableException&) { }; 00193 } 00194 } 00195 }