]> granicus.if.org Git - pdns/commitdiff
unify existing cache cleaning algorithms into one bit of code. Next up: the negcache
authorBert Hubert <bert.hubert@netherlabs.nl>
Mon, 30 Aug 2010 20:03:55 +0000 (20:03 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Mon, 30 Aug 2010 20:03:55 +0000 (20:03 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1702 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/cachecleaner.hh [new file with mode: 0644]
pdns/pdns_recursor.cc
pdns/recpacketcache.cc
pdns/recpacketcache.hh
pdns/recursor_cache.cc

diff --git a/pdns/cachecleaner.hh b/pdns/cachecleaner.hh
new file mode 100644 (file)
index 0000000..af2e82a
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef PDNS_CACHECLEANER_HH
+#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
+template <typename T> void pruneCollection(T& collection, unsigned int maxCached)
+{
+  uint32_t now=(uint32_t)time(0);
+  unsigned int toTrim=0;
+  
+  unsigned int cacheSize=collection.size();
+
+  if(maxCached && cacheSize > maxCached) {
+    toTrim = cacheSize - maxCached;
+  }
+
+//  cout<<"Need to trim "<<toTrim<<" from cache to meet target!\n";
+
+  typedef typename T::template nth_index<1>::type sequence_t;
+  sequence_t& sidx=collection.get<1>();
+
+  unsigned int tried=0, lookAt, erased=0;
+
+  // two modes - if toTrim is 0, just look through 10000 records and nuke everything that is expired
+  // otherwise, scan first 5*toTrim records, and stop once we've nuked enough
+  if(toTrim)
+    lookAt=5*toTrim;
+  else
+    lookAt=cacheSize/1000;
+
+  typename sequence_t::iterator iter=sidx.begin(), eiter;
+  for(; iter != sidx.end() && tried < lookAt ; ++tried) {
+    if(iter->getTTD() < now) { 
+      sidx.erase(iter++);
+      erased++;
+    }
+    else
+      ++iter;
+
+    if(toTrim && erased > toTrim)
+      break;
+  }
+
+  //cout<<"erased "<<erased<<" records based on ttd\n";
+  
+  if(erased >= toTrim) // done
+    return;
+
+  toTrim -= erased;
+
+  //if(toTrim)
+    // cout<<"Still have "<<toTrim - erased<<" entries left to erase to meet target\n"; 
+
+  eiter=iter=sidx.begin();
+  std::advance(eiter, toTrim); 
+  sidx.erase(iter, eiter);      // just lob it off from the beginning
+}
+
+#endif
index dc3af7eab64e5b0a148a5ed3e5a334c1e2738518..d849d597a0affd7b5901ac524d6568a9ee76e7cf 100644 (file)
@@ -26,6 +26,7 @@
 #endif // WIN32
 
 #include <boost/foreach.hpp>
+
 #include <pthread.h>
 #include "recpacketcache.hh"
 #include "utility.hh" 
@@ -35,6 +36,7 @@
 #include <map>
 #include <set>
 #include "recursor_cache.hh"
+#include "cachecleaner.hh"
 #include <stdio.h>
 #include <signal.h>
 #include <stdlib.h>
index 99809297c5886df6cfcc0697758c179e2e3d87ed..dd2ee75e305a6f16743c6123deefcaf436117c7f 100644 (file)
@@ -1,5 +1,6 @@
 #include <iostream>
 #include "recpacketcache.hh"
+#include "cachecleaner.hh"
 #include "dns.hh"
 #include "namespaces.hh"
 #include "lock.hh"
@@ -65,59 +66,8 @@ uint64_t RecursorPacketCache::size()
   return d_packetCache.size();
 }
 
-// this code is almost a copy of the one in recursor_cache.cc
 void RecursorPacketCache::doPruneTo(unsigned int maxCached)
 {
-  uint32_t now=(uint32_t)time(0);
-  unsigned int toTrim=0;
-  
-  unsigned int cacheSize=d_packetCache.size();
-
-  if(maxCached && cacheSize > maxCached) {
-    toTrim = cacheSize - maxCached;
-  }
-
-//  cout<<"Need to trim "<<toTrim<<" from cache to meet target!\n";
-
-  typedef packetCache_t::nth_index<1>::type sequence_t;
-  sequence_t& sidx=d_packetCache.get<1>();
-
-  unsigned int tried=0, lookAt, erased=0;
-
-  // two modes - if toTrim is 0, just look through 10000 records and nuke everything that is expired
-  // otherwise, scan first 5*toTrim records, and stop once we've nuked enough
-  if(toTrim)
-    lookAt=5*toTrim;
-  else
-    lookAt=cacheSize/1000;
-
-
-  sequence_t::iterator iter=sidx.begin(), eiter;
-  for(; iter != sidx.end() && tried < lookAt ; ++tried) {
-    if(iter->d_ttd < now) { 
-      sidx.erase(iter++);
-      erased++;
-    }
-    else
-      ++iter;
-
-    if(toTrim && erased > toTrim)
-      break;
-  }
-
-  //cout<<"erased "<<erased<<" records based on ttd\n";
-  
-  if(erased >= toTrim) // done
-    return;
-
-
-  toTrim -= erased;
-
-  //if(toTrim)
-    // cout<<"Still have "<<toTrim - erased<<" entries left to erase to meet target\n"; 
-
-  eiter=iter=sidx.begin();
-  std::advance(eiter, toTrim); 
-  sidx.erase(iter, eiter);      // just lob it off from the beginning
+  pruneCollection(d_packetCache, maxCached);
 }
 
index 5d6ba7b317ec34733bf8b029076dc3f37d5767b2..a35f36a3a9cb1e4f193233bc99a74d34c14c861b 100644 (file)
@@ -36,6 +36,11 @@ private:
     mutable std::string d_packet; // "I know what I am doing"
 
     inline bool operator<(const struct Entry& rhs) const;
+    
+    uint32_t getTTD() const
+    {
+      return d_ttd;
+    }
   };
  
   typedef multi_index_container<
index a11f83eb45d4132e25159d8ac593fda40323f79c..80764e597d3efdfaa48d9f2faf696a0708ba3756 100644 (file)
@@ -6,6 +6,7 @@
 #include "arguments.hh"
 #include "syncres.hh"
 #include "recursor_cache.hh"
+#include "cachecleaner.hh"
 
 using namespace std;
 #include "namespaces.hh"
@@ -354,58 +355,9 @@ uint64_t MemRecursorCache::doDump(int fd)
 
 void MemRecursorCache::doPrune(void)
 {
-  uint32_t now=(uint32_t)time(0);
   d_cachecachevalid=false;
 
   unsigned int maxCached=::arg().asNum("max-cache-entries") / g_numThreads;
-  unsigned int toTrim=0;
-  
-  unsigned int cacheSize=d_cache.size();
-
-  if(maxCached && cacheSize > maxCached) {
-    toTrim = cacheSize - maxCached;
-  }
-  
-  //  cout<<"Need to trim "<<toTrim<<" from cache to meet target!\n";
-
-  typedef cache_t::nth_index<1>::type sequence_t;
-  sequence_t& sidx=d_cache.get<1>();
-
-  unsigned int tried=0, lookAt, erased=0;
-
-  // two modes - if toTrim is 0, just look through 0.1% of all records and nuke everything that is expired
-  // otherwise, scan first 5*toTrim records, and stop once we've nuked enough
-  if(toTrim)
-    lookAt=5*toTrim;
-  else
-    lookAt=cacheSize/1000;
-
-  sequence_t::iterator iter=sidx.begin(), eiter;
-  for(; iter != sidx.end() && tried < lookAt ; ++tried) {
-    unsigned int ttd=iter->getTTD();
-    if(ttd < now) { 
-      sidx.erase(iter++);
-      erased++;
-    }
-    else
-      ++iter;
-
-    if(toTrim && erased > toTrim)
-      break;
-  }
-
-  //  cout<<"erased "<<erased<<" records based on ttd\n";
-  
-  if(erased >= toTrim)
-    return;
-
-  //  if(toTrim)
-  //    cout<<"Still have "<<toTrim - erased<<" entries left to erase to meet target\n";
-
-  toTrim -= erased;
-
-  eiter=iter=sidx.begin();
-  std::advance(eiter, toTrim);
-  sidx.erase(iter, eiter);
+  pruneCollection(d_cache, maxCached);
 }