Show
Ignore:
Timestamp:
06/23/08 00:17:20 (5 years ago)
Author:
ahu
Message:

implement fast wiping of "ds9a.nl" and "blah.ds9a.nl" using inverted ordering

Files:
1 modified

Legend:

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

    r1219 r1220  
    2222#include "statbag.hh" 
    2323#include <map> 
     24#include <boost/algorithm/string.hpp> 
    2425 
    2526extern StatBag S; 
     
    130131    return; 
    131132   
    132   //  cerr<<"Inserting, cet: "<<(int)cet<<endl; 
     133  //  cerr<<"Inserting qname '"<<qname<<"', cet: "<<(int)cet<<", value: '"<< (cet ? value : "PACKET") <<"', qtype: "<<qtype.getName()<<endl; 
    133134 
    134135  CacheEntry val; 
     
    158159{ 
    159160  WriteLock l(&d_mut); 
    160   int delcount; 
     161  int delcount=0; 
    161162 
    162163  if(match.empty()) { 
     
    171172     in the powerdns.com zone, so: 'powerdns.com' and '*.powerdns.com'. 
    172173 
    173      However, we do NOT want to delete 'usepowerdns.com!' 
     174     However, we do NOT want to delete 'usepowerdns.com!, nor 'powerdnsiscool.com' 
     175 
     176     So, at first shot, store in reverse label order: 
     177 
     178     'be.someotherdomain' 
     179     'com.powerdns' 
     180     'com.powerdns.images' 
     181     'com.powerdns.www' 
     182     'com.powerdnsiscool' 
     183     'com.usepowerdns.www' 
     184 
     185     If we get a request to remove 'everything above powerdns.com', we do a search for 'com.powerdns' which is guaranteed to come first (it is shortest!) 
     186     Then we delete everything that is either equal to 'com.powerdns' or begins with 'com.powerdns.' This trailing dot saves us  
     187     from deleting 'com.powerdnsiscool'. 
     188 
     189     We can stop the process once we reach something that doesn't match. 
     190 
     191     Ok - fine so far, except it doesn't work! Let's say there *is* no 'com.powerdns' in cache! 
     192 
     193     In that case our request doesn't find anything.. now what. 
     194     lower_bound to the rescue! It finds the place where 'com.powerdns' *would* be. 
     195      
     196     Ok - next step, can we get away with simply reversing the string? 
     197 
     198     'moc.sndrewop' 
     199     'moc.sndrewop.segami' 
     200     'moc.sndrewop.www' 
     201     'moc.loocsidnsrewop' 
     202     'moc.dnsrewopesu.www' 
     203 
     204     Ok - next step, can we get away with only reversing the comparison? 
     205 
     206     'powerdns.com' 
     207     'images.powerdns.com' 
     208     '   www.powerdns.com' 
     209     'powerdnsiscool.com' 
     210     'www.userpowerdns.com' 
     211 
    174212  */ 
    175  
    176   delcount=d_map.count(tie(match)); 
    177   pair<cmap_t::iterator, cmap_t::iterator> range = d_map.equal_range(tie(match)); 
    178   d_map.erase(range.first, range.second); 
    179  
     213  if(ends_with(match, "$")) { 
     214    string suffix(match); 
     215    suffix.resize(suffix.size()-1); 
     216 
     217    //    cerr<<"Begin dump!"<<endl; 
     218    cmap_t::const_iterator iter = d_map.lower_bound(tie(suffix)); 
     219    cmap_t::const_iterator start=iter; 
     220    string dotsuffix = "."+suffix; 
     221 
     222    for(; iter != d_map.end(); ++iter) { 
     223      if(!iequals(iter->qname, suffix) && !iends_with(iter->qname, dotsuffix)) { 
     224        //      cerr<<"Stopping!"<<endl; 
     225        break; 
     226      } 
     227      //      cerr<<"Will erase '"<<iter->qname<<"'\n"; 
     228 
     229      delcount++; 
     230    } 
     231    //    cerr<<"End dump!"<<endl; 
     232    d_map.erase(start, iter); 
     233  } 
     234  else { 
     235    delcount=d_map.count(tie(match)); 
     236    pair<cmap_t::iterator, cmap_t::iterator> range = d_map.equal_range(tie(match)); 
     237    d_map.erase(range.first, range.second); 
     238  } 
    180239  *statnumentries=d_map.size(); 
    181240  return delcount;