]> granicus.if.org Git - pdns/commitdiff
unify cache deletion queue management, and make negcache use it
authorBert Hubert <bert.hubert@netherlabs.nl>
Tue, 31 Aug 2010 06:49:01 +0000 (06:49 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Tue, 31 Aug 2010 06:49:01 +0000 (06:49 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1705 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/cachecleaner.hh
pdns/recpacketcache.cc
pdns/recursor_cache.cc
pdns/syncres.cc

index af2e82a0a41b58e941400d3e0ba601c838539b70..defd3a4a7d76149ae6c6695b9de8bf7dd15f0142 100644 (file)
@@ -2,6 +2,8 @@
 #define PDNS_CACHECLEANER_HH
 
 // this function can clean any cache that has a getTTD() method on its entries, and a 'sequence' index as its second index
+// the ritual is that the oldest entries are in *front* of the sequence collection, so on a hit, move an item to the end
+// on a miss, move it to the beginning
 template <typename T> void pruneCollection(T& collection, unsigned int maxCached)
 {
   uint32_t now=(uint32_t)time(0);
@@ -55,4 +57,26 @@ template <typename T> void pruneCollection(T& collection, unsigned int maxCached
   sidx.erase(iter, eiter);      // just lob it off from the beginning
 }
 
+
+template <typename T> void moveCacheItemToFrontOrBack(T& collection, typename T::iterator& iter, bool front)
+{
+  typedef typename T::template nth_index<1>::type sequence_t;
+  sequence_t& sidx=collection.get<1>();
+  typename sequence_t::iterator si=collection.project<1>(iter);
+  if(front)
+    sidx.relocate(sidx.begin(), si); // at the beginning of the delete queue
+  else
+    sidx.relocate(sidx.end(), si);  // back
+}
+
+template <typename T> void moveCacheItemToFront(T& collection, typename T::iterator& iter)
+{
+  moveCacheItemToFrontOrBack(collection, iter, true);
+}
+
+template <typename T> void moveCacheItemToBack(T& collection, typename T::iterator& iter)
+{
+  moveCacheItemToFrontOrBack(collection, iter, false);
+}
+
 #endif
index dd2ee75e305a6f16743c6123deefcaf436117c7f..37a1af51c4fab042c7abeae1ebc20206106069b3 100644 (file)
@@ -23,9 +23,6 @@ bool RecursorPacketCache::getResponsePacket(const std::string& queryPacket, time
     d_misses++;
     return false;
   }
-  typedef packetCache_t::nth_index<1>::type sequence_t;
-  sequence_t& sidx=d_packetCache.get<1>();
-  sequence_t::iterator si=d_packetCache.project<1>(iter);
     
   if((uint32_t)now < iter->d_ttd) { // it is fresh!
 //    cerr<<"Fresh for another "<<iter->d_ttd - now<<" seconds!"<<endl;
@@ -34,12 +31,11 @@ bool RecursorPacketCache::getResponsePacket(const std::string& queryPacket, time
     *responsePacket = iter->d_packet;
     ((struct dnsheader*)responsePacket->c_str())->id=id;
     d_hits++;
-
-    sidx.relocate(sidx.end(), si); // put it at the end of the delete queue
+    moveCacheItemToBack(d_packetCache, iter);
 
     return true;
   }
-  sidx.relocate(sidx.begin(), si); // at the beginning of the delete queue
+  moveCacheItemToFront(d_packetCache, iter);
   d_misses++;
   return false;
 }
index 80764e597d3efdfaa48d9f2faf696a0708ba3756..ff71142899d92ad6626000299ac6b44bfa220f07 100644 (file)
@@ -124,11 +124,7 @@ int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<
     for(cache_t::const_iterator i=d_cachecache.first; i != d_cachecache.second; ++i) 
       if(i->d_qtype == qt.getCode() || qt.getCode()==QType::ANY || 
          (qt.getCode()==QType::ADDR && (i->d_qtype == QType::A || i->d_qtype == QType::AAAA) )
-         ) {
-        typedef cache_t::nth_index<1>::type sequence_t;
-        sequence_t& sidx=d_cache.get<1>();
-        sequence_t::iterator si=d_cache.project<1>(i);
-        
+         ) {     
         for(vector<StoredRecord>::const_iterator k=i->d_records.begin(); k != i->d_records.end(); ++k) {
           if(k->d_ttd < 1000000000 || k->d_ttd > (uint32_t) now) {  // FIXME what does the 100000000 number mean?
             ttd=k->d_ttd;
@@ -140,9 +136,9 @@ int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<
         }
         if(res) {
           if(res->empty())
-            sidx.relocate(sidx.begin(), si); 
+            moveCacheItemToFront(d_cache, i);
           else
-            sidx.relocate(sidx.end(), si); 
+            moveCacheItemToBack(d_cache, i);
         }
         if(qt.getCode()!=QType::ANY && qt.getCode()!=QType::ADDR) // normally if we have a hit, we are done
           break;
index cabb156378967f81405a891c61c326ac014eeb47..22dd5443372ac4072127088172e53a4151e1cfbe 100644 (file)
@@ -36,6 +36,7 @@
 #include "dnsparser.hh"
 #include "dns_random.hh"
 #include "lock.hh"
+#include "cachecleaner.hh"
 
 __thread SyncRes::StaticStorage* t_sstorage;
 
@@ -429,11 +430,13 @@ int SyncRes::doResolve(const string &qname, const QType &qtype, vector<DNSResour
   return res<0 ? RCode::ServFail : res;
 }
 
+#if 0
 // for testing purpoises
 static bool ipv6First(const ComboAddress& a, const ComboAddress& b)
 {
   return !(a.sin4.sin_family < a.sin4.sin_family);
 }
+#endif
 
 /** This function explicitly goes out for A addresses, but if configured to use IPv6 as well, will also return any IPv6 addresses in the cache
     Additionally, it will return the 'best' address up front, and the rest shufled
@@ -649,10 +652,12 @@ bool SyncRes::doCacheCheck(const string &qname, const QType &qtype, vector<DNSRe
         giveNegative=true;
         sqname=ni->d_qname;
         sqt=QType::SOA;
+        moveCacheItemToBack(t_sstorage->negcache, ni);
         break;
       }
       else {
-        LOG<<prefix<<qname<<": Entire record '"<<qname<<"' was negatively cached, but entry expired"<<endl;
+        LOG<<prefix<<qname<<": Entire record '"<<qname<<"' or type was negatively cached, but entry expired"<<endl;
+        moveCacheItemToFront(t_sstorage->negcache, ni);
       }
     }
   }