PacketCache::PacketCache()
{
pthread_rwlock_init(&d_mut,0);
- pthread_mutex_init(&d_dellock,0);
d_hit=d_miss=0;
d_ttl=-1;
cmap_t::iterator place;
tie(place, success)=d_map.insert(val);
// cerr<<"Insert succeeded: "<<success<<endl;
- // if(!success)
- // cerr<<"Replace: "<<d_map.replace(place, val)<<endl;
+ if(!success)
+ d_map.replace(place, val);
}
else
S.inc("deferred-cache-inserts");
}
-/** purges entries from the packetcache. If prefix ends on a $, it is treated as a suffix */
-int PacketCache::purge(const string &f_prefix)
+/** purges entries from the packetcache. If match ends on a $, it is treated as a suffix */
+int PacketCache::purge(const string &match)
{
- Lock pl(&d_dellock);
-
- string prefix(f_prefix);
- if(prefix.empty()) {
- cmap_t *tmp=new cmap_t;
- {
- DTime dt;
- dt.set();
- WriteLock l(&d_mut);
- tmp->swap(d_map);
- L<<Logger::Error<<"cache clean time: "<<dt.udiff()<<"usec"<<endl;
- }
-
- int size=tmp->size();
- delete tmp;
+ WriteLock l(&d_mut);
+ int delcount;
+ if(match.empty()) {
+ delcount = d_map.size();
+ d_map.clear();
*statnumentries=0;
- return size;
- }
-
- bool suffix=false;
- if(prefix[prefix.size()-1]=='$') {
- prefix=prefix.substr(0,prefix.size()-1);
- suffix=true;
+ return delcount;
}
- string check=prefix+"|";
- vector<cmap_t::iterator> toRemove;
+ /* ok, the suffix delete plan. We want to be able to delete everything that
+ pertains 'www.powerdns.com' but we also want to be able to delete everything
+ in the powerdns.com zone, so: 'powerdns.com' and '*.powerdns.com'.
- ReadLock l(&d_mut);
-
- for(cmap_t::iterator i=d_map.begin();i!=d_map.end();++i) {
- string::size_type pos=i->qname.find(check);
+ However, we do NOT want to delete 'usepowerdns.com!'
+ */
- if(!pos || (suffix && pos!=string::npos))
- toRemove.push_back(i);
- }
+ delcount=d_map.count(tie(match));
+ pair<cmap_t::iterator, cmap_t::iterator> range = d_map.equal_range(tie(match));
+ d_map.erase(range.first, range.second);
- l.upgrade();
-
- for(vector<cmap_t::iterator>::const_iterator i=toRemove.begin();i!=toRemove.end();++i)
- d_map.erase(*i);
*statnumentries=d_map.size();
- return toRemove.size();
+ return delcount;
}
bool PacketCache::getEntry(const string &qname, const QType& qtype, CacheEntryType cet, string& value, int zoneID, bool meritsRecursion)
return false;
}
- // needs to do ttl check here
uint16_t qt = qtype.getCode();
cmap_t::const_iterator i=d_map.find(tie(qname, qt, cet, zoneID, meritsRecursion));
time_t now=time(0);
return ret;
}
-
int PacketCache::size()
{
ReadLock l(&d_mut);
/** readlock for figuring out which iterators to delete, upgrade to writelock when actually cleaning */
void PacketCache::cleanup()
{
- Lock pl(&d_dellock); // ALWAYS ACQUIRE DELLOCK FIRST
WriteLock l(&d_mut);
*statnumentries=d_map.size();