]> granicus.if.org Git - pdns/commitdiff
implement very simple cache cache that catches repeated nearly identical lookups
authorBert Hubert <bert.hubert@netherlabs.nl>
Fri, 31 Mar 2006 06:46:58 +0000 (06:46 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Fri, 31 Mar 2006 06:46:58 +0000 (06:46 +0000)
appears to have lowered cpu load by 40%

git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@646 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/recursor_cache.cc
pdns/recursor_cache.hh

index 686f0e541b3009cdfb7eeb5c034c257abf025857..9486f1965c65c26f41f845b33ed1b8b95fcf64de 100644 (file)
@@ -78,22 +78,34 @@ unsigned int MemRecursorCache::bytes()
 int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<DNSResourceRecord>* res)
 {
   unsigned int ttd=0;
-  tuple<string, uint16_t> key=make_tuple(toLowerCanonic(qname), qt.getCode());
+  string lqname(toLowerCanonic(qname));
+
+  //  cerr<<"looking up "<< toLowerCanonic(qname)+"|"+qt.getName()<<"\n";
+
+  if(!d_cachecachevalid || d_cachedqname != lqname) {
+    //    cerr<<"had cache cache miss"<<endl;
+    d_cachedqname=lqname;
+    d_cachecache=d_cache.equal_range(tie(lqname));
+    d_cachecachevalid=true;
+  }
+  else
+    ;
+  //    cerr<<"had cache cache hit!"<<endl;
 
-  cache_t::const_iterator j=d_cache.find(key);
 
-  //  cerr<<"looking up "<< toLowerCanonic(qname)+"|"+qt.getName() << " ("<<key<<", "<<code<<")\n";
   if(res)
     res->clear();
 
-  if(j!=d_cache.end()) { 
+  if(d_cachecache.first!=d_cachecache.second) { 
     if(res) {
-      for(vector<StoredRecord>::const_iterator k=j->d_records.begin(); k != j->d_records.end(); ++k) {
-       if(k->d_ttd > (uint32_t) now) {
-         DNSResourceRecord rr=String2DNSRR(qname, qt,  k->d_string, ttd=k->d_ttd); 
-         res->insert(rr);
-       }
-      }
+      for(cache_t::const_iterator i=d_cachecache.first; i != d_cachecache.second; ++i) 
+       if(i->d_qtype == qt.getCode()) 
+         for(vector<StoredRecord>::const_iterator k=i->d_records.begin(); k != i->d_records.end(); ++k) {
+           if(k->d_ttd > (uint32_t) now) {
+             DNSResourceRecord rr=String2DNSRR(qname, qt,  k->d_string, ttd=k->d_ttd); 
+             res->insert(rr);
+           }
+         }
     }
 
     //    cerr<<"time left : "<<ttd - now<<", "<< (res ? res->size() : 0) <<"\n";
@@ -108,6 +120,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<DNSResourceRecord>& content)
 {
+  d_cachecachevalid=false;
   tuple<string, uint16_t> key=make_tuple(toLowerCanonic(qname), qt.getCode());
   cache_t::iterator stored=d_cache.find(key);
   
@@ -179,7 +192,7 @@ void MemRecursorCache::doDumpAndClose(int fd)
 void MemRecursorCache::doPrune(void)
 {
   uint32_t now=(uint32_t)time(0);
-
+  d_cachecachevalid=false;
 //  cout<<"Going to prune!\n";
 
   typedef cache_t::nth_index<1>::type cache_by_ttd_t;
index 4d63fef9ff522e86c7a32ffe3cd6ab26e9a09b6e..0df92d3642d6c9c2f41348d055845de15c226cb5 100644 (file)
@@ -24,6 +24,8 @@ using namespace ::boost::multi_index;
 class MemRecursorCache : public boost::noncopyable //  : public RecursorCache
 {
 public:
+  MemRecursorCache() : d_cachecachevalid(false)
+  {}
   unsigned int size();
   unsigned int bytes();
   int get(time_t, const string &qname, const QType& qt, set<DNSResourceRecord>* res);
@@ -106,7 +108,9 @@ private:
 
 private:
   cache_t d_cache;
-
+  pair<cache_t::const_iterator, cache_t::const_iterator> d_cachecache;
+  string d_cachedqname;
+  bool d_cachecachevalid;
 };