[net] Measure DNS.CacheEvicted and DNS.CacheExpired.

On every eviction from HostCache record the time left to expiration
(DNS.CacheEvicted) or time since expiration (DNS.CacheExpired).
A distinction is made for evictions on Lookup (DNS.CacheExpiredOnGet).


Review URL: https://chromiumcodereview.appspot.com/11359053

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166781 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/base/expiring_cache.h b/net/base/expiring_cache.h
index fe2fc65..ee3fc3f 100644
--- a/net/base/expiring_cache.h
+++ b/net/base/expiring_cache.h
@@ -14,6 +14,19 @@
 
 namespace net {
 
+template <typename KeyType,
+          typename ValueType,
+          typename ExpirationType>
+class NoopEvictionHandler {
+ public:
+  void Handle(const KeyType& key,
+              const ValueType& value,
+              const ExpirationType& expiration,
+              const ExpirationType& now,
+              bool onGet) const {
+  }
+};
+
 // Cache implementation where all entries have an explicit expiration policy. As
 // new items are added, expired items will be removed first.
 // The template types have the following requirements:
@@ -54,7 +67,10 @@
 template <typename KeyType,
           typename ValueType,
           typename ExpirationType,
-          typename ExpirationCompare>
+          typename ExpirationCompare,
+          typename EvictionHandler = NoopEvictionHandler<KeyType,
+                                                         ValueType,
+                                                         ExpirationType> >
 class ExpiringCache {
  private:
   // Intentionally violate the C++ Style Guide so that EntryMap is known to be
@@ -113,7 +129,7 @@
 
     // Immediately remove expired entries.
     if (!expiration_comp_(now, it->second.second)) {
-      entries_.erase(it);
+      Evict(it, now, true);
       return NULL;
     }
 
@@ -163,7 +179,7 @@
     typename EntryMap::iterator it;
     for (it = entries_.begin(); it != entries_.end(); ) {
       if (!expiration_comp_(now, it->second.second)) {
-        entries_.erase(it++);
+        Evict(it++, now, false);
       } else {
         ++it;
       }
@@ -175,15 +191,24 @@
     // If the cache is still too full, start deleting items 'randomly'.
     for (it = entries_.begin();
          it != entries_.end() && entries_.size() >= max_entries_;) {
-      entries_.erase(it++);
+      Evict(it++, now, false);
     }
   }
 
+  void Evict(typename EntryMap::iterator it,
+             const ExpirationType& now,
+             bool on_get) {
+    eviction_handler_.Handle(it->first, it->second.first, it->second.second,
+                             now, on_get);
+    entries_.erase(it);
+  }
+
   // Bound on total size of the cache.
   size_t max_entries_;
 
   EntryMap entries_;
   ExpirationCompare expiration_comp_;
+  EvictionHandler eviction_handler_;
 
   DISALLOW_COPY_AND_ASSIGN(ExpiringCache);
 };