From: Bert Hubert Date: Sat, 25 Mar 2006 21:01:35 +0000 (+0000) Subject: move cache to composite_keys, doing away the nasty string-concatenation based keys X-Git-Tag: rec-3-0~130 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=748eff9faca91ebd71dca8f4e7dc520e51855be1;p=pdns move cache to composite_keys, doing away the nasty string-concatenation based keys implement cache wiping via rec_control implement cache dumping git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@623 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/dnsrecords.cc b/pdns/dnsrecords.cc index 4528b30e7..2f9021cec 100644 --- a/pdns/dnsrecords.cc +++ b/pdns/dnsrecords.cc @@ -20,6 +20,11 @@ boilerplate_conv(A, ns_t_a, conv.xfrIP(d_ip)); +uint32_t ARecordContent::getIP() const +{ + return d_ip; +} + void ARecordContent::doRecordCheck(const DNSRecord& dr) { if(dr.d_clen!=4) diff --git a/pdns/rec_channel_rec.cc b/pdns/rec_channel_rec.cc index 88f6c550b..a23c409dc 100644 --- a/pdns/rec_channel_rec.cc +++ b/pdns/rec_channel_rec.cc @@ -8,6 +8,9 @@ #include #include #include +#include +#include +#include using namespace std; using namespace boost; @@ -61,6 +64,34 @@ string doGet(T begin, T end) return ret; } +template +string doDumpCache(T begin, T end) +{ + T i=begin; + string fname; + + if(i!=end) + fname=*i; + + int fd=open(fname.c_str(), O_CREAT | O_EXCL | O_WRONLY | O_LARGEFILE, 0660); + if(fd < 0) + return "Error opening dump file for writing: "+string(strerror(errno))+"\n"; + + RC.doDumpAndClose(fd); + + return "done\n"; +} + +template +string doWipeCache(T begin, T end) +{ + for(T i=begin; i != end; ++i) + RC.doWipeCache(*i); + + return "done\n"; +} + + uint32_t getQueryRate() { struct timeval now; @@ -116,14 +147,20 @@ string RecursorControlParser::getAnswer(const string& question) if(words.empty()) return "invalid command"; - string& cmd=words[0]; + string cmd=toLower(words[0]); vector::const_iterator begin=words.begin()+1, end=words.end(); - if(words[0]=="GET") + if(words[0]=="get") return doGet(begin, end); - if(words[0]=="QUIT") + if(words[0]=="quit") exit(1); + + if(words[0]=="dump-cache") + return doDumpCache(begin, end); + + if(words[0]=="wipe-cache") + return doWipeCache(begin, end); return "Unknown command '"+cmd+"'\n"; diff --git a/pdns/recursor_cache.cc b/pdns/recursor_cache.cc index 34ea25b94..7483e10c6 100644 --- a/pdns/recursor_cache.cc +++ b/pdns/recursor_cache.cc @@ -8,6 +8,7 @@ using namespace std; using namespace boost; #include "config.h" + #ifdef GCC_SKIP_LOCKING #include // This code is ugly but does speedup the recursor tremendously on multi-processor systems, and even has a large effect (20, 30%) on uniprocessor @@ -66,7 +67,7 @@ unsigned int MemRecursorCache::bytes() unsigned int ret=0; for(cache_t::const_iterator i=d_cache.begin(); i!=d_cache.end(); ++i) { - ret+=i->d_name.length(); + ret+=i->d_qname.length(); for(vector::const_iterator j=i->d_records.begin(); j!= i->d_records.end(); ++j) ret+=j->size(); } @@ -77,18 +78,21 @@ unsigned int MemRecursorCache::bytes() int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set* res) { unsigned int ttd=0; - uint16_t code=qt.getCode(); - string key(toLowerCanonic(qname)); key.append(1,'|'); key.append((char*)&code, ((char*)&code)+2); + tuple key=make_tuple(toLowerCanonic(qname), qt.getCode()); + cache_t::const_iterator j=d_cache.find(key); + // cerr<<"looking up "<< toLowerCanonic(qname)+"|"+qt.getName() << " ("<clear(); - if(j!=d_cache.end() && j->d_records.begin()->d_ttd>(unsigned int)now) { + if(j!=d_cache.end()) { if(res) { for(vector::const_iterator k=j->d_records.begin(); k != j->d_records.end(); ++k) { - DNSResourceRecord rr=String2DNSRR(qname, qt, k->d_string, ttd=k->d_ttd); - res->insert(rr); + if(k->d_ttd > (uint32_t) now) { + DNSResourceRecord rr=String2DNSRR(qname, qt, k->d_string, ttd=k->d_ttd); + res->insert(rr); + } } } @@ -104,8 +108,7 @@ int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set< touched, but only given a new ttd */ void MemRecursorCache::replace(const string &qname, const QType& qt, const set& content) { - uint16_t code=qt.getCode(); - string key(toLowerCanonic(qname)); key.append(1,'|'); key.append((char*)&code, ((char*)&code)+2); + tuple key=make_tuple(toLowerCanonic(qname), qt.getCode()); cache_t::iterator stored=d_cache.find(key); bool isNew=false; @@ -148,7 +151,28 @@ void MemRecursorCache::replace(const string &qname, const QType& qt, const set< d_cache.replace(stored, ce); } +void MemRecursorCache::doWipeCache(const string& name) +{ + pair range=d_cache.equal_range(tie(name)); + d_cache.erase(range.first, range.second); +} +void MemRecursorCache::doDumpAndClose(int fd) +{ + FILE* fp=fdopen(fd, "w"); + if(!fp) { + close(fd); + return; + } + time_t now=time(0); + for(cache_t::const_iterator i=d_cache.begin(); i!=d_cache.end(); ++i) { + for(vector::const_iterator j=i->d_records.begin(); j != i->d_records.end(); ++j) { + DNSResourceRecord rr=String2DNSRR(i->d_qname, QType(i->d_qtype), j->d_string, j->d_ttd - now); + fprintf(fp, "%s. %d IN %s %s\n", rr.qname.c_str(), rr.ttl, rr.qtype.getName().c_str(), rr.content.c_str()); + } + } + fclose(fp); +} void MemRecursorCache::doPrune(void) { diff --git a/pdns/recursor_cache.hh b/pdns/recursor_cache.hh index 0095aded3..4d63fef9f 100644 --- a/pdns/recursor_cache.hh +++ b/pdns/recursor_cache.hh @@ -9,7 +9,7 @@ #undef L #include #include - +#include #include #include #if BOOST_VERSION >= 103300 @@ -29,6 +29,8 @@ public: int get(time_t, const string &qname, const QType& qt, set* res); void replace(const string &qname, const QType& qt, const set& content); void doPrune(void); + void doDumpAndClose(int fd); + void doWipeCache(const string& name); uint64_t cacheHits, cacheMisses; private: @@ -66,10 +68,13 @@ private: // typedef __gnu_cxx::hash_map > cache_t; struct CacheEntry { - CacheEntry(){} - CacheEntry(const string& name, const vector& records) : d_name(name), d_records(records) + string d_qname; + uint16_t d_qtype; + + CacheEntry(const tuple& key, const vector& records) : + d_qname(key.get<0>()), d_qtype(key.get<1>()), d_records(records) {} - string d_name; + typedef vector records_t; records_t d_records; uint32_t getTTD() const @@ -88,11 +93,13 @@ private: typedef multi_index_container< CacheEntry, indexed_by < -#if BOOST_VERSION >= 103300 - hashed_unique >, -#else - ordered_unique >, -#endif + ordered_unique< + composite_key< + CacheEntry, + member, + member + > + >, ordered_non_unique > > > cache_t;