Changeset 656

Show
Ignore:
Timestamp:
04/04/06 17:26:07 (4 years ago)
Author:
ahu
Message:

move cache to being pruned 'CLOCK' fashion

Location:
trunk/pdns/pdns
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/pdns_recursor.cc

    r652 r656  
    290290    if(res<0) { 
    291291      pw.getHeader()->rcode=RCode::ServFail; 
    292       pw.commit(); 
     292      // no commit here, because no record 
    293293      g_stats.servFails++; 
    294294    } 
     
    679679    ::arg().set("max-tcp-clients","Maximum number of simultaneous TCP clients")="128"; 
    680680    ::arg().set("hint-file", "If set, load root hints from this file")=""; 
     681    ::arg().set("max-cache-entries", "If set, maximum number of entries in the main cache")="0"; 
    681682 
    682683    ::arg().setCmd("help","Provide a helpful message"); 
  • trunk/pdns/pdns/rec_channel_rec.cc

    r647 r656  
    9292} 
    9393 
     94template<typename T> 
     95string doSlashCache(T begin, T end) 
     96{ 
     97  RC.doSlash(10); 
     98 
     99  return "done\n"; 
     100} 
    94101 
    95102uint32_t getQueryRate() 
     
    187194    return doDumpCache(begin, end); 
    188195 
     196  if(cmd=="slash-cache")  
     197    return doSlashCache(begin, end); 
     198 
    189199  if(cmd=="wipe-cache")  
    190200    return doWipeCache(begin, end); 
  • trunk/pdns/pdns/recursor_cache.cc

    r646 r656  
    44#include <boost/shared_ptr.hpp> 
    55#include "dnsrecords.hh" 
     6#include <malloc.h> 
     7#include "arguments.hh" 
    68 
    79using namespace std; 
     
    100102    if(res) { 
    101103      for(cache_t::const_iterator i=d_cachecache.first; i != d_cachecache.second; ++i)  
    102         if(i->d_qtype == qt.getCode())  
     104        if(i->d_qtype == qt.getCode()) { 
     105          typedef cache_t::nth_index<1>::type sequence_t; 
     106          sequence_t& sidx=d_cache.get<1>(); 
     107          sequence_t::iterator si=d_cache.project<1>(i); 
     108 
    103109          for(vector<StoredRecord>::const_iterator k=i->d_records.begin(); k != i->d_records.end(); ++k) { 
    104110            if(k->d_ttd > (uint32_t) now) { 
     
    107113            } 
    108114          } 
     115          if(res->empty()) 
     116            sidx.relocate(sidx.begin(), si);  
     117          else 
     118            sidx.relocate(sidx.end(), si);  
     119          break; 
     120        } 
    109121    } 
    110122 
     
    124136  tuple<string, uint16_t> key=make_tuple(toLowerCanonic(qname), qt.getCode()); 
    125137  cache_t::iterator stored=d_cache.find(key); 
     138 
     139  //  cerr<<"storing "<< toLowerCanonic(qname)+"|"+qt.getName()<<"\n"; 
    126140   
    127141  bool isNew=false; 
     
    180194    return; 
    181195  } 
     196 
     197  typedef cache_t::nth_index<1>::type sequence_t; 
     198  sequence_t& sidx=d_cache.get<1>(); 
     199 
    182200  time_t now=time(0); 
    183   for(cache_t::const_iterator i=d_cache.begin(); i!=d_cache.end(); ++i) { 
     201  for(sequence_t::const_iterator i=sidx.begin(); i != sidx.end(); ++i) { 
    184202    for(vector<StoredRecord>::const_iterator j=i->d_records.begin(); j != i->d_records.end(); ++j) { 
    185203      DNSResourceRecord rr=String2DNSRR(i->d_qname, QType(i->d_qtype), j->d_string, j->d_ttd - now); 
     
    190208} 
    191209 
     210void MemRecursorCache::doSlash(int perc) 
     211{ 
     212  doPrune(); 
     213} 
     214 
    192215void MemRecursorCache::doPrune(void) 
    193216{ 
    194217  uint32_t now=(uint32_t)time(0); 
    195218  d_cachecachevalid=false; 
    196 //  cout<<"Going to prune!\n"; 
    197  
    198   typedef cache_t::nth_index<1>::type cache_by_ttd_t; 
    199   cache_by_ttd_t& ttdindex=d_cache.get<1>(); 
    200  
    201   uint32_t looked(0), quickZonk(0), fullZonk(0), partialZonk(0), noZonk(0); 
    202   DTime dt; 
    203   dt.set();  
    204   cache_by_ttd_t::iterator j; 
    205   for(j=ttdindex.begin();j!=ttdindex.end();){ 
    206     if(j->getTTD() > now) { 
    207 //      cout<<"Done pruning, this record ("<<j->d_name<<") only needs to get killed in "<< j->getTTD() - now <<" seconds, rest will be later\n"; 
     219 
     220  unsigned int maxCached=::arg().asNum("max-cache-entries"); 
     221  unsigned int toTrim=0; 
     222   
     223  unsigned int cacheSize=d_cache.size(); 
     224 
     225  if(maxCached && cacheSize > maxCached) 
     226    toTrim = cacheSize - maxCached; 
     227 
     228  //  cout<<"Need to trim "<<toTrim<<" from cache to meet target!\n"; 
     229 
     230  typedef cache_t::nth_index<1>::type sequence_t; 
     231  sequence_t& sidx=d_cache.get<1>(); 
     232 
     233 
     234  unsigned int tried=0, lookAt, erased=0; 
     235 
     236  // two modes - if toTrim is 0, just look through 10000 records and nuke everything that is expired 
     237  // otherwise, scan first 5*toTrim records, and stop once we've nuked enough 
     238  if(toTrim) 
     239    lookAt=5*toTrim; 
     240  else 
     241    lookAt=10000; 
     242 
     243 
     244  sequence_t::iterator iter=sidx.begin(), eiter; 
     245  for(; iter != sidx.end() && tried < lookAt ; ++tried) { 
     246    if(iter->getTTD() < now) { 
     247      sidx.erase(iter++); 
     248      erased++; 
     249    } 
     250    else 
     251      ++iter; 
     252 
     253    if(toTrim && erased > toTrim) 
    208254      break; 
    209     } 
    210     else  
    211         ; 
    212 //      cout<<"Looking at '"<<j->d_name<<"', "<<now - j->getTTD()<<" seconds overdue!\n"; 
    213     looked++; 
    214     if(j->d_records.size()==1) { 
    215       j++; 
    216       quickZonk++; 
    217       continue; 
    218     } 
    219     predicate p(now); 
    220     CacheEntry ce=*j; 
    221  
    222     size_t before=ce.d_records.size(); 
    223     ce.d_records.erase(remove_if(ce.d_records.begin(), ce.d_records.end(), p), ce.d_records.end()); 
    224  
    225     if(ce.d_records.empty()) { // everything is gone 
    226 //      cout<<"Zonked it entirely!\n"; 
    227       j++; 
    228       fullZonk++; 
    229     } 
    230     else { 
    231       if(ce.d_records.size()!=before) { 
    232 //      cout<<"Zonked partially, putting back, new TTD: "<< ce.getTTD() - now<<endl;; 
    233         cache_by_ttd_t::iterator here=j++; 
    234         ttdindex.replace(here, ce); 
    235         partialZonk++; 
    236       } 
    237       else { 
    238         ++j; 
    239         noZonk++; 
    240         break; 
    241       } 
    242     } 
    243   } 
    244    
    245   //  cout<<"Walk took "<< dt.udiff()<<"usec\n"; 
    246   //  dt.set(); 
    247   ttdindex.erase(ttdindex.begin(), j); 
    248 //    cout<<"Erase took "<< dt.udiff()<<" usec, looked: "<<looked<<", quick: "<<quickZonk<<", full: "; 
    249  //   cout<<fullZonk<<", partial: "<<partialZonk<<", no: "<<noZonk<<"\n"; 
    250   //  cache_t(d_cache).swap(d_cache); 
    251 } 
    252  
     255  } 
     256 
     257  //  cout<<"erased "<<erased<<" records based on ttd\n"; 
     258   
     259  if(erased >= toTrim) 
     260    return; 
     261 
     262  //  if(toTrim) 
     263  //    cout<<"Still have "<<toTrim - erased<<" entries left to erase to meet target\n"; 
     264 
     265 
     266  eiter=iter=sidx.begin(); 
     267  advance(eiter, toTrim); 
     268  sidx.erase(iter, eiter); 
     269} 
     270 
  • trunk/pdns/pdns/recursor_cache.hh

    r646 r656  
    1212#include <boost/tuple/tuple_comparison.hpp> 
    1313#include <boost/multi_index/key_extractors.hpp> 
     14#include <boost/multi_index/sequenced_index.hpp> 
    1415#include <boost/version.hpp> 
    1516#if BOOST_VERSION >= 103300 
     
    3233  void replace(const string &qname, const QType& qt,  const set<DNSResourceRecord>& content); 
    3334  void doPrune(void); 
     35  void doSlash(int perc); 
    3436  void doDumpAndClose(int fd); 
    3537  void doWipeCache(const string& name); 
     
    103105                      > 
    104106                >, 
    105                 ordered_non_unique<const_mem_fun<CacheEntry,uint32_t,&CacheEntry::getTTD> > 
     107               sequenced<> 
    106108               > 
    107109  > cache_t; 
     
    109111private: 
    110112  cache_t d_cache; 
    111   pair<cache_t::const_iterator, cache_t::const_iterator> d_cachecache; 
     113  pair<cache_t::iterator, cache_t::iterator> d_cachecache; 
    112114  string d_cachedqname; 
    113115  bool d_cachecachevalid;