The attached patch changes how we store the contents of a varied URI. If a URI is varied, all variations will be stored underneath a new <hash>.header.vary/ directory.
This enables future tools, such as the ability to easily delete a URI from the cache, without scanning the entire tree, just to find the possible varied versions. The code was written pretty quickly, and I would love some feedback both on the idea, and the hacky way I did it :) -Paul
Index: modules/cache/mod_disk_cache.c =================================================================== --- modules/cache/mod_disk_cache.c (revision 219914) +++ modules/cache/mod_disk_cache.c (working copy) @@ -50,8 +50,8 @@ * CRLF */ -#define VARY_FORMAT_VERSION 1 -#define DISK_FORMAT_VERSION 2 +#define VARY_FORMAT_VERSION 3 +#define DISK_FORMAT_VERSION 4 typedef struct { /* Indicates the format of the header struct stored on-disk. */ @@ -76,6 +76,7 @@ typedef struct disk_cache_object { const char *root; /* the location of the cache directory */ char *tempfile; /* temp file tohold the content */ + const char *prefix; const char *datafile; /* name of file where the data will go */ const char *hdrsfile; /* name of file where the hdrs will go */ const char *hashfile; /* Computed hash key for this URI */ @@ -124,6 +125,8 @@ */ #define CACHE_HEADER_SUFFIX ".header" #define CACHE_DATA_SUFFIX ".data" +#define CACHE_VDIR_SUFFIX ".vary" + static char *header_file(apr_pool_t *p, disk_cache_conf *conf, disk_cache_object_t *dobj, const char *name) { @@ -131,8 +134,15 @@ dobj->hashfile = ap_cache_generate_name(p, conf->dirlevels, conf->dirlength, name); } - return apr_pstrcat(p, conf->cache_root, "/", dobj->hashfile, - CACHE_HEADER_SUFFIX, NULL); + + if (dobj->prefix) { + return apr_pstrcat(p, dobj->prefix, CACHE_VDIR_SUFFIX, "/", + dobj->hashfile, CACHE_HEADER_SUFFIX, NULL); + } + else { + return apr_pstrcat(p, conf->cache_root, "/", dobj->hashfile, + CACHE_HEADER_SUFFIX, NULL); + } } static char *data_file(apr_pool_t *p, disk_cache_conf *conf, @@ -142,8 +152,15 @@ dobj->hashfile = ap_cache_generate_name(p, conf->dirlevels, conf->dirlength, name); } - return apr_pstrcat(p, conf->cache_root, "/", dobj->hashfile, - CACHE_DATA_SUFFIX, NULL); + + if (dobj->prefix) { + return apr_pstrcat(p, dobj->prefix, CACHE_VDIR_SUFFIX, "/", + dobj->hashfile, CACHE_DATA_SUFFIX, NULL); + } + else { + return apr_pstrcat(p, conf->cache_root, "/", dobj->hashfile, + CACHE_DATA_SUFFIX, NULL); + } } static void mkdir_structure(disk_cache_conf *conf, const char *file, apr_pool_t *pool) @@ -352,6 +369,7 @@ obj->key = apr_pstrdup(r->pool, key); dobj->name = obj->key; + dobj->prefix = NULL; dobj->datafile = data_file(r->pool, conf, dobj, key); dobj->hdrsfile = header_file(r->pool, conf, dobj, key); dobj->tempfile = apr_pstrcat(r->pool, conf->cache_root, AP_TEMPFILE, NULL); @@ -393,6 +411,8 @@ info = &(obj->info); /* Open the headers file */ + dobj->prefix = NULL; + dobj->hdrsfile = header_file(r->pool, conf, dobj, key); flags = APR_READ|APR_BINARY|APR_BUFFERED; rc = apr_file_open(&dobj->hfd, dobj->hdrsfile, flags, 0, r->pool); @@ -428,6 +448,7 @@ nkey = regen_key(r->pool, r->headers_in, varray, key); dobj->hashfile = NULL; + dobj->prefix = dobj->hdrsfile; dobj->hdrsfile = header_file(r->pool, conf, dobj, nkey); flags = APR_READ|APR_BINARY|APR_BUFFERED; @@ -784,6 +805,7 @@ dobj->tempfile = apr_pstrcat(r->pool, conf->cache_root, AP_TEMPFILE, NULL); tmp = regen_key(r->pool, r->headers_in, varray, dobj->name); + dobj->prefix = dobj->hdrsfile; dobj->hashfile = NULL; dobj->datafile = data_file(r->pool, conf, dobj, tmp); dobj->hdrsfile = header_file(r->pool, conf, dobj, tmp);