Fix IP/FQDN cache accounting to avoid idle caches on busy servers. When maintaining the IP/FQDN cache size, use the number of entries in the cache rather than the number of allocated and not freed MEM_IPCACHE_ENTRY and MEM_FQDNCACHE_ENTRY objects. These objects are used outside the cache for DNS queries. If queries leak (or perhaps when there are just a lot of them), the memory-pool-based count overestimates the cache size, sometimes to such a degree that the cache remains nearly empty despite lots of misses. Use memory-pool-based counter to estimate cache size also violates IP/FQDN cache encapsulation boundaries because it effectively prevents others from using the same memory pool. === modified file 'src/fqdncache.cc' --- src/fqdncache.cc 2010-10-29 00:12:28 +0000 +++ src/fqdncache.cc 2011-01-21 11:07:12 +0000 @@ -152,6 +152,9 @@ /// \ingroup FQDNCacheInternal static long fqdncache_high = 200; +/// \ingroup FQDNCacheInternal +inline int fqdncacheCount() { return fqdn_table ? fqdn_table->count : 0; } + int fqdncache_entry::age() const { @@ -229,7 +232,7 @@ eventAdd("fqdncache_purgelru", fqdncache_purgelru, NULL, 10.0, 1); for (m = lru_list.tail; m; m = prev) { - if (memInUse(MEM_FQDNCACHE_ENTRY) < fqdncache_low) + if (fqdncacheCount() < fqdncache_low) break; prev = m->prev; @@ -698,9 +701,12 @@ storeAppendPrintf(sentry, "FQDN Cache Statistics:\n"); - storeAppendPrintf(sentry, "FQDNcache Entries: %d\n", + storeAppendPrintf(sentry, "FQDNcache Entries In Use: %d\n", memInUse(MEM_FQDNCACHE_ENTRY)); + storeAppendPrintf(sentry, "FQDNcache Entries Cached: %d\n", + fqdncacheCount()); + storeAppendPrintf(sentry, "FQDNcache Requests: %d\n", FqdncacheStats.requests); @@ -882,7 +888,7 @@ case FQDN_ENT: Answer = snmp_var_new_integer(Var->name, Var->name_length, - memInUse(MEM_FQDNCACHE_ENTRY), + fqdncacheCount(), SMI_GAUGE32); break; === modified file 'src/ipcache.cc' --- src/ipcache.cc 2010-12-13 11:31:14 +0000 +++ src/ipcache.cc 2011-01-21 10:09:05 +0000 @@ -161,6 +161,9 @@ extern int _dns_ttl_; #endif +/// \ingroup IPCacheInternal +inline int ipcacheCount() { return ip_table ? ip_table->count : 0; } + int ipcache_entry::age() const { @@ -235,7 +238,7 @@ eventAdd("ipcache_purgelru", ipcache_purgelru, NULL, 10.0, 1); for (m = lru_list.tail; m; m = prev) { - if (memInUse(MEM_IPCACHE_ENTRY) < ipcache_low) + if (ipcacheCount() < ipcache_low) break; prev = m->prev; @@ -855,8 +858,10 @@ dlink_node *m; assert(ip_table != NULL); storeAppendPrintf(sentry, "IP Cache Statistics:\n"); - storeAppendPrintf(sentry, "IPcache Entries: %d\n", + storeAppendPrintf(sentry, "IPcache Entries In Use: %d\n", memInUse(MEM_IPCACHE_ENTRY)); + storeAppendPrintf(sentry, "IPcache Entries Cached: %d\n", + ipcacheCount()); storeAppendPrintf(sentry, "IPcache Requests: %d\n", IpcacheStats.requests); storeAppendPrintf(sentry, "IPcache Hits: %d\n", @@ -1231,7 +1236,7 @@ case IP_ENT: Answer = snmp_var_new_integer(Var->name, Var->name_length, - memInUse(MEM_IPCACHE_ENTRY), + ipcacheCount(), SMI_GAUGE32); break;