From: Remi Gacogne Date: Tue, 2 Mar 2021 17:03:17 +0000 (+0100) Subject: dnsdist: Remove entries from all the packet cache's shards as well X-Git-Tag: dnsdist-1.6.0-alpha2~1^2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c9134a29ae582dac6c32922272c467ef05706393;p=thirdparty%2Fpdns.git dnsdist: Remove entries from all the packet cache's shards as well --- diff --git a/pdns/dnsdist-cache.cc b/pdns/dnsdist-cache.cc index 7dfde45886..d27636d7b6 100644 --- a/pdns/dnsdist-cache.cc +++ b/pdns/dnsdist-cache.cc @@ -336,34 +336,39 @@ size_t DNSDistPacketCache::purgeExpired(size_t upTo, const time_t now) } /* Remove all entries, keeping only upTo - entries in the cache */ + entries in the cache. + If the cache has more than one shard, we will try hard + to make sure that every shard has free space remaining. +*/ size_t DNSDistPacketCache::expunge(size_t upTo) { + const size_t maxPerShard = upTo / d_shardCount; + size_t removed = 0; - const uint64_t size = getSize(); - if (upTo >= size) { - return removed; - } + for (auto& shard : d_shards) { + WriteLock w(&shard.d_lock); + auto& map = shard.d_map; - size_t toRemove = size - upTo; + if (map.size() <= maxPerShard) { + continue; + } + + size_t toRemove = map.size() - maxPerShard; - for (uint32_t shardIndex = 0; shardIndex < d_shardCount; shardIndex++) { - WriteLock w(&d_shards.at(shardIndex).d_lock); - auto& map = d_shards[shardIndex].d_map; auto beginIt = map.begin(); auto endIt = beginIt; - size_t removeFromThisShard = (toRemove - removed) / (d_shardCount - shardIndex); - if (map.size() >= removeFromThisShard) { - std::advance(endIt, removeFromThisShard); + + if (map.size() >= toRemove) { + std::advance(endIt, toRemove); map.erase(beginIt, endIt); - d_shards[shardIndex].d_entriesCount -= removeFromThisShard; - removed += removeFromThisShard; + shard.d_entriesCount -= toRemove; + removed += toRemove; } else { removed += map.size(); map.clear(); - d_shards[shardIndex].d_entriesCount = 0; + shard.d_entriesCount = 0; } }