42 #ifndef _DWMRDAPIPV4ROUTES_HH_ 43 #define _DWMRDAPIPV4ROUTES_HH_ 50 #include <unordered_map> 51 #include <shared_mutex> 54 #include "DwmPortability.hh" 57 #include "DwmBZ2IO.hh" 58 #include "DwmIpv4Prefix.hh" 59 #include "DwmOperators.hh" 60 #include "DwmReadable.hh" 61 #include "DwmWritable.hh" 62 #include "DwmGZReadable.hh" 63 #include "DwmGZWritable.hh" 64 #include "DwmBZ2Readable.hh" 65 #include "DwmBZ2Writable.hh" 82 template <
typename _valueT>
84 :
public Readable,
public Writable,
85 public GZReadable,
public GZWritable,
86 public BZ2Readable,
public BZ2Writable
89 typedef std::map<Ipv4Address, _valueT> _RepSubType;
90 typedef typename _RepSubType::const_iterator const_iterator;
105 std::shared_lock<std::shared_mutex> lock(_mtx);
106 for (uint8_t i = 0; i < 33; ++i)
117 std::shared_lock<std::shared_mutex> lock(_mtx);
118 for (uint8_t i = 0; i < 33; ++i) {
119 if (! _maps[i].empty()) {
131 bool Add(
const Ipv4Prefix & prefix,
const _valueT & value)
135 std::shared_lock<std::shared_mutex> lock(_mtx);
136 typename _RepSubType::iterator iter =
137 _maps[prefix.MaskLength()].find(prefix.Network());
138 if (iter == _maps[prefix.MaskLength()].end()) {
139 _maps[prefix.MaskLength()][prefix.Network()] = value;
150 std::shared_lock<std::shared_mutex> lock(_mtx);
151 return(_maps[prefix.MaskLength()][prefix.Network()]);
161 std::lock_guard<std::shared_mutex> lock(_mtx);
162 typename _RepSubType::iterator iter =
163 _maps[prefix.MaskLength()].find(prefix.Network());
164 if (iter != _maps[prefix.MaskLength()].end()) {
165 _maps[prefix.MaskLength()].erase(iter);
176 bool Find(
const Ipv4Prefix & prefix, _valueT & match)
const 179 std::shared_lock<std::shared_mutex> lock(_mtx);
180 if (! _maps[prefix.MaskLength()].empty()) {
181 typename _RepSubType::const_iterator iter =
182 _maps[prefix.MaskLength()].find(prefix.Network());
183 if (iter != _maps[prefix.MaskLength()].end()) {
184 match = iter->second;
197 std::pair<Ipv4Prefix,_valueT> & match)
const 201 Ipv4Prefix lp(ipAddr, 32);
203 typename _RepSubType::const_iterator iter;
204 for (int8_t i = 32; i >= 0; --i) {
205 std::shared_lock<std::shared_mutex> lock(_mtx);
206 if (_maps[i].empty())
209 iter = _maps[i].find(lp.Network());
210 if (iter != _maps[i].end()) {
212 match.second = iter->second;
230 std::pair<Ipv4Prefix, const _valueT *> & match)
const 233 Ipv4Prefix lp(ipAddr, 32);
234 typename _RepSubType::const_iterator iter;
235 for (int8_t i = 32; i >= 0; --i) {
236 std::shared_lock<std::shared_mutex> lock(_mtx);
237 if (_maps[i].empty())
240 iter = _maps[i].find(lp.Network());
241 if (iter != _maps[i].end()) {
243 match.second = &(iter->second);
256 bool Find(
const Ipv4Address & ipAddr,
257 std::vector<std::pair<Ipv4Prefix,_valueT> > & matches)
const 259 if (! matches.empty())
262 typename _RepSubType::const_iterator iter;
264 for (int8_t i = 32; i >= 0; --i) {
265 std::shared_lock<std::shared_mutex> lock(_mtx);
266 if (_maps[i].empty())
268 Ipv4Prefix prefix(ipAddr, i);
269 iter = _maps[i].find(prefix.Network());
270 if (iter != _maps[i].end()) {
271 std::pair<Ipv4Prefix,_valueT> match(prefix, iter->second);
272 matches.push_back(match);
275 return(! matches.empty());
285 for (int8_t i = 32; i >= 0; --i) {
286 std::shared_lock<std::shared_mutex> lock(_mtx);
287 if (_maps[i] != r._maps[i])
300 return(! (*
this == r));
309 for (uint8_t i = 0; i < 33; ++i) {
310 std::shared_lock<std::shared_mutex> lock(_mtx);
311 rc += _maps[i].size();
319 void HashSizes(std::vector<std::pair<uint8_t, uint32_t> > & sizes)
const 323 for (uint8_t i = 0; i < 33; ++i) {
324 std::shared_lock<std::shared_mutex> lock(_mtx);
325 if (! _maps[i].empty()) {
326 sizes.push_back(std::pair<uint8_t,uint32_t>(i,_maps[i].size()));
335 uint32_t StreamedLength()
const 337 std::shared_lock<std::shared_mutex> lock(_mtx);
338 return(IO::StreamedLength(_maps));
344 std::istream &
Read(std::istream & is)
346 std::lock_guard<std::shared_mutex> lock(_mtx);
347 return(IO::Read(is, _maps));
353 std::ostream &
Write(std::ostream & os)
const 355 std::shared_lock<std::shared_mutex> lock(_mtx);
356 return(IO::Write(os, _maps));
365 std::lock_guard<std::shared_mutex> lock(_mtx);
366 return(IO::Read(f, _maps));
375 std::shared_lock<std::shared_mutex> lock(_mtx);
376 return(IO::Write(f, _maps));
385 std::lock_guard<std::shared_mutex> lock(_mtx);
386 return(IO::Read(fd, _maps));
395 std::shared_lock<std::shared_mutex> lock(_mtx);
396 return(IO::Write(fd, _maps));
405 std::lock_guard<std::shared_mutex> lock(_mtx);
406 return(GZIO::Read(gzf, _maps));
415 std::shared_lock<std::shared_mutex> lock(_mtx);
416 return(GZIO::Write(gzf, _maps));
425 std::lock_guard<std::shared_mutex> lock(_mtx);
426 return(BZ2IO::BZRead(bzf, _maps));
435 std::shared_lock<std::shared_mutex> lock(_mtx);
436 return(BZ2IO::BZWrite(bzf, _maps));
439 void SortByKey(std::vector<std::pair<Ipv4Prefix,_valueT>> & target,
440 bool ascending =
true)
const 442 if (! target.empty())
444 std::shared_lock<std::shared_mutex> lock(_mtx);
445 if (! this->_maps.empty()) {
446 target.resize(this->
Size());
447 typename std::vector<_RepSubType>::const_iterator iter =
450 for (uint8_t hashNum = 0; hashNum < 33; ++hashNum) {
451 if (! this->_maps[hashNum].empty()) {
452 typename _RepSubType::const_iterator hiter =
453 this->_maps[hashNum].begin();
454 for ( ; hiter != iter->end(); ++hiter) {
455 target[pfx].first = Ipv4Prefix(hiter->first, hashNum);
456 target[pfx].second = hiter->second;
461 if (! target.empty()) {
463 std::sort(target.begin(), target.end(), KeyLess());
466 std::sort(target.begin(), target.end(), KeyGreater());
481 void SortByValue(std::vector<std::pair<Ipv4Prefix,_valueT> > & target)
483 if (! target.empty())
485 std::shared_lock<std::shared_mutex> lock(_mtx);
486 if (! this->_maps.empty()) {
487 target.resize(this->
Size());
488 typename std::vector<_RepSubType>::const_iterator iter =
491 for (uint8_t hashNum = 0; hashNum < 33; ++hashNum) {
492 if (! this->_maps[hashNum].empty()) {
493 typename _RepSubType::const_iterator hiter =
494 this->_maps[hashNum].begin();
495 for ( ; hiter != iter->end(); ++hiter) {
496 target[pfx].first = Ipv4Prefix(hiter->first, hashNum);
497 target[pfx].second = hiter->second;
502 if (! target.empty())
503 std::sort(target.begin(), target.end(), ValueGreater());
516 for (int8_t hashNum = 32; hashNum > 0; --hashNum) {
517 typename _RepSubType::const_iterator hiter =
518 _maps[hashNum].begin();
519 for ( ; hiter != _maps[hashNum].end(); ++hiter) {
520 bool foundWider =
false;
521 for (int8_t widerHash = hashNum - 1; widerHash > 0; --widerHash) {
522 if (_maps[widerHash].find(Ipv4Prefix(hiter->first,widerHash).Network())
523 != _maps[widerHash].end()) {
530 rc += ((uint32_t)1 << (32 - hashNum));
540 bool operator () (
const std::pair<Ipv4Prefix,_valueT> & e1,
541 const std::pair<Ipv4Prefix,_valueT> & e2)
const 543 return(e1.first > e2.first);
550 bool operator () (
const std::pair<Ipv4Prefix,_valueT> & e1,
551 const std::pair<Ipv4Prefix,_valueT> & e2)
const 553 return(e1.first < e2.first);
560 bool operator () (
const std::pair<Ipv4Prefix,_valueT> & e1,
561 const std::pair<Ipv4Prefix,_valueT> & e2)
const 563 return(e1.second > e2.second);
569 std::vector<_RepSubType> _maps;
570 mutable std::shared_mutex _mtx;
577 #endif // _DWMRDAPIPV4ROUTES_HH_ bool Add(const Ipv4Prefix &prefix, const _valueT &value)
Adds an entry.
Definition: DwmRDAPIpv4Routes.hh:131
void Clear()
Clears all entries.
Definition: DwmRDAPIpv4Routes.hh:103
_valueT & operator[](const Ipv4Prefix &prefix)
operator [] works like you would expect from an STL map.
Definition: DwmRDAPIpv4Routes.hh:148
int BZRead(BZFILE *bzf)
Reads the routes from a BZFILE pointer.
Definition: DwmRDAPIpv4Routes.hh:423
uint32_t AddressesCovered() const
Returns the number of addresses covered by the contained prefixes, not including 0/0.
Definition: DwmRDAPIpv4Routes.hh:513
int BZWrite(BZFILE *bzf) const
Writes the routes to a BZFILE pointer.
Definition: DwmRDAPIpv4Routes.hh:433
bool operator==(const Ipv4Routes< _valueT > &r) const
operator == It's unlikely you'd ever need to use this, and it's expensive.
Definition: DwmRDAPIpv4Routes.hh:283
std::istream & Read(std::istream &is)
Reads the routes from an istream. Returns the istream.
Definition: DwmRDAPIpv4Routes.hh:344
void SortByValue(std::vector< std::pair< Ipv4Prefix, _valueT > > &target)
Sorts the contained pair<Ipv4Prefix,_valueT> values into a vector, in descending order by the value s...
Definition: DwmRDAPIpv4Routes.hh:481
uint32_t Size() const
Returns the number of routes.
Definition: DwmRDAPIpv4Routes.hh:306
std::ostream & Write(std::ostream &os) const
Writes the routes to an ostream. Returns the ostream.
Definition: DwmRDAPIpv4Routes.hh:353
int Write(gzFile gzf) const
Writes the routes to a gzFile.
Definition: DwmRDAPIpv4Routes.hh:413
bool Find(const Ipv4Prefix &prefix, _valueT &match) const
Find the entry for the given prefix.
Definition: DwmRDAPIpv4Routes.hh:176
bool Delete(const Ipv4Prefix &prefix)
Deletes the entry for prefix.
Definition: DwmRDAPIpv4Routes.hh:158
bool Find(const Ipv4Address &ipAddr, std::vector< std::pair< Ipv4Prefix, _valueT > > &matches) const
Finds all matches for ipAddr.
Definition: DwmRDAPIpv4Routes.hh:256
This template class provides an associative container keyed by IPv4 addresses, with longest-match sea...
Definition: DwmRDAPIpv4Routes.hh:83
Definition: DwmCountryCode.hh:53
ssize_t Read(int fd)
Reads the routes from a file descriptor.
Definition: DwmRDAPIpv4Routes.hh:383
int Read(gzFile gzf)
Reads the routes from a gzFile.
Definition: DwmRDAPIpv4Routes.hh:403
size_t Read(FILE *f)
Reades the routes from a FILE pointer.
Definition: DwmRDAPIpv4Routes.hh:363
bool Empty() const
Returns true if there are no entries.
Definition: DwmRDAPIpv4Routes.hh:114
size_t Write(FILE *f) const
Writes the routes to a FILE pointer.
Definition: DwmRDAPIpv4Routes.hh:373
bool FindLongest(const Ipv4Address &ipAddr, std::pair< Ipv4Prefix, _valueT > &match) const
Finds the longest match for ipAddr.
Definition: DwmRDAPIpv4Routes.hh:196
ssize_t Write(int fd) const
Writes the routes to a file descriptor.
Definition: DwmRDAPIpv4Routes.hh:393
bool operator!=(const Ipv4Routes< _valueT > &r) const
operator != It's unlikely you'd ever need to use this, and it's expensive.
Definition: DwmRDAPIpv4Routes.hh:298
bool FindLongest(const Ipv4Address &ipAddr, std::pair< Ipv4Prefix, const _valueT *> &match) const
Finds the longest match for ipAddr.
Definition: DwmRDAPIpv4Routes.hh:229