From 2667dc9a501b61a4c2750bd11666b215e557d2d5 Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Thu, 19 Jun 2008 21:47:55 +0000 Subject: [PATCH] initial cleanups for performance boost of packet cache git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1209 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- pdns/packetcache.cc | 108 +++++++++++++++++++++++++++++++------------- pdns/packetcache.hh | 102 ++--------------------------------------- 2 files changed, 81 insertions(+), 129 deletions(-) diff --git a/pdns/packetcache.cc b/pdns/packetcache.cc index 57f8b0a41..52765c3c9 100644 --- a/pdns/packetcache.cc +++ b/pdns/packetcache.cc @@ -42,32 +42,75 @@ PacketCache::PacketCache() statnumentries=S.getPointer("packetcache-size"); } - -void PacketCache::insert(DNSPacket *q, DNSPacket *r) +int PacketCache::get(DNSPacket *p, DNSPacket *cached) { - if(d_ttl < 0) - getTTLS(); - - if(ntohs(q->d.qdcount)!=1) { - L<<"Warning - tried to cache a packet with wrong number of questions: "<d.qdcount)<d.rd; + if(d_ttl<0) + getTTLS(); + if(d_doRecursion && p->d.rd) { // wants recursion + if(!d_recursivettl) { + (*statnummiss)++; + d_miss++; + return 0; + } + } + else { // does not + if(!d_ttl) { + (*statnummiss)++; + d_miss++; + return 0; + } + } + + bool packetMeritsRecursion=d_doRecursion && p->d.rd; char ckey[512]; - unsigned int len=q->qdomain.length(); - if(len > sizeof(ckey)) - return; - memcpy(ckey,q->qdomain.c_str(),len); // add TOLOWER HERE FIXME XXX + int len=p->qdomain.length(); + memcpy(ckey,p->qdomain.c_str(),len); // add TOLOWER HERE FIXME XXX ckey[len]='|'; ckey[len+1]=packetMeritsRecursion ? 'r' : 'n'; - ckey[len+2]=(q->qtype.getCode()>>8) & 0xff; - ckey[len+3]=(q->qtype.getCode()) & 0xff; + ckey[len+2]=(p->qtype.getCode()>>8)&0xff; + ckey[len+3]=(p->qtype.getCode())&0xff; string key; - key.assign(ckey,q->qdomain.length()+4); - insert(key,r->getString(), packetMeritsRecursion ? d_recursivettl : d_ttl); + key.assign(ckey,p->qdomain.length()+4); + // cout<<"key lookup: '"<qdomain+"|"+(packetMeritsRecursion ? "R" : "N")+ "|"+p->qtype.getName()); + + if(ntohs(p->d.qdcount)!=1) // we get confused by packets with more than one question + return 0; + + { + TryReadLock l(&d_mut); // take a readlock here + if(!l.gotIt()) { + S.inc("deferred-cache-lookup"); + return 0; + } + + if(!((d_hit+d_miss)%1000)) { + *statnumentries=d_map.size(); // needs lock + } + cmap_t::const_iterator i; + if((i=d_map.find(key))!=d_map.end()) { // HIT! + + if(i->second.ttd>time(0)) { // it is still fresh + (*statnumhit)++; + d_hit++; + if(cached->parse(i->second.value.c_str(), i->second.value.size()) < 0) { + return -1; + } + cached->spoofQuestion(p->qdomain); // for correct case + return 1; + } + } + } + (*statnummiss)++; + d_miss++; + return 0; // bummer } void PacketCache::getTTLS() @@ -78,34 +121,35 @@ void PacketCache::getTTLS() d_doRecursion=arg().mustDo("recursor"); } -void PacketCache::insert(const char *packet, int length) + +void PacketCache::insert(DNSPacket *q, DNSPacket *r) { - if(d_ttl<0) + if(d_ttl < 0) getTTLS(); + + if(ntohs(q->d.qdcount)!=1) { + L<<"Warning - tried to cache a packet with wrong number of questions: "<d.qdcount)<d.rd; char ckey[512]; - unsigned int len=p.qdomain.length(); + unsigned int len=q->qdomain.length(); if(len > sizeof(ckey)) return; - memcpy(ckey, p.qdomain.c_str(), len); // add TOLOWER HERE FIXME XXX + memcpy(ckey,q->qdomain.c_str(),len); // add TOLOWER HERE FIXME XXX ckey[len]='|'; ckey[len+1]=packetMeritsRecursion ? 'r' : 'n'; - ckey[len+2]=(p.qtype.getCode()>>8) & 0xff; - ckey[len+3]=(p.qtype.getCode()) & 0xff; + ckey[len+2]=(q->qtype.getCode()>>8) & 0xff; + ckey[len+3]=(q->qtype.getCode()) & 0xff; string key; - key.assign(ckey,p.qdomain.length()+4); - // string key=toLower(p.qdomain+"|"+(packetMeritsRecursion ? "R" : "N")+"|"+p.qtype.getName()); + key.assign(ckey,q->qdomain.length()+4); - string buffer; - buffer.assign(packet,length); - insert(key,buffer, packetMeritsRecursion ? d_recursivettl : d_ttl); + insert(key,r->getString(), packetMeritsRecursion ? d_recursivettl : d_ttl); } + void PacketCache::insert(const string &key, const string &packet, unsigned int ttl) { if(!ttl) diff --git a/pdns/packetcache.hh b/pdns/packetcache.hh index 0056bd294..c142d1314 100644 --- a/pdns/packetcache.hh +++ b/pdns/packetcache.hh @@ -1,6 +1,6 @@ /* PowerDNS Versatile Database Driven Nameserver - Copyright (C) 2002 PowerDNS.COM BV + Copyright (C) 2002 - 2008 PowerDNS.COM BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 @@ -63,14 +63,15 @@ class PacketCache public: PacketCache(); void insert(DNSPacket *q, DNSPacket *r); //!< We copy the contents of *p into our cache. Do not needlessly call this to insert questions already in the cache as it wastes resources - void insert(const char *packet, int length); - inline int get(DNSPacket *p, DNSPacket *q); //!< We return a dynamically allocated copy out of our cache. You need to delete it. You also need to spoof in the right ID with the DNSPacket.spoofID() method. + void insert(const string &key, const string &packet, unsigned int ttl); + + int get(DNSPacket *p, DNSPacket *q); //!< We return a dynamically allocated copy out of our cache. You need to delete it. You also need to spoof in the right ID with the DNSPacket.spoofID() method. bool getKey(const string &key, string &content); int size(); //!< number of entries in the cache void cleanup(); //!< force the cache to preen itself from expired packets int purge(const string &prefix=""); - void insert(const string &key, const string &packet, unsigned int ttl); + map getCounts(); private: typedef string ckey_t; @@ -84,31 +85,8 @@ private: typedef CacheContent cvalue_t; void getTTLS(); -#ifndef WIN32 - - struct compare_string - { - bool operator()(const string& s1, const string& s2) const - { - return s1 == s2; - } - }; - - struct hash_string - { - size_t operator()(const string& s) const - { - return __stl_hash_string(s.c_str()); - } - }; - - typedef hash_map cmap_t; - -#else typedef map< ckey_t, cvalue_t > cmap_t; -#endif // WIN32 - cmap_t d_map; pthread_rwlock_t d_mut; @@ -124,76 +102,6 @@ private: int *statnumentries; }; -inline int PacketCache::get(DNSPacket *p, DNSPacket *cached) -{ - extern StatBag S; - if(!((d_hit+d_miss)%5000)) { - cleanup(); - } - - if(d_ttl<0) - getTTLS(); - - if(d_doRecursion && p->d.rd) { // wants recursion - if(!d_recursivettl) { - (*statnummiss)++; - d_miss++; - return 0; - } - } - else { // does not - if(!d_ttl) { - (*statnummiss)++; - d_miss++; - return 0; - } - } - - bool packetMeritsRecursion=d_doRecursion && p->d.rd; - char ckey[512]; - int len=p->qdomain.length(); - memcpy(ckey,p->qdomain.c_str(),len); // add TOLOWER HERE FIXME XXX - ckey[len]='|'; - ckey[len+1]=packetMeritsRecursion ? 'r' : 'n'; - ckey[len+2]=(p->qtype.getCode()>>8)&0xff; - ckey[len+3]=(p->qtype.getCode())&0xff; - string key; - - key.assign(ckey,p->qdomain.length()+4); - // cout<<"key lookup: '"<qdomain+"|"+(packetMeritsRecursion ? "R" : "N")+ "|"+p->qtype.getName()); - - if(ntohs(p->d.qdcount)!=1) // we get confused by packets with more than one question - return 0; - - { - TryReadLock l(&d_mut); // take a readlock here - if(!l.gotIt()) { - S.inc("deferred-cache-lookup"); - return 0; - } - - if(!((d_hit+d_miss)%1000)) { - *statnumentries=d_map.size(); // needs lock - } - cmap_t::const_iterator i; - if((i=d_map.find(key))!=d_map.end()) { // HIT! - - if(i->second.ttd>time(0)) { // it is still fresh - (*statnumhit)++; - d_hit++; - if(cached->parse(i->second.value.c_str(), i->second.value.size()) < 0) { - return -1; - } - cached->spoofQuestion(p->qdomain); // for correct case - return 1; - } - } - } - (*statnummiss)++; - d_miss++; - return 0; // bummer -} #endif /* PACKETCACHE_HH */ -- 2.40.0