]> granicus.if.org Git - pdns/commitdiff
adaptive packetcache cleaning interval
authorKees Monshouwer <mind04@monshouwer.org>
Tue, 27 Sep 2016 08:55:47 +0000 (10:55 +0200)
committermind04 <mind04@monshouwer.org>
Wed, 28 Sep 2016 14:27:05 +0000 (16:27 +0200)
pdns/packetcache.cc
pdns/packetcache.hh

index 3b0d301d047902f03cb8d284adc37b5863d08d34..e523014f703acd4cdac642da22efa667bc277540 100644 (file)
@@ -43,6 +43,10 @@ PacketCache::PacketCache()
   d_ttl=-1;
   d_recursivettl=-1;
 
+  d_lastclean=time(0);
+  d_cleanskipped=false;
+  d_nextclean=d_cleaninterval=4096;
+
   S.declare("packetcache-hit");
   S.declare("packetcache-miss");
   S.declare("packetcache-size");
@@ -408,7 +412,7 @@ void PacketCache::cleanup()
 
   DLOG(L<<"Starting cache clean, cacheSize: "<<cacheSize<<", lookAt: "<<lookAt<<", toTrim: "<<toTrim<<endl);
 
-  time_t now=time(0);
+  time_t now = time(0);
   unsigned int totErased = 0;
   for(auto& mc : d_maps) {
     WriteLock wl(&mc.d_mut);
@@ -434,3 +438,35 @@ void PacketCache::cleanup()
 
   DLOG(L<<"Done with cache clean, cacheSize: "<<*d_statnumentries<<", totErased"<<totErased<<endl);
 }
+
+void PacketCache::cleanupIfNeeded()
+{
+  if (d_ops++ == d_nextclean) {
+    int timediff = max((int)(time(0) - d_lastclean), 1);
+
+    DLOG(L<<"cleaninterval: "<<d_cleaninterval<<", timediff: "<<timediff<<endl);
+
+    if (d_cleaninterval == 300000 && timediff < 30) {
+      d_cleanskipped = true;
+      d_nextclean += d_cleaninterval;
+
+      DLOG(L<<"cleaning skipped, timediff: "<<timediff<<endl);
+
+      return;
+    }
+
+    if(!d_cleanskipped) {
+      d_cleaninterval=(int)(0.6*d_cleaninterval)+(0.4*d_cleaninterval*(30.0/timediff));
+      d_cleaninterval=std::max(d_cleaninterval, 1000);
+      d_cleaninterval=std::min(d_cleaninterval, 300000);
+
+      DLOG(L<<"new cleaninterval: "<<d_cleaninterval<<endl);
+    } else {
+      d_cleanskipped = false;
+    }
+
+    d_nextclean += d_cleaninterval;
+    d_lastclean=time(0);
+    cleanup();
+  }
+}
index dd23524cb0e84d00755be2f399f1a22830971515..957ff8dbce91e316a965db3c03e089999a251dc5 100644 (file)
@@ -69,15 +69,7 @@ public:
   
 
   int size() { return *d_statnumentries; } //!< number of entries in the cache
-  void cleanupIfNeeded()
-  {
-    if(!(++d_ops % 300000)) {
-      if(d_lastclean + 30 < time(0)) {
-        d_lastclean=time(0); 
-        cleanup();
-      }
-    }
-  }
+  void cleanupIfNeeded();
   void cleanup(); //!< force the cache to preen itself from expired packets
   int purge();
   int purge(const std::string& match); // could be $ terminated. Is not a dnsname!
@@ -155,7 +147,10 @@ private:
   }
 
   AtomicCounter d_ops;
-  time_t d_lastclean{0}; // doesn't need to be atomic
+  time_t d_lastclean; // doesn't need to be atomic
+  unsigned long d_nextclean;
+  int d_cleaninterval;
+  bool d_cleanskipped;
   AtomicCounter *d_statnumhit;
   AtomicCounter *d_statnummiss;
   AtomicCounter *d_statnumentries;