--- /dev/null
+#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
#endif // WIN32
#include <boost/foreach.hpp>
+
#include <pthread.h>
#include "recpacketcache.hh"
#include "utility.hh"
#include <map>
#include <set>
#include "recursor_cache.hh"
+#include "cachecleaner.hh"
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <iostream>
#include "recpacketcache.hh"
+#include "cachecleaner.hh"
#include "dns.hh"
#include "namespaces.hh"
#include "lock.hh"
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);
}
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<
#include "arguments.hh"
#include "syncres.hh"
#include "recursor_cache.hh"
+#include "cachecleaner.hh"
using namespace std;
#include "namespaces.hh"
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);
}