// this function can clean any cache that has a getTTD() method on its entries, a preRemoval() method and a 'sequence' index as its second index
// the ritual is that the oldest entries are in *front* of the sequence collection, so on a hit, move an item to the end
// on a miss, move it to the beginning
-template <typename S, typename C, typename T> void pruneCollection(C& container, T& collection, unsigned int maxCached, unsigned int scanFraction=1000)
+template <typename S, typename C, typename T> void pruneCollection(C& container, T& collection, size_t maxCached, size_t scanFraction = 1000)
{
- time_t now=time(0);
- unsigned int toTrim=0;
-
- unsigned int cacheSize=collection.size();
+ const time_t now = time(0);
+ size_t toTrim = 0;
+ const size_t cacheSize = collection.size();
- if(cacheSize > maxCached) {
+ if (cacheSize > maxCached) {
toTrim = cacheSize - maxCached;
}
-// cout<<"Need to trim "<<toTrim<<" from cache to meet target!\n";
-
- typedef typename T::template index<S>::type sequence_t;
- sequence_t& sidx=collection.template get<S>();
-
- unsigned int tried=0, lookAt, erased=0;
+ auto& sidx = collection.template get<S>();
// two modes - if toTrim is 0, just look through 1/scanFraction 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/scanFraction;
+ const size_t lookAt = toTrim ? 5 * toTrim : cacheSize / scanFraction;
+ size_t tried = 0, erased = 0;
- typename sequence_t::iterator iter=sidx.begin(), eiter;
- for(; iter != sidx.end() && tried < lookAt ; ++tried) {
- if(iter->getTTD() < now) {
+ for (auto iter = sidx.begin(); iter != sidx.end() && tried < lookAt ; ++tried) {
+ if (iter->getTTD() < now) {
container.preRemoval(*iter);
iter = sidx.erase(iter);
erased++;
}
- else
+ else {
++iter;
+ }
- if(toTrim && erased >= toTrim)
+ if (toTrim && erased >= toTrim) {
break;
+ }
}
- //cout<<"erased "<<erased<<" records based on ttd\n";
-
- if(erased >= toTrim) // done
+ 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);
// just lob it off from the beginning
- for (auto i = iter; ; ) {
- if (i == eiter) {
- break;
- }
-
- container.preRemoval(*i);
- sidx.erase(i++);
+ auto iter = sidx.begin();
+ for (size_t i = 0; i < toTrim && iter != sidx.end(); i++) {
+ container.preRemoval(*iter);
+ iter = sidx.erase(iter);
}
}
bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, uint16_t* ecsBegin, uint16_t* ecsEnd, RecProtoBufMessage* protobufMessage);
bool getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, uint16_t* ecsBegin, uint16_t* ecsEnd, RecProtoBufMessage* protobufMessage);
void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, uint16_t ecsBegin, uint16_t ecsEnd, boost::optional<RecProtoBufMessage>&& protobufMessage);
- void doPruneTo(unsigned int maxSize=250000);
+ void doPruneTo(size_t maxSize=250000);
uint64_t doDump(int fd);
int doWipePacketCache(const DNSName& name, uint16_t qtype=0xffff, bool subtree=false);