Go to the documentation of this file.00001
00002
00003
00004
00005
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)
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)
00023 { }
00024
00025 NeighborDatabase::NeighborEntry::~NeighborEntry()
00026 { }
00027
00028 void NeighborDatabase::NeighborEntry::update(const ibrcommon::BloomFilter &bf, const size_t lifetime)
00029 {
00030 _filter = bf;
00031
00032 if (lifetime == 0)
00033 {
00034 _filter_expire = std::numeric_limits<std::size_t>::max();
00035 }
00036 else
00037 {
00038 _filter_expire = dtn::utils::Clock::getExpireTime(lifetime);
00039 }
00040
00041 _filter_state = FILTER_AVAILABLE;
00042 }
00043
00044 void NeighborDatabase::NeighborEntry::reset()
00045 {
00046 _filter_state = FILTER_EXPIRED;
00047 }
00048
00049 void NeighborDatabase::NeighborEntry::add(const dtn::data::MetaBundle &bundle)
00050 {
00051 _summary.add(bundle);
00052 }
00053
00054 bool NeighborDatabase::NeighborEntry::has(const dtn::data::BundleID &id, const bool require_bloomfilter) const
00055 {
00056 if (require_bloomfilter && (_filter_state != FILTER_AVAILABLE))
00057 throw BloomfilterNotAvailableException(eid);
00058
00059 if (_filter_state == FILTER_AVAILABLE)
00060 {
00061 if (_filter.contains(id.toString()))
00062 return true;
00063 }
00064
00065 if (_summary.contains(id))
00066 return true;
00067
00068 return false;
00069 }
00070
00071 void NeighborDatabase::NeighborEntry::expire(const size_t timestamp)
00072 {
00073 if ((_filter_expire > 0) && (_filter_expire < timestamp))
00074 {
00075 IBRCOMMON_LOGGER_DEBUG(15) << "summary vector of " << eid.getString() << " is expired" << IBRCOMMON_LOGGER_ENDL;
00076
00077
00078 _filter_state = FILTER_EXPIRED;
00079 }
00080
00081 _summary.expire(timestamp);
00082 }
00083
00084 void NeighborDatabase::expire(const size_t timestamp)
00085 {
00086 for (std::map<dtn::data::EID, NeighborDatabase::NeighborEntry* >::const_iterator iter = _entries.begin(); iter != _entries.end(); iter++)
00087 {
00088 (*iter).second->expire(timestamp);
00089 }
00090 }
00091
00092 void NeighborDatabase::NeighborEntry::acquireFilterRequest() throw (NoMoreTransfersAvailable)
00093 {
00094 if (_filter_state != FILTER_EXPIRED)
00095 throw NoMoreTransfersAvailable();
00096
00097 _filter_state = FILTER_AWAITING;
00098 }
00099
00100 void NeighborDatabase::NeighborEntry::acquireTransfer(const dtn::data::BundleID &id) throw (NoMoreTransfersAvailable, AlreadyInTransitException)
00101 {
00102 ibrcommon::MutexLock l(_transit_lock);
00103
00104
00105 if (_transit_bundles.find(id) != _transit_bundles.end()) throw AlreadyInTransitException();
00106
00107
00108 if (_transit_bundles.size() >= _transit_max) throw NoMoreTransfersAvailable();
00109
00110
00111 _transit_bundles.insert(id);
00112
00113 IBRCOMMON_LOGGER_DEBUG(20) << "acquire transfer of " << id.toString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL;
00114 }
00115
00116 void NeighborDatabase::NeighborEntry::releaseTransfer(const dtn::data::BundleID &id)
00117 {
00118 ibrcommon::MutexLock l(_transit_lock);
00119 _transit_bundles.erase(id);
00120
00121 IBRCOMMON_LOGGER_DEBUG(20) << "release transfer of " << id.toString() << " (" << _transit_bundles.size() << " bundles in transit)" << IBRCOMMON_LOGGER_ENDL;
00122 }
00123
00124 NeighborDatabase::NeighborDatabase()
00125 {
00126 }
00127
00128 NeighborDatabase::~NeighborDatabase()
00129 {
00130 std::set<dtn::data::EID> ret;
00131
00132 for (std::map<dtn::data::EID, NeighborDatabase::NeighborEntry* >::const_iterator iter = _entries.begin(); iter != _entries.end(); iter++)
00133 {
00134 delete (*iter).second;
00135 }
00136 }
00137
00138 NeighborDatabase::NeighborEntry& NeighborDatabase::create(const dtn::data::EID &eid)
00139 {
00140 if (_entries.find(eid) == _entries.end())
00141 {
00142 NeighborEntry *entry = new NeighborEntry(eid);
00143 _entries[eid] = entry;
00144 }
00145
00146 return (*_entries[eid]);
00147 }
00148
00149 NeighborDatabase::NeighborEntry& NeighborDatabase::get(const dtn::data::EID &eid) throw (NeighborNotAvailableException)
00150 {
00151 if (_entries.find(eid) == _entries.end())
00152 {
00153 throw NeighborNotAvailableException();
00154 }
00155
00156 return (*_entries[eid]);
00157 }
00158
00159 NeighborDatabase::NeighborEntry& NeighborDatabase::reset(const dtn::data::EID &eid)
00160 {
00161 try {
00162 NeighborDatabase::NeighborEntry &e = get(eid);
00163 e.reset();
00164 } catch (const NeighborNotAvailableException&) { };
00165 }
00166
00167 void NeighborDatabase::remove(const dtn::data::EID &eid)
00168 {
00169 _entries.erase(eid);
00170 }
00171
00172 void NeighborDatabase::addBundle(const dtn::data::EID &neighbor, const dtn::data::MetaBundle &b)
00173 {
00174 try {
00175 NeighborDatabase::NeighborEntry &entry = get(neighbor);
00176 entry.add(b);
00177 } catch (const NeighborDatabase::NeighborNotAvailableException&) { };
00178 }
00179 }
00180 }