You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2015/06/15 18:28:09 UTC

[4/6] trafficserver git commit: TS-3580: Use HttpCacheKey to enter the cache

TS-3580: Use HttpCacheKey to enter the cache

Refactor the cache interface so that the HTTP cache lookup path
uses the new HttpCacheKey type, rather than fussing with URL objects
directly. This lets us use the per-request cache generation number
to access cache objects while the cache remains oblivious.


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/7ff2d618
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/7ff2d618
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/7ff2d618

Branch: refs/heads/master
Commit: 7ff2d6189d0170b422b8d1bc3df1c2145198ee68
Parents: 643208d
Author: James Peach <jp...@apache.org>
Authored: Mon May 4 09:44:18 2015 -0700
Committer: James Peach <jp...@apache.org>
Committed: Mon Jun 15 09:16:00 2015 -0700

----------------------------------------------------------------------
 iocore/cache/Cache.cc                   | 103 ++++++++++-----------------
 iocore/cache/CachePages.cc              |  18 ++---
 iocore/cache/I_Cache.h                  |  22 +++---
 iocore/cache/I_CacheDefs.h              |  18 +++++
 iocore/cache/P_CacheInternal.h          |  35 +++------
 iocore/cluster/ClusterCache.cc          |   4 +-
 iocore/cluster/P_ClusterCacheInternal.h |   4 +-
 iocore/cluster/P_ClusterInline.h        |  53 +++++++-------
 proxy/CacheControl.cc                   |   2 +-
 proxy/CacheControl.h                    |   2 +-
 proxy/ICP.cc                            |   8 ++-
 proxy/Prefetch.cc                       |   6 +-
 proxy/http/HttpCacheSM.cc               |  16 +++--
 proxy/http/HttpCacheSM.h                |   8 ++-
 proxy/http/HttpSM.cc                    |  16 ++++-
 15 files changed, 153 insertions(+), 162 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/iocore/cache/Cache.cc
----------------------------------------------------------------------
diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc
index 370c516..e062c08 100644
--- a/iocore/cache/Cache.cc
+++ b/iocore/cache/Cache.cc
@@ -268,25 +268,18 @@ cache_stats_bytes_used_cb(const char *name, RecDataT data_type, RecData *data, R
 
 #ifdef CLUSTER_CACHE
 static Action *
-open_read_internal(int opcode, Continuation *cont, MIOBuffer *buf, CacheURL *url, CacheHTTPHdr *request,
-                   CacheLookupHttpConfig *params, CacheKey *key, time_t pin_in_cache, CacheFragType frag_type, char *hostname,
-                   int host_len)
+open_read_internal(int opcode, Continuation *cont, MIOBuffer *buf, const HttpCacheKey *key, CacheHTTPHdr *request,
+                   CacheLookupHttpConfig *params, time_t pin_in_cache, CacheFragType frag_type)
 {
-  INK_MD5 url_md5;
-  if ((opcode == CACHE_OPEN_READ_LONG) || (opcode == CACHE_OPEN_READ_BUFFER_LONG)) {
-    Cache::generate_key(&url_md5, url);
-  } else {
-    url_md5 = *key;
-  }
-  ClusterMachine *m = cluster_machine_at_depth(cache_hash(url_md5));
+  ClusterMachine *m = cluster_machine_at_depth(cache_hash(key->hash));
 
   if (m) {
-    return Cluster_read(m, opcode, cont, buf, url, request, params, key, pin_in_cache, frag_type, hostname, host_len);
+    return Cluster_read(m, opcode, cont, buf, request, params, &key->hash, pin_in_cache, frag_type, key->hostname, key->hostlen);
   } else {
     if ((opcode == CACHE_OPEN_READ_LONG) || (opcode == CACHE_OPEN_READ_BUFFER_LONG)) {
-      return caches[frag_type]->open_read(cont, &url_md5, request, params, frag_type, hostname, host_len);
+      return caches[frag_type]->open_read(cont, &key->hash, request, params, frag_type, key->hostname, key->hostlen);
     } else {
-      return caches[frag_type]->open_read(cont, key, frag_type, hostname, host_len);
+      return caches[frag_type]->open_read(cont, &key->hash, frag_type, key->hostname, key->hostlen);
     }
   }
 }
@@ -1205,8 +1198,8 @@ CacheProcessor::db_check(bool afix)
 }
 
 Action *
-CacheProcessor::lookup(Continuation *cont, CacheKey *key, bool cluster_cache_local ATS_UNUSED, bool local_only ATS_UNUSED,
-                       CacheFragType frag_type, char *hostname, int host_len)
+CacheProcessor::lookup(Continuation *cont, const CacheKey *key, bool cluster_cache_local ATS_UNUSED, bool local_only ATS_UNUSED,
+                       CacheFragType frag_type, const char *hostname, int host_len)
 {
 #ifdef CLUSTER_CACHE
   // Try to send remote, if not possible, handle locally
@@ -1221,16 +1214,20 @@ CacheProcessor::lookup(Continuation *cont, CacheKey *key, bool cluster_cache_loc
 }
 
 inkcoreapi Action *
-CacheProcessor::open_read(Continuation *cont, CacheKey *key, bool cluster_cache_local ATS_UNUSED, CacheFragType frag_type,
-                          char *hostname, int host_len)
+CacheProcessor::open_read(Continuation *cont, const CacheKey *key, bool cluster_cache_local ATS_UNUSED, CacheFragType frag_type,
+                          const char *hostname, int hostlen)
 {
 #ifdef CLUSTER_CACHE
   if (cache_clustering_enabled > 0 && !cluster_cache_local) {
-    return open_read_internal(CACHE_OPEN_READ, cont, (MIOBuffer *)0, (CacheURL *)0, (CacheHTTPHdr *)0, (CacheLookupHttpConfig *)0,
-                              key, 0, frag_type, hostname, host_len);
+    HttpCacheKey hkey;
+    hkey.hash = *key;
+    hkey.hostname = hostname;
+    hkey.hostlen = hostlen;
+    return open_read_internal(CACHE_OPEN_READ, cont, (MIOBuffer *)0, &hkey, (CacheHTTPHdr *)0, (CacheLookupHttpConfig *)0, 0,
+                              frag_type);
   }
 #endif
-  return caches[frag_type]->open_read(cont, key, frag_type, hostname, host_len);
+  return caches[frag_type]->open_read(cont, key, frag_type, hostname, hostlen);
 }
 
 inkcoreapi Action *
@@ -1241,15 +1238,15 @@ CacheProcessor::open_write(Continuation *cont, CacheKey *key, bool cluster_cache
   if (cache_clustering_enabled > 0 && !cluster_cache_local) {
     ClusterMachine *m = cluster_machine_at_depth(cache_hash(*key));
     if (m)
-      return Cluster_write(cont, expected_size, (MIOBuffer *)0, m, key, frag_type, options, pin_in_cache, CACHE_OPEN_WRITE, key,
-                           (CacheURL *)0, (CacheHTTPHdr *)0, (CacheHTTPInfo *)0, hostname, host_len);
+      return Cluster_write(cont, expected_size, (MIOBuffer *)0, m, key, frag_type, options, pin_in_cache, CACHE_OPEN_WRITE,
+                           (CacheHTTPHdr *)0, (CacheHTTPInfo *)0, hostname, host_len);
   }
 #endif
   return caches[frag_type]->open_write(cont, key, frag_type, options, pin_in_cache, hostname, host_len);
 }
 
 Action *
-CacheProcessor::remove(Continuation *cont, CacheKey *key, bool cluster_cache_local ATS_UNUSED, CacheFragType frag_type,
+CacheProcessor::remove(Continuation *cont, const CacheKey *key, bool cluster_cache_local ATS_UNUSED, CacheFragType frag_type,
                        const char *hostname, int host_len)
 {
   Debug("cache_remove", "[CacheProcessor::remove] Issuing cache delete for %u", cache_hash(*key));
@@ -1275,15 +1272,10 @@ scan(Continuation *cont, char *hostname = 0, int host_len = 0, int KB_per_second
 
 #ifdef HTTP_CACHE
 Action *
-CacheProcessor::lookup(Continuation *cont, CacheURL *url, bool cluster_cache_local, bool local_only, CacheFragType frag_type)
+CacheProcessor::lookup(Continuation *cont, const HttpCacheKey *key, bool cluster_cache_local, bool local_only,
+                       CacheFragType frag_type)
 {
-  (void)local_only;
-  INK_MD5 md5;
-  url->hash_get(&md5);
-  int host_len = 0;
-  const char *hostname = url->host_get(&host_len);
-
-  return lookup(cont, &md5, cluster_cache_local, local_only, frag_type, (char *)hostname, host_len);
+  return lookup(cont, &key->hash, cluster_cache_local, local_only, frag_type, key->hostname, key->hostlen);
 }
 
 #endif
@@ -3016,17 +3008,6 @@ Cache::lookup(Continuation *cont, const CacheKey *key, CacheFragType type, char
     return ACTION_RESULT_DONE;
 }
 
-Action *
-Cache::lookup(Continuation *cont, CacheURL *url, CacheFragType type)
-{
-  CryptoHash id;
-
-  url->hash_get(&id);
-  int len = 0;
-  char const *hostname = url->host_get(&len);
-  return lookup(cont, &id, type, hostname, len);
-}
-
 int
 CacheVC::removeEvent(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
 {
@@ -3797,65 +3778,53 @@ ink_cache_init(ModuleVersion v)
 
 //----------------------------------------------------------------------------
 Action *
-CacheProcessor::open_read(Continuation *cont, CacheURL *url, bool cluster_cache_local, CacheHTTPHdr *request,
+CacheProcessor::open_read(Continuation *cont, const HttpCacheKey *key, bool cluster_cache_local, CacheHTTPHdr *request,
                           CacheLookupHttpConfig *params, time_t pin_in_cache, CacheFragType type)
 {
 #ifdef CLUSTER_CACHE
   if (cache_clustering_enabled > 0 && !cluster_cache_local) {
-    return open_read_internal(CACHE_OPEN_READ_LONG, cont, (MIOBuffer *)0, url, request, params, (CacheKey *)0, pin_in_cache, type,
-                              (char *)0, 0);
+    return open_read_internal(CACHE_OPEN_READ_LONG, cont, (MIOBuffer *)0, key, request, params, pin_in_cache, type);
   }
 #endif
-  return caches[type]->open_read(cont, url, request, params, type);
+
+  return caches[type]->open_read(cont, &key->hash, request, params, type, key->hostname, key->hostlen);
 }
 
 
 //----------------------------------------------------------------------------
 Action *
-CacheProcessor::open_write(Continuation *cont, int expected_size, CacheURL *url, bool cluster_cache_local, CacheHTTPHdr *request,
-                           CacheHTTPInfo *old_info, time_t pin_in_cache, CacheFragType type)
+CacheProcessor::open_write(Continuation *cont, int expected_size, const HttpCacheKey *key, bool cluster_cache_local,
+                           CacheHTTPHdr *request, CacheHTTPInfo *old_info, time_t pin_in_cache, CacheFragType type)
 {
 #ifdef CLUSTER_CACHE
   if (cache_clustering_enabled > 0 && !cluster_cache_local) {
-    INK_MD5 url_md5;
-    Cache::generate_key(&url_md5, url);
-    ClusterMachine *m = cluster_machine_at_depth(cache_hash(url_md5));
+    ClusterMachine *m = cluster_machine_at_depth(cache_hash(key->hash));
 
     if (m) {
       // Do remote open_write()
-      INK_MD5 url_only_md5;
-      Cache::generate_key(&url_only_md5, url);
-      return Cluster_write(cont, expected_size, (MIOBuffer *)0, m, &url_only_md5, type, false, pin_in_cache, CACHE_OPEN_WRITE_LONG,
-                           (CacheKey *)0, url, request, old_info, (char *)0, 0);
+      return Cluster_write(cont, expected_size, (MIOBuffer *)0, m, &key->hash, type, false, pin_in_cache, CACHE_OPEN_WRITE_LONG,
+                           request, old_info, key->hostname, key->hostlen);
     }
   }
 #endif
-  return caches[type]->open_write(cont, url, request, old_info, pin_in_cache, type);
+  return caches[type]->open_write(cont, &key->hash, old_info, pin_in_cache, NULL /* key1 */, type, key->hostname, key->hostlen);
 }
 
 //----------------------------------------------------------------------------
 // Note: this should not be called from from the cluster processor, or bad
 // recursion could occur. This is merely a convenience wrapper.
 Action *
-CacheProcessor::remove(Continuation *cont, CacheURL *url, bool cluster_cache_local, CacheFragType frag_type)
+CacheProcessor::remove(Continuation *cont, const HttpCacheKey *key, bool cluster_cache_local, CacheFragType frag_type)
 {
-  CryptoHash id;
-  int len = 0;
-  const char *hostname;
-
-  url->hash_get(&id);
-  hostname = url->host_get(&len);
-
-  Debug("cache_remove", "[CacheProcessor::remove] Issuing cache delete for %s", url->string_get_ref());
 #ifdef CLUSTER_CACHE
   if (cache_clustering_enabled > 0 && !cluster_cache_local) {
     // Remove from cluster
-    return remove(cont, &id, cluster_cache_local, frag_type, hostname, len);
+    return remove(cont, &key->hash, cluster_cache_local, frag_type, key->hostname, key->hostlen);
   }
 #endif
 
   // Remove from local cache only.
-  return caches[frag_type]->remove(cont, &id, frag_type, hostname, len);
+  return caches[frag_type]->remove(cont, &key->hash, frag_type, key->hostname, key->hostlen);
 }
 
 CacheDisk *

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/iocore/cache/CachePages.cc
----------------------------------------------------------------------
diff --git a/iocore/cache/CachePages.cc b/iocore/cache/CachePages.cc
index 13f2b2a..721bffc 100644
--- a/iocore/cache/CachePages.cc
+++ b/iocore/cache/CachePages.cc
@@ -438,13 +438,13 @@ ShowCache::lookup_url(int event, Event *e)
   const char *s;
   s = show_cache_urlstrs[0];
   url.parse(&s, s + strlen(s));
-  INK_MD5 md5;
-  int len;
-  url.hash_get(&md5);
-  const char *hostname = url.host_get(&len);
+
+  HttpCacheKey key;
+  Cache::generate_key(&key, &url); // XXX choose a cache generation number ...
+
   SET_HANDLER(&ShowCache::handleCacheEvent);
   Action *lookup_result =
-    cacheProcessor.open_read(this, &md5, getClusterCacheLocal(&url, (char *)hostname), CACHE_FRAG_TYPE_HTTP, (char *)hostname, len);
+    cacheProcessor.open_read(this, &key.hash, getClusterCacheLocal(&url), CACHE_FRAG_TYPE_HTTP, key.hostname, key.hostlen);
   if (!lookup_result)
     lookup_result = ACTION_IO_ERROR;
   if (lookup_result == ACTION_RESULT_DONE)
@@ -482,9 +482,11 @@ ShowCache::delete_url(int event, Event *e)
   // increment the index so that the next time
   // delete_url is called you delete the next url
   urlstrs_index++;
-  int len;
-  const char *hostname = url.host_get(&len);
-  cacheProcessor.remove(this, &url, getClusterCacheLocal(&url, (char *)hostname), CACHE_FRAG_TYPE_HTTP);
+
+  HttpCacheKey key;
+  Cache::generate_key(&key, &url); // XXX choose a cache generation number ...
+
+  cacheProcessor.remove(this, &key, getClusterCacheLocal(&url), CACHE_FRAG_TYPE_HTTP);
   return EVENT_DONE;
 }
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/iocore/cache/I_Cache.h
----------------------------------------------------------------------
diff --git a/iocore/cache/I_Cache.h b/iocore/cache/I_Cache.h
index 50b3185..77aafe9 100644
--- a/iocore/cache/I_Cache.h
+++ b/iocore/cache/I_Cache.h
@@ -76,25 +76,27 @@ struct CacheProcessor : public Processor {
   int dir_check(bool fix);
   int db_check(bool fix);
 
-  inkcoreapi Action *lookup(Continuation *cont, CacheKey *key, bool cluster_cache_local, bool local_only = false,
-                            CacheFragType frag_type = CACHE_FRAG_TYPE_NONE, char *hostname = 0, int host_len = 0);
-  inkcoreapi Action *open_read(Continuation *cont, CacheKey *key, bool cluster_cache_local,
-                               CacheFragType frag_type = CACHE_FRAG_TYPE_NONE, char *hostname = 0, int host_len = 0);
+  inkcoreapi Action *lookup(Continuation *cont, const CacheKey *key, bool cluster_cache_local, bool local_only = false,
+                            CacheFragType frag_type = CACHE_FRAG_TYPE_NONE, const char *hostname = 0, int host_len = 0);
+  inkcoreapi Action *open_read(Continuation *cont, const CacheKey *key, bool cluster_cache_local,
+                               CacheFragType frag_type = CACHE_FRAG_TYPE_NONE, const char *hostname = 0, int host_len = 0);
   inkcoreapi Action *open_write(Continuation *cont, CacheKey *key, bool cluster_cache_local,
                                 CacheFragType frag_type = CACHE_FRAG_TYPE_NONE, int expected_size = CACHE_EXPECTED_SIZE,
                                 int options = 0, time_t pin_in_cache = (time_t)0, char *hostname = 0, int host_len = 0);
-  inkcoreapi Action *remove(Continuation *cont, CacheKey *key, bool cluster_cache_local,
+  inkcoreapi Action *remove(Continuation *cont, const CacheKey *key, bool cluster_cache_local,
                             CacheFragType frag_type = CACHE_FRAG_TYPE_NONE, const char *hostname = 0, int host_len = 0);
   Action *scan(Continuation *cont, char *hostname = 0, int host_len = 0, int KB_per_second = SCAN_KB_PER_SECOND);
 #ifdef HTTP_CACHE
-  Action *lookup(Continuation *cont, CacheURL *url, bool cluster_cache_local, bool local_only = false,
+  Action *lookup(Continuation *cont, const HttpCacheKey *key, bool cluster_cache_local, bool local_only = false,
                  CacheFragType frag_type = CACHE_FRAG_TYPE_HTTP);
-  inkcoreapi Action *open_read(Continuation *cont, CacheURL *url, bool cluster_cache_local, CacheHTTPHdr *request,
+  inkcoreapi Action *open_read(Continuation *cont, const HttpCacheKey *key, bool cluster_cache_local, CacheHTTPHdr *request,
                                CacheLookupHttpConfig *params, time_t pin_in_cache = (time_t)0,
                                CacheFragType frag_type = CACHE_FRAG_TYPE_HTTP);
-  Action *open_write(Continuation *cont, int expected_size, CacheURL *url, bool cluster_cache_local, CacheHTTPHdr *request,
-                     CacheHTTPInfo *old_info, time_t pin_in_cache = (time_t)0, CacheFragType frag_type = CACHE_FRAG_TYPE_HTTP);
-  Action *remove(Continuation *cont, CacheURL *url, bool cluster_cache_local, CacheFragType frag_type = CACHE_FRAG_TYPE_HTTP);
+  Action *open_write(Continuation *cont, int expected_size, const HttpCacheKey *key, bool cluster_cache_local,
+                     CacheHTTPHdr *request, CacheHTTPInfo *old_info, time_t pin_in_cache = (time_t)0,
+                     CacheFragType frag_type = CACHE_FRAG_TYPE_HTTP);
+  Action *remove(Continuation *cont, const HttpCacheKey *key, bool cluster_cache_local,
+                 CacheFragType frag_type = CACHE_FRAG_TYPE_HTTP);
 #endif
   Action *link(Continuation *cont, CacheKey *from, CacheKey *to, bool cluster_cache_local,
                CacheFragType frag_type = CACHE_FRAG_TYPE_HTTP, char *hostname = 0, int host_len = 0);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/iocore/cache/I_CacheDefs.h
----------------------------------------------------------------------
diff --git a/iocore/cache/I_CacheDefs.h b/iocore/cache/I_CacheDefs.h
index 93b0cac..941ff0e 100644
--- a/iocore/cache/I_CacheDefs.h
+++ b/iocore/cache/I_CacheDefs.h
@@ -117,6 +117,24 @@ enum CacheFragType {
 };
 
 typedef CryptoHash CacheKey;
+
+struct HttpCacheKey {
+  uint64_t
+  slice64(int i) const
+  {
+    return hash.slice64(i);
+  }
+  uint32_t
+  slice32(int i) const
+  {
+    return hash.slice32(i);
+  }
+
+  int hostlen;
+  const char *hostname;
+  CacheKey hash;
+};
+
 #define CACHE_ALLOW_MULTIPLE_WRITES 1
 #define CACHE_EXPECTED_SIZE 32768
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/iocore/cache/P_CacheInternal.h
----------------------------------------------------------------------
diff --git a/iocore/cache/P_CacheInternal.h b/iocore/cache/P_CacheInternal.h
index 96d08a3..7007bc2 100644
--- a/iocore/cache/P_CacheInternal.h
+++ b/iocore/cache/P_CacheInternal.h
@@ -1033,16 +1033,13 @@ struct Cache {
   Action *scan(Continuation *cont, const char *hostname = 0, int host_len = 0, int KB_per_second = 2500);
 
 #ifdef HTTP_CACHE
-  Action *lookup(Continuation *cont, CacheURL *url, CacheFragType type);
-  inkcoreapi Action *open_read(Continuation *cont, const CacheKey *key, CacheHTTPHdr *request, CacheLookupHttpConfig *params,
-                               CacheFragType type, const char *hostname, int host_len);
-  Action *open_read(Continuation *cont, CacheURL *url, CacheHTTPHdr *request, CacheLookupHttpConfig *params, CacheFragType type);
+  Action *open_read(Continuation *cont, const CacheKey *key, CacheHTTPHdr *request, CacheLookupHttpConfig *params,
+                    CacheFragType type, const char *hostname, int host_len);
   Action *open_write(Continuation *cont, const CacheKey *key, CacheHTTPInfo *old_info, time_t pin_in_cache = (time_t)0,
                      const CacheKey *key1 = NULL, CacheFragType type = CACHE_FRAG_TYPE_HTTP, const char *hostname = 0,
                      int host_len = 0);
-  Action *open_write(Continuation *cont, CacheURL *url, CacheHTTPHdr *request, CacheHTTPInfo *old_info,
-                     time_t pin_in_cache = (time_t)0, CacheFragType type = CACHE_FRAG_TYPE_HTTP);
   static void generate_key(INK_MD5 *md5, CacheURL *url);
+  static void generate_key(HttpCacheKey *md5, CacheURL *url, cache_generation_t generation = -1);
 #endif
 
   Action *link(Continuation *cont, const CacheKey *from, const CacheKey *to, CacheFragType type, const char *hostname,
@@ -1067,15 +1064,6 @@ extern Cache *theStreamCache;
 inkcoreapi extern Cache *caches[NUM_CACHE_FRAG_TYPES];
 
 #ifdef HTTP_CACHE
-TS_INLINE Action *
-Cache::open_read(Continuation *cont, CacheURL *url, CacheHTTPHdr *request, CacheLookupHttpConfig *params, CacheFragType type)
-{
-  INK_MD5 md5;
-  int len;
-  url->hash_get(&md5);
-  const char *hostname = url->host_get(&len);
-  return open_read(cont, &md5, request, params, type, hostname, len);
-}
 
 TS_INLINE void
 Cache::generate_key(INK_MD5 *md5, CacheURL *url)
@@ -1083,22 +1071,17 @@ Cache::generate_key(INK_MD5 *md5, CacheURL *url)
   url->hash_get(md5);
 }
 
-TS_INLINE Action *
-Cache::open_write(Continuation *cont, CacheURL *url, CacheHTTPHdr *request, CacheHTTPInfo *old_info, time_t pin_in_cache,
-                  CacheFragType type)
+TS_INLINE void
+Cache::generate_key(HttpCacheKey *key, CacheURL *url, cache_generation_t generation)
 {
-  (void)request;
-  INK_MD5 url_md5;
-  url->hash_get(&url_md5);
-  int len;
-  const char *hostname = url->host_get(&len);
-
-  return open_write(cont, &url_md5, old_info, pin_in_cache, NULL, type, hostname, len);
+  key->hostname = url->host_get(&key->hostlen);
+  url->hash_get(&key->hash, generation);
 }
+
 #endif
 
 TS_INLINE unsigned int
-cache_hash(INK_MD5 &md5)
+cache_hash(const INK_MD5 &md5)
 {
   uint64_t f = md5.fold();
   unsigned int mhash = (unsigned int)(f >> 32);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/iocore/cluster/ClusterCache.cc
----------------------------------------------------------------------
diff --git a/iocore/cluster/ClusterCache.cc b/iocore/cluster/ClusterCache.cc
index 6c8d424..c4480e1 100644
--- a/iocore/cluster/ClusterCache.cc
+++ b/iocore/cluster/ClusterCache.cc
@@ -2387,8 +2387,8 @@ CacheContinuation::lookupEvent(int /* event ATS_UNUSED */, void * /* d ATS_UNUSE
 //            Zero (Action *) if no probe
 //////////////////////////////////////////////////////////////////////////
 Action *
-CacheContinuation::do_remote_lookup(Continuation *cont, CacheKey *key, CacheContinuation *c, CacheFragType ft, char *hostname,
-                                    int hostname_len)
+CacheContinuation::do_remote_lookup(Continuation *cont, const CacheKey *key, CacheContinuation *c, CacheFragType ft,
+                                    const char *hostname, int hostname_len)
 {
   int probe_depth = 0;
   ClusterMachine *past_probes[CONFIGURATION_HISTORY_PROBE_DEPTH] = {0};

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/iocore/cluster/P_ClusterCacheInternal.h
----------------------------------------------------------------------
diff --git a/iocore/cluster/P_ClusterCacheInternal.h b/iocore/cluster/P_ClusterCacheInternal.h
index eb7d5cd..bba6f17 100644
--- a/iocore/cluster/P_ClusterCacheInternal.h
+++ b/iocore/cluster/P_ClusterCacheInternal.h
@@ -309,7 +309,7 @@ struct CacheContinuation : public Continuation {
   static CacheContinuation *cacheContAllocator_alloc();
   static void cacheContAllocator_free(CacheContinuation *);
   inkcoreapi static Action *callback_failure(Action *, int, int, CacheContinuation *this_cc = 0);
-  static Action *do_remote_lookup(Continuation *, CacheKey *, CacheContinuation *, CacheFragType, char *, int);
+  static Action *do_remote_lookup(Continuation *, const CacheKey *, CacheContinuation *, CacheFragType, const char *, int);
   inkcoreapi static Action *do_op(Continuation *, ClusterMachine *, void *, int, char *, int, int nbytes = -1, MIOBuffer *b = 0);
   static int setup_local_vc(char *data, int data_len, CacheContinuation *cc, ClusterMachine *mp, Action **);
   static void disposeOfDataBuffer(void *buf);
@@ -331,7 +331,7 @@ struct CacheContinuation : public Continuation {
 #define CFL_MAX (1 << 15)
 
 struct CacheOpArgs_General {
-  INK_MD5 *url_md5;
+  const INK_MD5 *url_md5;
   time_t pin_in_cache; // open_write() specific arg
   CacheFragType frag_type;
   uint16_t cfl_flags;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/iocore/cluster/P_ClusterInline.h
----------------------------------------------------------------------
diff --git a/iocore/cluster/P_ClusterInline.h b/iocore/cluster/P_ClusterInline.h
index ed97c36..18aa72d 100644
--- a/iocore/cluster/P_ClusterInline.h
+++ b/iocore/cluster/P_ClusterInline.h
@@ -33,7 +33,7 @@
 #include "P_ClusterHandler.h"
 
 inline Action *
-Cluster_lookup(Continuation *cont, CacheKey *key, CacheFragType frag_type, char *hostname, int host_len)
+Cluster_lookup(Continuation *cont, const CacheKey *key, CacheFragType frag_type, const char *hostname, int host_len)
 {
   // Try to send remote, if not possible, handle locally
   Action *retAct;
@@ -59,9 +59,9 @@ Cluster_lookup(Continuation *cont, CacheKey *key, CacheFragType frag_type, char
 }
 
 inline Action *
-Cluster_read(ClusterMachine *owner_machine, int opcode, Continuation *cont, MIOBuffer *buf, CacheURL *url, CacheHTTPHdr *request,
-             CacheLookupHttpConfig *params, CacheKey *key, time_t pin_in_cache, CacheFragType frag_type, char *hostname,
-             int host_len)
+Cluster_read(ClusterMachine *owner_machine, int opcode, Continuation *cont, MIOBuffer *buf, CacheHTTPHdr *request,
+             CacheLookupHttpConfig *params, const CacheKey *key, time_t pin_in_cache, CacheFragType frag_type, const char *hostname,
+             int hostlen)
 {
   (void)params;
   if (clusterProcessor.disable_remote_cluster_ops(owner_machine)) {
@@ -78,19 +78,15 @@ Cluster_read(ClusterMachine *owner_machine, int opcode, Continuation *cont, MIOB
 
   if (vers == CacheOpMsg_long::CACHE_OP_LONG_MESSAGE_VERSION) {
     if ((opcode == CACHE_OPEN_READ_LONG) || (opcode == CACHE_OPEN_READ_BUFFER_LONG)) {
+      ink_assert(hostname);
+      ink_assert(hostlen);
+
       // Determine length of data to Marshal
       flen = op_to_sizeof_fixedlen_msg(opcode);
 
-      const char *url_hostname;
-      int url_hlen;
-      INK_MD5 url_only_md5;
-
-      Cache::generate_key(&url_only_md5, url);
-      url_hostname = url->host_get(&url_hlen);
-
       len += request->m_heap->marshal_length();
       len += params->marshal_length();
-      len += url_hlen;
+      len += hostlen;
 
       if ((flen + len) > DEFAULT_MAX_BUFFER_SIZE) // Bound marshalled data
         goto err_exit;
@@ -110,27 +106,27 @@ Cluster_read(ClusterMachine *owner_machine, int opcode, Continuation *cont, MIOB
       if ((res = params->marshal(data, cur_len)) < 0)
         goto err_exit;
       data += res;
-      memcpy(data, url_hostname, url_hlen);
+      memcpy(data, hostname, hostlen);
 
       CacheOpArgs_General readArgs;
-      readArgs.url_md5 = &url_only_md5;
+      readArgs.url_md5 = key;
       readArgs.pin_in_cache = pin_in_cache;
       readArgs.frag_type = frag_type;
       return CacheContinuation::do_op(cont, owner_machine, (void *)&readArgs, opcode, (char *)msg, (flen + len), -1, buf);
     } else {
       // Build message if we have host data.
 
-      if (host_len) {
+      if (hostlen) {
         // Determine length of data to Marshal
         flen = op_to_sizeof_fixedlen_msg(opcode);
-        len = host_len;
+        len = hostlen;
 
         if ((flen + len) > DEFAULT_MAX_BUFFER_SIZE) // Bound marshalled data
           goto err_exit;
 
         msg = (char *)ALLOCA_DOUBLE(flen + len);
         data = msg + flen;
-        memcpy(data, hostname, host_len);
+        memcpy(data, hostname, hostlen);
 
       } else {
         msg = 0;
@@ -156,11 +152,10 @@ err_exit:
 }
 
 inline Action *
-Cluster_write(Continuation *cont, int expected_size, MIOBuffer *buf, ClusterMachine *m, INK_MD5 *url_md5, CacheFragType ft,
-              int options, time_t pin_in_cache, int opcode, CacheKey *key, CacheURL *url, CacheHTTPHdr *request,
-              CacheHTTPInfo *old_info, char *hostname, int host_len)
+Cluster_write(Continuation *cont, int expected_size, MIOBuffer *buf, ClusterMachine *m, const CacheKey *url_md5, CacheFragType ft,
+              int options, time_t pin_in_cache, int opcode, CacheHTTPHdr *request, CacheHTTPInfo *old_info, const char *hostname,
+              int hostlen)
 {
-  (void)key;
   (void)request;
   if (clusterProcessor.disable_remote_cluster_ops(m)) {
     Action a;
@@ -177,10 +172,10 @@ Cluster_write(Continuation *cont, int expected_size, MIOBuffer *buf, ClusterMach
   switch (opcode) {
   case CACHE_OPEN_WRITE: {
     // Build message if we have host data
-    if (host_len) {
+    if (hostlen) {
       // Determine length of data to Marshal
       flen = op_to_sizeof_fixedlen_msg(CACHE_OPEN_WRITE);
-      len = host_len;
+      len = hostlen;
 
       if ((flen + len) > DEFAULT_MAX_BUFFER_SIZE) // Bound marshalled data
         goto err_exit;
@@ -188,13 +183,13 @@ Cluster_write(Continuation *cont, int expected_size, MIOBuffer *buf, ClusterMach
       msg = (char *)ALLOCA_DOUBLE(flen + len);
       data = msg + flen;
 
-      memcpy(data, hostname, host_len);
+      memcpy(data, hostname, hostlen);
     }
     break;
   }
   case CACHE_OPEN_WRITE_LONG: {
-    int url_hlen;
-    const char *url_hostname = url->host_get(&url_hlen);
+    ink_assert(hostname);
+    ink_assert(hostlen);
 
     // Determine length of data to Marshal
     flen = op_to_sizeof_fixedlen_msg(CACHE_OPEN_WRITE_LONG);
@@ -207,7 +202,7 @@ Cluster_write(Continuation *cont, int expected_size, MIOBuffer *buf, ClusterMach
     if (old_info) {
       len += old_info->marshal_length();
     }
-    len += url_hlen;
+    len += hostlen;
 
     if ((flen + len) > DEFAULT_MAX_BUFFER_SIZE) // Bound marshalled data
       goto err_exit;
@@ -224,7 +219,7 @@ Cluster_write(Continuation *cont, int expected_size, MIOBuffer *buf, ClusterMach
       }
       data += res;
     }
-    memcpy(data, url_hostname, url_hlen);
+    memcpy(data, hostname, hostlen);
     break;
   }
   default: {
@@ -343,7 +338,7 @@ err_exit:
 }
 
 inline Action *
-Cluster_remove(ClusterMachine *m, Continuation *cont, CacheKey *key, CacheFragType frag_type, const char *hostname, int host_len)
+Cluster_remove(ClusterMachine *m, Continuation *cont, const CacheKey *key, CacheFragType frag_type, const char *hostname, int host_len)
 {
   if (clusterProcessor.disable_remote_cluster_ops(m)) {
     Action a;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/proxy/CacheControl.cc
----------------------------------------------------------------------
diff --git a/proxy/CacheControl.cc b/proxy/CacheControl.cc
index 44a7fbc..77af5fe 100644
--- a/proxy/CacheControl.cc
+++ b/proxy/CacheControl.cc
@@ -177,7 +177,7 @@ getCacheControl(CacheControlResult *result, HttpRequestData *rdata, OverridableH
 }
 
 bool
-getClusterCacheLocal(URL *url, char * /* hostname ATS_UNUSED */)
+getClusterCacheLocal(URL *url)
 {
   HttpRequestData rdata;
   CacheControlResult result;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/proxy/CacheControl.h
----------------------------------------------------------------------
diff --git a/proxy/CacheControl.h b/proxy/CacheControl.h
index 2668443..de3820c 100644
--- a/proxy/CacheControl.h
+++ b/proxy/CacheControl.h
@@ -132,7 +132,7 @@ struct OverridableHttpConfigParams;
 
 inkcoreapi void getCacheControl(CacheControlResult *result, HttpRequestData *rdata, OverridableHttpConfigParams *h_txn_conf,
                                 char *tag = NULL);
-inkcoreapi bool getClusterCacheLocal(URL *url, char *hostname);
+inkcoreapi bool getClusterCacheLocal(URL *url);
 inkcoreapi bool host_rule_in_CacheControlTable();
 inkcoreapi bool ip_rule_in_CacheControlTable();
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/proxy/ICP.cc
----------------------------------------------------------------------
diff --git a/proxy/ICP.cc b/proxy/ICP.cc
index af3d697..b3affe4 100644
--- a/proxy/ICP.cc
+++ b/proxy/ICP.cc
@@ -453,16 +453,20 @@ ICPPeerReadCont::ICPPeerQueryCont(int /* event ATS_UNUSED */, Event * /* e ATS_U
 
   SET_HANDLER((ICPPeerReadContHandler)&ICPPeerReadCont::ICPPeerQueryEvent);
   if (_state->_rICPmsg->un.query.URL && *_state->_rICPmsg->un.query.URL) {
+    HttpCacheKey key;
+
+    Cache::generate_key(&key, &_state->_cachelookupURL); // XXX choose a cache generation number ...
     _state->_queryResult = ~CACHE_EVENT_LOOKUP_FAILED;
     _start_time = ink_get_hrtime();
+
     if (pluginFreshnessCalcFunc && _ICPpr->GetConfig()->globalConfig()->ICPStaleLookup()) {
       //////////////////////////////////////////////////////////////
       // Note: _cache_lookup_local is ignored in this case, since
       //       cache clustering is not used with stale lookup.
       //////////////////////////////////////////////////////////////
-      a = cacheProcessor.open_read(this, &_state->_cachelookupURL, false, &gclient_request, &global_cache_lookup_config, (time_t)0);
+      a = cacheProcessor.open_read(this, &key, false, &gclient_request, &global_cache_lookup_config, (time_t)0);
     } else {
-      a = cacheProcessor.lookup(this, &_state->_cachelookupURL, false, _state->_cache_lookup_local);
+      a = cacheProcessor.lookup(this, &key, false, _state->_cache_lookup_local);
     }
     if (!a) {
       a = ACTION_IO_ERROR;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/proxy/Prefetch.cc
----------------------------------------------------------------------
diff --git a/proxy/Prefetch.cc b/proxy/Prefetch.cc
index 18393ee..521aa83 100644
--- a/proxy/Prefetch.cc
+++ b/proxy/Prefetch.cc
@@ -1446,12 +1446,16 @@ PrefetchBlaster::handleEvent(int event, void *data)
 
   switch (event) {
   case EVENT_IMMEDIATE: {
+    HttpCacheKey key;
+
     // Here, we need to decide if we need to prefetch based on whether it
     // is in the cache or not.
 
     // if (cache_lookup_necessary) do:
     initCacheLookupConfig();
-    cacheProcessor.open_read(this, request->url_get(), false, request, &cache_lookup_config, 0);
+
+    Cache::generate_key(&key, request->url_get()); // XXX choose a cache generation number ...
+    cacheProcessor.open_read(this, &key, false, request, &cache_lookup_config, 0);
 
     break;
   }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/proxy/http/HttpCacheSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpCacheSM.cc b/proxy/http/HttpCacheSM.cc
index ff02e3a..c259b38 100644
--- a/proxy/http/HttpCacheSM.cc
+++ b/proxy/http/HttpCacheSM.cc
@@ -145,7 +145,7 @@ HttpCacheSM::state_cache_open_read(int event, void *data)
                         "retrying cache open read...",
           master_sm->sm_id, open_read_tries);
 
-    do_cache_open_read();
+    do_cache_open_read(cache_key);
     break;
 
   default:
@@ -200,7 +200,7 @@ HttpCacheSM::do_schedule_in()
 }
 
 Action *
-HttpCacheSM::do_cache_open_read()
+HttpCacheSM::do_cache_open_read(const HttpCacheKey &key)
 {
   open_read_tries++;
   ink_assert(pending_action == NULL);
@@ -211,7 +211,7 @@ HttpCacheSM::do_cache_open_read()
   }
   // Initialising read-while-write-inprogress flag
   this->readwhilewrite_inprogress = false;
-  Action *action_handle = cacheProcessor.open_read(this, this->lookup_url, master_sm->t_state.cache_control.cluster_cache_local,
+  Action *action_handle = cacheProcessor.open_read(this, &key, master_sm->t_state.cache_control.cluster_cache_local,
                                                    this->read_request_hdr, this->read_config, this->read_pin_in_cache);
 
   if (action_handle != ACTION_RESULT_DONE) {
@@ -230,10 +230,11 @@ HttpCacheSM::do_cache_open_read()
 }
 
 Action *
-HttpCacheSM::open_read(URL *url, HTTPHdr *hdr, CacheLookupHttpConfig *params, time_t pin_in_cache)
+HttpCacheSM::open_read(const HttpCacheKey *key, URL *url, HTTPHdr *hdr, CacheLookupHttpConfig *params, time_t pin_in_cache)
 {
   Action *act_return;
 
+  cache_key = *key;
   lookup_url = url;
   read_request_hdr = hdr;
   read_config = params;
@@ -244,7 +245,7 @@ HttpCacheSM::open_read(URL *url, HTTPHdr *hdr, CacheLookupHttpConfig *params, ti
   lookup_max_recursive++;
   current_lookup_level++;
   open_read_cb = false;
-  act_return = do_cache_open_read();
+  act_return = do_cache_open_read(cache_key);
   // the following logic is based on the assumption that the secnod
   // lookup won't happen if the HttpSM hasn't been called back for the
   // first lookup
@@ -267,7 +268,8 @@ HttpCacheSM::open_read(URL *url, HTTPHdr *hdr, CacheLookupHttpConfig *params, ti
 }
 
 Action *
-HttpCacheSM::open_write(URL *url, HTTPHdr *request, CacheHTTPInfo *old_info, time_t pin_in_cache, bool retry, bool allow_multiple)
+HttpCacheSM::open_write(const HttpCacheKey *key, URL *url, HTTPHdr *request, CacheHTTPInfo *old_info, time_t pin_in_cache,
+                        bool retry, bool allow_multiple)
 {
   SET_HANDLER(&HttpCacheSM::state_cache_open_write);
   ink_assert(pending_action == NULL);
@@ -297,7 +299,7 @@ HttpCacheSM::open_write(URL *url, HTTPHdr *request, CacheHTTPInfo *old_info, tim
   }
 
   Action *action_handle =
-    cacheProcessor.open_write(this, 0, url, master_sm->t_state.cache_control.cluster_cache_local, request,
+    cacheProcessor.open_write(this, 0, key, master_sm->t_state.cache_control.cluster_cache_local, request,
                               // INKqa11166
                               allow_multiple ? (CacheHTTPInfo *)CACHE_ALLOW_MULTIPLE_WRITES : old_info, pin_in_cache);
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/proxy/http/HttpCacheSM.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpCacheSM.h b/proxy/http/HttpCacheSM.h
index d0ed2ad..3c14da3 100644
--- a/proxy/http/HttpCacheSM.h
+++ b/proxy/http/HttpCacheSM.h
@@ -68,9 +68,10 @@ public:
     captive_action.init(this);
   }
 
-  Action *open_read(URL *url, HTTPHdr *hdr, CacheLookupHttpConfig *params, time_t pin_in_cache);
+  Action *open_read(const HttpCacheKey *key, URL *url, HTTPHdr *hdr, CacheLookupHttpConfig *params, time_t pin_in_cache);
 
-  Action *open_write(URL *url, HTTPHdr *request, CacheHTTPInfo *old_info, time_t pin_in_cache, bool retry, bool allow_multiple);
+  Action *open_write(const HttpCacheKey *key, URL *url, HTTPHdr *request, CacheHTTPInfo *old_info, time_t pin_in_cache, bool retry,
+                     bool allow_multiple);
 
   CacheVConnection *cache_read_vc;
   CacheVConnection *cache_write_vc;
@@ -144,7 +145,7 @@ public:
 
 private:
   void do_schedule_in();
-  Action *do_cache_open_read();
+  Action *do_cache_open_read(const HttpCacheKey &);
 
   int state_cache_open_read(int event, void *data);
   int state_cache_open_write(int event, void *data);
@@ -165,6 +166,7 @@ private:
 
   // Common parameters
   URL *lookup_url;
+  HttpCacheKey cache_key;
 
   // to keep track of multiple cache lookups
   int lookup_max_recursive;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/7ff2d618/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index b913bff..96030a3 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -4342,8 +4342,12 @@ HttpSM::do_cache_lookup_and_read()
 
   DebugSM("http_seq", "[HttpSM::do_cache_lookup_and_read] [%" PRId64 "] Issuing cache lookup for URL %s", sm_id,
           c_url->string_get(&t_state.arena));
+
+  HttpCacheKey key;
+  Cache::generate_key(&key, c_url, t_state.txn_conf->cache_generation_number);
+
   Action *cache_action_handle =
-    cache_sm.open_read(c_url, &t_state.hdr_info.client_request, &(t_state.cache_info.config),
+    cache_sm.open_read(&key, c_url, &t_state.hdr_info.client_request, &(t_state.cache_info.config),
                        (time_t)((t_state.cache_control.pin_in_cache_for < 0) ? 0 : t_state.cache_control.pin_in_cache_for));
   //
   // pin_in_cache value is an open_write parameter.
@@ -4372,7 +4376,9 @@ HttpSM::do_cache_delete_all_alts(Continuation *cont)
 
   Action *cache_action_handle = NULL;
 
-  cache_action_handle = cacheProcessor.remove(cont, t_state.cache_info.lookup_url, t_state.cache_control.cluster_cache_local);
+  HttpCacheKey key;
+  Cache::generate_key(&key, t_state.cache_info.lookup_url, t_state.txn_conf->cache_generation_number);
+  cache_action_handle = cacheProcessor.remove(cont, &key, t_state.cache_control.cluster_cache_local);
   if (cont != NULL) {
     if (cache_action_handle != ACTION_RESULT_DONE) {
       ink_assert(!pending_action);
@@ -4463,8 +4469,12 @@ HttpSM::do_cache_prepare_action(HttpCacheSM *c_sm, CacheHTTPInfo *object_read_in
 
   ink_assert(s_url != NULL && s_url->valid());
   DebugSM("http_cache_write", "[%" PRId64 "] writing to cache with URL %s", sm_id, s_url->string_get(&t_state.arena));
+
+  HttpCacheKey key;
+  Cache::generate_key(&key, s_url, t_state.txn_conf->cache_generation_number);
+
   Action *cache_action_handle = c_sm->open_write(
-    s_url, &t_state.hdr_info.client_request, object_read_info,
+    &key, s_url, &t_state.hdr_info.client_request, object_read_info,
     (time_t)((t_state.cache_control.pin_in_cache_for < 0) ? 0 : t_state.cache_control.pin_in_cache_for), retry, allow_multiple);
 
   if (cache_action_handle != ACTION_RESULT_DONE) {