and specifying them in the call if needed.
uint64_t AuthPacketCache::purgeExact(const DNSName& qname)
{
auto& mc = getMap(qname);
- uint64_t delcount = purgeExactLockedCollection(mc, qname);
+ uint64_t delcount = purgeExactLockedCollection<NameTag>(mc, qname);
*d_statnumentries -= delcount;
uint64_t delcount = 0;
if(ends_with(match, "$")) {
- delcount = purgeLockedCollectionsVector(d_maps, match);
+ delcount = purgeLockedCollectionsVector<NameTag>(d_maps, match);
*d_statnumentries -= delcount;
}
else {
uint64_t cacheSize = *d_statnumentries;
uint64_t totErased = 0;
- totErased = pruneLockedCollectionsVector(d_maps, maxCached, cacheSize);
+ totErased = pruneLockedCollectionsVector<SequencedTag>(d_maps, maxCached, cacheSize);
*d_statnumentries -= totErased;
DLOG(g_log<<"Done with cache clean, cacheSize: "<<(*d_statnumentries)<<", totErased"<<totErased<<endl);
struct HashTag{};
struct NameTag{};
- struct SequenceTag{};
+ struct SequencedTag{};
typedef multi_index_container<
CacheEntry,
indexed_by <
hashed_non_unique<tag<HashTag>, member<CacheEntry,uint32_t,&CacheEntry::hash> >,
ordered_non_unique<tag<NameTag>, member<CacheEntry,DNSName,&CacheEntry::qname>, CanonDNSNameCompare >,
- sequenced<tag<SequenceTag>>
+ sequenced<tag<SequencedTag>>
>
> cmap_t;
uint64_t AuthQueryCache::purgeExact(const DNSName& qname)
{
auto& mc = getMap(qname);
- uint64_t delcount = purgeExactLockedCollection(mc, qname);
+ uint64_t delcount = purgeExactLockedCollection<NameTag>(mc, qname);
*d_statnumentries -= delcount;
uint64_t delcount = 0;
if(ends_with(match, "$")) {
- delcount = purgeLockedCollectionsVector(d_maps, match);
+ delcount = purgeLockedCollectionsVector<NameTag>(d_maps, match);
*d_statnumentries -= delcount;
}
else {
uint64_t cacheSize = *d_statnumentries;
uint64_t totErased = 0;
- totErased = pruneLockedCollectionsVector(d_maps, maxCached, cacheSize);
+ totErased = pruneLockedCollectionsVector<SequencedTag>(d_maps, maxCached, cacheSize);
*d_statnumentries -= totErased;
DLOG(g_log<<"Done with cache clean, cacheSize: "<<*d_statnumentries<<", totErased"<<totErased<<endl);
struct HashTag{};
struct NameTag{};
- struct SequenceTag{};
+ struct SequencedTag{};
typedef multi_index_container<
CacheEntry,
indexed_by <
member<CacheEntry,uint16_t,&CacheEntry::qtype>,
member<CacheEntry,int, &CacheEntry::zoneID> > > ,
ordered_non_unique<tag<NameTag>, member<CacheEntry,DNSName,&CacheEntry::qname>, CanonDNSNameCompare >,
- sequenced<tag<SequenceTag>>
+ sequenced<tag<SequencedTag>>
>
> cmap_t;
// 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 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, unsigned int maxCached, unsigned int scanFraction=1000)
{
time_t now=time(0);
unsigned int toTrim=0;
// cout<<"Need to trim "<<toTrim<<" from cache to meet target!\n";
- typedef typename T::template nth_index<1>::type sequence_t;
- sequence_t& sidx=collection.template get<1>();
+ typedef typename T::template index<S>::type sequence_t;
+ sequence_t& sidx=collection.template get<S>();
unsigned int tried=0, lookAt, erased=0;
}
}
-// note: this expects iterator from first index, and sequence MUST be second index!
-template <typename T> void moveCacheItemToFrontOrBack(T& collection, typename T::iterator& iter, bool front)
+// note: this expects iterator from first index
+template <typename S, typename T> void moveCacheItemToFrontOrBack(T& collection, typename T::iterator& iter, bool front)
{
- typedef typename T::template nth_index<1>::type sequence_t;
- sequence_t& sidx=collection.template get<1>();
- typename sequence_t::iterator si=collection.template project<1>(iter);
+ typedef typename T::template index<S>::type sequence_t;
+ sequence_t& sidx=collection.template get<S>();
+ typename sequence_t::iterator si=collection.template project<S>(iter);
if(front)
sidx.relocate(sidx.begin(), si); // at the beginning of the delete queue
else
sidx.relocate(sidx.end(), si); // back
}
-template <typename T> void moveCacheItemToFront(T& collection, typename T::iterator& iter)
+template <typename S, typename T> void moveCacheItemToFront(T& collection, typename T::iterator& iter)
{
- moveCacheItemToFrontOrBack(collection, iter, true);
+ moveCacheItemToFrontOrBack<S>(collection, iter, true);
}
-template <typename T> void moveCacheItemToBack(T& collection, typename T::iterator& iter)
+template <typename S, typename T> void moveCacheItemToBack(T& collection, typename T::iterator& iter)
{
- moveCacheItemToFrontOrBack(collection, iter, false);
+ moveCacheItemToFrontOrBack<S>(collection, iter, false);
}
-template <typename T> uint64_t pruneLockedCollectionsVector(vector<T>& maps, uint64_t maxCached, uint64_t cacheSize)
+template <typename S, typename T> uint64_t pruneLockedCollectionsVector(vector<T>& maps, uint64_t maxCached, uint64_t cacheSize)
{
time_t now = time(nullptr);
uint64_t totErased = 0;
for(auto& mc : maps) {
WriteLock wl(&mc.d_mut);
- auto& sidx = boost::multi_index::get<2>(mc.d_map);
+ auto& sidx = boost::multi_index::get<S>(mc.d_map);
uint64_t erased = 0, lookedAt = 0;
for(auto i = sidx.begin(); i != sidx.end(); lookedAt++) {
if(i->ttd < now) {
return delcount;
}
-template <typename T> uint64_t purgeLockedCollectionsVector(vector<T>& maps, const std::string& match)
+template <typename N, typename T> uint64_t purgeLockedCollectionsVector(vector<T>& maps, const std::string& match)
{
uint64_t delcount=0;
string prefix(match);
DNSName dprefix(prefix);
for(auto& mc : maps) {
WriteLock wl(&mc.d_mut);
- auto& idx = boost::multi_index::get<1>(mc.d_map);
+ auto& idx = boost::multi_index::get<N>(mc.d_map);
auto iter = idx.lower_bound(dprefix);
auto start = iter;
return delcount;
}
-template <typename T> uint64_t purgeExactLockedCollection(T& mc, const DNSName& qname)
+template <typename N, typename T> uint64_t purgeExactLockedCollection(T& mc, const DNSName& qname)
{
uint64_t delcount=0;
WriteLock wl(&mc.d_mut);
- auto& idx = boost::multi_index::get<1>(mc.d_map);
+ auto& idx = boost::multi_index::get<N>(mc.d_map);
auto range = idx.equal_range(qname);
if(range.first != range.second) {
delcount += distance(range.first, range.second);
return delcount;
}
-template<typename Index>
+template<typename S, typename Index>
std::pair<typename Index::iterator,bool>
lruReplacingInsert(Index& i,const typename Index::value_type& x)
{
std::pair<typename Index::iterator,bool> res = i.insert(x);
if (!res.second) {
- moveCacheItemToBack(i, res.first);
+ moveCacheItemToBack<S>(i, res.first);
res.second = i.replace(res.first, x);
}
return res;
nce.d_value = value;
{
WriteLock l(&s_metacachelock);
- lruReplacingInsert(s_metacache, nce);
+ lruReplacingInsert<SequencedTag>(s_metacache, nce);
}
}
}
kce.d_ttd = now + ttl;
{
WriteLock l(&s_keycachelock);
- lruReplacingInsert(s_keycache, kce);
+ lruReplacingInsert<SequencedTag>(s_keycache, kce);
}
}
if(now.tv_sec - s_last_prune > (time_t)(30)) {
{
WriteLock l(&s_metacachelock);
- pruneCollection(*this, s_metacache, ::arg().asNum("max-cache-entries"));
+ pruneCollection<SequencedTag>(*this, s_metacache, ::arg().asNum("max-cache-entries"));
}
{
WriteLock l(&s_keycachelock);
- pruneCollection(*this, s_keycache, ::arg().asNum("max-cache-entries"));
+ pruneCollection<SequencedTag>(*this, s_keycache, ::arg().asNum("max-cache-entries"));
}
s_last_prune=time(0);
}
iter = d_limits.insert(e).first;
}
- moveCacheItemToBack(d_limits, iter);
+ moveCacheItemToBack<SequencedTag>(d_limits, iter);
return !iter->d_limiter.check(d_qps, d_burst);
}
}
};
+ struct KeyCacheTag{};
+ struct CompositeTag{};
+ struct SequencedTag{};
typedef multi_index_container<
KeyCacheEntry,
indexed_by<
- ordered_unique<member<KeyCacheEntry, DNSName, &KeyCacheEntry::d_domain> >,
- sequenced<>
+ ordered_unique<tag<KeyCacheTag>,member<KeyCacheEntry, DNSName, &KeyCacheEntry::d_domain> >,
+ sequenced<tag<SequencedTag>>
>
> keycache_t;
typedef multi_index_container<
METACacheEntry,
indexed_by<
- ordered_unique<
+ ordered_unique<tag<CompositeTag>,
composite_key<
METACacheEntry,
member<METACacheEntry, DNSName, &METACacheEntry::d_domain> ,
member<METACacheEntry, std::string, &METACacheEntry::d_key>
>, composite_key_compare<std::less<DNSName>, CIStringCompare> >,
- sequenced<>
+ sequenced<tag<SequencedTag>>
>
> metacache_t;
}
d_hits++;
- moveCacheItemToBack(d_packetCache, iter);
+ moveCacheItemToBack<SequencedTag>(d_packetCache, iter);
#ifdef HAVE_PROTOBUF
if (protobufMessage) {
if (iter->d_protobufMessage) {
return true;
}
else {
- moveCacheItemToFront(d_packetCache, iter);
+ moveCacheItemToFront<SequencedTag>(d_packetCache, iter);
d_misses++;
break;
}
continue;
}
- moveCacheItemToBack(d_packetCache, iter);
+ moveCacheItemToBack<SequencedTag>(d_packetCache, iter);
iter->d_packet = std::move(responsePacket);
iter->d_query = std::move(query);
iter->d_ecsBegin = ecsBegin;
void RecursorPacketCache::doPruneTo(unsigned int maxCached)
{
- pruneCollection(*this, d_packetCache, maxCached);
+ pruneCollection<SequencedTag>(*this, d_packetCache, maxCached);
}
uint64_t RecursorPacketCache::doDump(int fd)
}
};
+ struct SequencedTag{};
typedef multi_index_container<
Entry,
indexed_by <
hashed_non_unique<tag<HashTag>, composite_key<Entry, member<Entry,uint32_t,&Entry::d_tag>, member<Entry,uint32_t,&Entry::d_qhash> > >,
- sequenced<> ,
+ sequenced<tag<SequencedTag>> ,
ordered_non_unique<tag<NameTag>, member<Entry,DNSName,&Entry::d_name>, CanonDNSNameCompare >
>
> packetCache_t;
*wasAuth = entry->d_auth;
}
- moveCacheItemToBack(d_cache, entry);
+ moveCacheItemToBack<SequencedTag>(d_cache, entry);
return ttd;
}
}
else {
/* this netmask-specific entry has expired */
- moveCacheItemToFront(d_cache, entry);
+ moveCacheItemToFront<SequencedTag>(d_cache, entry);
ecsIndex->removeNetmask(best);
if (ecsIndex->isEmpty()) {
d_ecsIndex.erase(ecsIndex);
}
}
else {
- moveCacheItemToFront(d_cache, entry);
+ moveCacheItemToFront<SequencedTag>(d_cache, entry);
}
}
auto firstIndexIterator = d_cache.project<OrderedTag>(i);
if (i->d_ttd <= now) {
- moveCacheItemToFront(d_cache, firstIndexIterator);
+ moveCacheItemToFront<SequencedTag>(d_cache, firstIndexIterator);
continue;
}
}
if (!isNew) {
- moveCacheItemToBack(d_cache, stored);
+ moveCacheItemToBack<SequencedTag>(d_cache, stored);
}
d_cache.replace(stored, ce);
}
{
d_cachecachevalid=false;
- pruneCollection(*this, d_cache, keep);
+ pruneCollection<SequencedTag>(*this, d_cache, keep);
}
// We have something
if ((uint32_t)now.tv_sec < ni->d_ttd) {
*ne = &(*ni);
- moveCacheItemToBack(d_negcache, ni);
+ moveCacheItemToBack<SequenceTag>(d_negcache, ni);
return true;
}
- moveCacheItemToFront(d_negcache, ni);
+ moveCacheItemToFront<SequenceTag>(d_negcache, ni);
++ni;
}
return false;
if ((uint32_t)now.tv_sec < ni->d_ttd) {
// Not expired
*ne = &(*ni);
- moveCacheItemToBack(d_negcache, firstIndexIterator);
+ moveCacheItemToBack<SequenceTag>(d_negcache, firstIndexIterator);
return true;
}
// expired
- moveCacheItemToFront(d_negcache, firstIndexIterator);
+ moveCacheItemToFront<SequenceTag>(d_negcache, firstIndexIterator);
}
++ni;
}
*/
void NegCache::add(const NegCacheEntry& ne)
{
- lruReplacingInsert(d_negcache, ne);
+ lruReplacingInsert<SequenceTag>(d_negcache, ne);
}
/*!
*/
void NegCache::prune(unsigned int maxEntries)
{
- pruneCollection(*this, d_negcache, maxEntries, 200);
+ pruneCollection<SequenceTag>(*this, d_negcache, maxEntries, 200);
}
/*!
struct timeval now;
Utility::gettimeofday(&now, nullptr);
- negcache_sequence_t& sidx = d_negcache.get<1>();
+ negcache_sequence_t& sidx = d_negcache.get<SequenceTag>();
for (const NegCacheEntry& ne : sidx) {
ret++;
fprintf(fp, "%s %" PRId64 " IN %s VIA %s ; (%s)\n", ne.d_name.toString().c_str(), static_cast<int64_t>(ne.d_ttd - now.tv_sec), ne.d_qtype.getName().c_str(), ne.d_auth.toString().c_str(), vStates[ne.d_validationState]);
}
private:
+ struct CompositeKey
+ {
+ };
+ struct SequenceTag
+ {
+ };
typedef boost::multi_index_container<
NegCacheEntry,
indexed_by<
- ordered_unique<
+ ordered_unique<tag<CompositeKey>,
composite_key<
NegCacheEntry,
member<NegCacheEntry, DNSName, &NegCacheEntry::d_name>,
member<NegCacheEntry, QType, &NegCacheEntry::d_qtype>>,
composite_key_compare<
CanonDNSNameCompare, std::less<QType>>>,
- sequenced<>,
- hashed_non_unique<
+ sequenced<tag<SequenceTag>>,
+ hashed_non_unique<tag<NegCacheEntry>,
member<NegCacheEntry, DNSName, &NegCacheEntry::d_name>>>>
negcache_t;