unsigned int RecursorPacketCache::s_refresh_ttlperc{0};
+void RecursorPacketCache::setShardSizes(size_t shardSize)
+{
+ for (auto& shard : d_maps) {
+ auto lock = shard.lock();
+ lock->d_shardSize = shardSize;
+ }
+}
+
uint64_t RecursorPacketCache::size() const
{
uint64_t count = 0;
for (const auto& map : d_maps) {
- count += map.d_entriesCount;
+ count += map.getEntriesCount();
}
return count;
}
return sum;
}
+pair<uint64_t, uint64_t> RecursorPacketCache::stats()
+{
+ uint64_t contended = 0;
+ uint64_t acquired = 0;
+ for (auto& shard : d_maps) {
+ auto content = shard.lock();
+ contended += content->d_contended_count;
+ acquired += content->d_acquired_count;
+ }
+ return {contended, acquired};
+}
+
uint64_t RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype, bool subtree)
{
uint64_t count = 0;
}
if (qtype == 0xffff || iter->d_type == qtype) {
iter = idx.erase(iter);
- map.d_entriesCount--;
+ map.decEntriesCount();
count++;
}
else {
*age = static_cast<uint32_t>(now - iter->d_creation);
// we know ttl is > 0
auto ttl = static_cast<uint32_t>(iter->d_ttd - now);
- if (s_refresh_ttlperc > 0 && !iter->d_submitted) {
- const uint32_t deadline = iter->getOrigTTL() * s_refresh_ttlperc / 100;
- const bool almostExpired = ttl <= deadline;
- if (almostExpired) {
- iter->d_submitted = true;
- pushAlmostExpiredTask(qname, qtype, iter->d_ttd, Netmask());
+ if (s_refresh_ttlperc > 0 && !iter->d_submitted && taskQTypeIsSupported(qtype)) {
+ const dnsheader_aligned header(iter->d_packet.data());
+ const auto* headerPtr = header.get();
+ if (headerPtr->rcode == RCode::NoError) {
+ const uint32_t deadline = iter->getOrigTTL() * s_refresh_ttlperc / 100;
+ const bool almostExpired = ttl <= deadline;
+ if (almostExpired) {
+ iter->d_submitted = true;
+ pushAlmostExpiredTask(qname, qtype, iter->d_ttd, Netmask());
+ }
}
}
*responsePacket = iter->d_packet;
return;
}
- struct Entry entry(qname, qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState);
+ struct Entry entry(DNSName(qname), qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState);
if (pbdata) {
entry.d_pbdata = std::move(*pbdata);
}
shard->d_map.insert(entry);
- map.d_entriesCount++;
+ map.incEntriesCount();
- if (shard->d_map.size() > d_maxSize / d_maps.size()) {
+ if (shard->d_map.size() > shard->d_shardSize) {
auto& seq_idx = shard->d_map.get<SequencedTag>();
seq_idx.erase(seq_idx.begin());
- map.d_entriesCount--;
+ map.decEntriesCount();
}
- assert(map.d_entriesCount == shard->d_map.size()); // XXX
+ assert(map.getEntriesCount() == shard->d_map.size()); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clib implementation
}
-void RecursorPacketCache::doPruneTo(size_t maxSize)
+void RecursorPacketCache::doPruneTo(time_t now, size_t maxSize)
{
size_t cacheSize = size();
- pruneMutexCollectionsVector<SequencedTag>(*this, d_maps, maxSize, cacheSize);
+ pruneMutexCollectionsVector<SequencedTag>(now, d_maps, maxSize, cacheSize);
}
uint64_t RecursorPacketCache::doDump(int file)
size_t shardNum = 0;
size_t min = std::numeric_limits<size_t>::max();
size_t max = 0;
+ uint64_t maxSize = 0;
for (auto& shard : d_maps) {
auto lock = shard.lock();
const auto& sidx = lock->d_map.get<SequencedTag>();
const auto shardSize = lock->d_map.size();
- fprintf(filePtr.get(), "; packetcache shard %zu; size %zu\n", shardNum, shardSize);
+ fprintf(filePtr.get(), "; packetcache shard %zu; size %zu/%zu\n", shardNum, shardSize, lock->d_shardSize);
min = std::min(min, shardSize);
max = std::max(max, shardSize);
+ maxSize += lock->d_shardSize;
shardNum++;
- for (const auto& entry : sidx) {
+ for (const auto& entry : sidx) {
count++;
try {
fprintf(filePtr.get(), "%s %" PRId64 " %s ; tag %d %s\n", entry.d_name.toString().c_str(), static_cast<int64_t>(entry.d_ttd - now), DNSRecordContent::NumberToType(entry.d_type).c_str(), entry.d_tag, entry.d_tcp ? "tcp" : "udp");
}
}
}
- fprintf(filePtr.get(), "; packetcache size: %" PRIu64 "/%zu shards: %zu min/max shard size: %zu/%zu\n", size(), d_maxSize, d_maps.size(), min, max);
+ fprintf(filePtr.get(), "; packetcache size: %" PRIu64 "/%" PRIu64 " shards: %zu min/max shard size: %zu/%zu\n", size(), maxSize, d_maps.size(), min, max);
return count;
}