This patch is generated from the dtd branch of dsa in squid
Wed Sep 29 00:01:41 2004 GMT
See http://devel.squid-cache.org/

Index: squid/include/version.h
diff -u squid/include/version.h:1.3.4.6.2.2 squid/include/version.h:1.3.4.7
--- squid/include/version.h:1.3.4.6.2.2	Wed Aug 14 04:27:28 2002
+++ squid/include/version.h	Wed Aug 14 04:20:35 2002
@@ -8,5 +8,5 @@
 #endif
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1016582072
+#define SQUID_RELEASE_TIME squid_curtime
 #endif
Index: squid/lib/Array.c
diff -u squid/lib/Array.c:1.3.4.1.8.1 squid/lib/Array.c:1.3.4.1.10.2
--- squid/lib/Array.c:1.3.4.1.8.1	Wed Aug 14 03:15:30 2002
+++ squid/lib/Array.c	Mon Dec 23 13:21:46 2002
@@ -107,10 +107,11 @@
 {
     int i,j;
     assert(a);
-    assert(a->count > 0);
+    if (a->count == 0) return; /* do nothing, when nothing in array */
     for (i = 0; i < a->count; ++i) 
 	if (a->items[i] == obj) 
 	    break;
+    if (i == a->count) return; /* not found */
     --a->count;
     for (j = i; j < a->count; ++j)
 	    a->items[j] = a->items[j+1];
Index: squid/src/HttpReply.c
diff -u squid/src/HttpReply.c:1.3.4.3 squid/src/HttpReply.c:1.3.4.3.10.2
--- squid/src/HttpReply.c:1.3.4.3	Mon Jan 15 14:49:17 2001
+++ squid/src/HttpReply.c	Wed Mar 10 22:02:57 2004
@@ -344,6 +344,13 @@
 	rep->content_type = StringNull;
     rep->cache_control = httpHeaderGetCc(hdr);
     rep->content_range = httpHeaderGetContRange(hdr);
+#ifdef DTD
+    str = base64_decode(httpHeaderGetStr(hdr, HDR_CONTENT_MD5));
+    if (str)
+	stringLimitInit(&rep->content_md5, str, MD5_DIGEST_CHARS);
+    else
+	rep->content_md5 = StringNull;
+#endif
     rep->keep_alive = httpMsgIsPersistent(rep->sline.version, &rep->header);
     /* be sure to set expires after date and cache-control */
     rep->expires = httpReplyHdrExpirationTime(rep);
Index: squid/src/Makefile.in
diff -u squid/src/Makefile.in:1.3.4.4.4.1 squid/src/Makefile.in:1.3.4.4.6.1.2.1
--- squid/src/Makefile.in:1.3.4.4.4.1	Wed Aug 14 03:15:31 2002
+++ squid/src/Makefile.in	Mon Dec 23 20:58:04 2002
@@ -76,6 +76,7 @@
 SHELL		= /bin/sh
 
 INCLUDE		= -I. -I../include -I$(top_srcdir)/include
+DEFINES		= -DDSA -DDTD
 CFLAGS 		= $(AC_CFLAGS) $(INCLUDE) $(DEFINES)
 SQUID_LIBS	= -L../lib $(CRYPTLIB) $(REGEXLIB) @SQUID_PTHREAD_LIB@ \
 		  $(SNMPLIB) $(MALLOCLIB) -lmiscutil $(XTRA_LIBS)
@@ -147,7 +148,6 @@
 		neighbors.o \
 		net_db.o \
 		Packer.o \
-		payload.o \
 		pconn.o \
 		peer_digest.o \
 		peer_select.o \
Index: squid/src/asn.c
diff -u squid/src/asn.c:1.4.2.2.8.2 squid/src/asn.c:1.4.2.3.2.1
--- squid/src/asn.c:1.4.2.2.8.2	Wed Aug 14 04:27:28 2002
+++ squid/src/asn.c	Fri Nov 15 01:10:31 2002
@@ -62,7 +62,11 @@
 };
 
 struct _ASState {
+#ifdef DSA	
+    InstanceEntry *entry;
+#else
     StoreEntry *entry;
+#endif    
     store_client *sc;
     request_t *request;
     int as_number;
@@ -187,7 +191,11 @@
 asnCacheStart(int as)
 {
     LOCAL_ARRAY(char, asres, 4096);
+#ifdef DSA    
+    InstanceEntry *e;
+#else    
     StoreEntry *e;
+#endif    
     request_t *req;
     ASState *asState = xcalloc(1, sizeof(ASState));
     cbdataAdd(asState, cbdataXfree, 0);
@@ -197,19 +205,34 @@
     req = urlParse(METHOD_GET, asres);
     assert(NULL != req);
     asState->request = requestLink(req);
+#ifdef DSA    
+    if ((e = instanceGetPublic(asres, METHOD_GET)) == NULL) {
+	e = instanceCreateEntry(asres, asres, null_request_flags, METHOD_GET);
+	asState->sc = storeClientListAdd(e->p, asState);
+#else	
     if ((e = storeGetPublic(asres, METHOD_GET)) == NULL) {
 	e = storeCreateEntry(asres, asres, null_request_flags, METHOD_GET);
 	asState->sc = storeClientListAdd(e, asState);
+#endif	
 	fwdStart(-1, e, asState->request);
     } else {
-	payloadLockObject(e->p);
+#ifdef DSA	    
+	storeLockObject(e->p);
+	asState->sc = storeClientListAdd(e->p, asState);
+#else	
+	storeLockObject(e);
 	asState->sc = storeClientListAdd(e, asState);
+#endif	
     }
     asState->entry = e;
     asState->seen = 0;
     asState->offset = 0;
     storeClientCopy(asState->sc,
+#ifdef DSA		    
+	e->p,
+#else	
 	e,
+#endif	
 	asState->seen,
 	asState->offset,
 	4096,
@@ -222,7 +245,11 @@
 asHandleReply(void *data, char *buf, ssize_t size)
 {
     ASState *asState = data;
+#ifdef DSA  
+    StoreEntry *e = asState->entry->p;
+#else    
     StoreEntry *e = asState->entry;
+#endif    
     char *s;
     char *t;
     debug(53, 3) ("asHandleReply: Called with size=%d\n", size);
@@ -231,7 +258,7 @@
 	asStateFree(asState);
 	return;
     }
-    if (size == 0 && e->p->mem_obj->inmem_hi > 0) {
+    if (size == 0 && e->mem_obj->inmem_hi > 0) {
 	memFree(buf, MEM_4K_BUF);
 	asStateFree(asState);
 	return;
@@ -240,7 +267,7 @@
 	memFree(buf, MEM_4K_BUF);
 	asStateFree(asState);
 	return;
-    } else if (HTTP_OK != e->p->mem_obj->reply->sline.status) {
+    } else if (HTTP_OK != e->mem_obj->reply->sline.status) {
 	debug(53, 1) ("WARNING: AS %d whois request failed\n",
 	    asState->as_number);
 	memFree(buf, MEM_4K_BUF);
@@ -269,7 +296,11 @@
     debug(53, 3) ("asState->seen = %d, asState->offset = %d\n",
 	asState->seen, asState->offset);
     if (e->store_status == STORE_PENDING) {
+#ifdef DSA	    
 	debug(53, 3) ("asHandleReply: store_status == STORE_PENDING: %s\n", storeUrl(e));
+#else
+	debug(53, 3) ("asHandleReply: store_status == STORE_PENDING: %s\n", storeUrl(e));
+#endif
 	storeClientCopy(asState->sc,
 	    e,
 	    asState->seen,
@@ -278,7 +309,7 @@
 	    buf,
 	    asHandleReply,
 	    asState);
-    } else if (asState->seen < e->p->mem_obj->inmem_hi) {
+    } else if (asState->seen < e->mem_obj->inmem_hi) {
 	debug(53, 3) ("asHandleReply: asState->seen < e->mem_obj->inmem_hi %s\n", storeUrl(e));
 	storeClientCopy(asState->sc,
 	    e,
@@ -299,9 +330,15 @@
 asStateFree(void *data)
 {
     ASState *asState = data;
+#ifdef DSA    
+    debug(53, 3) ("asnStateFree: %s\n", storeUrl(asState->entry->p));
+    storeUnregister(asState->sc, asState->entry->p, asState);
+    storeUnlockObject(asState->entry->p);
+#else    
     debug(53, 3) ("asnStateFree: %s\n", storeUrl(asState->entry));
     storeUnregister(asState->sc, asState->entry, asState);
-    payloadUnlockObject(asState->entry->p);
+    storeUnlockObject(asState->entry);
+#endif    
     requestUnlink(asState->request);
     cbdataFree(asState);
 }
Index: squid/src/cache_manager.c
diff -u squid/src/cache_manager.c:1.3.4.3.8.1 squid/src/cache_manager.c:1.3.4.3.10.1
--- squid/src/cache_manager.c:1.3.4.3.8.1	Wed Aug 14 03:15:31 2002
+++ squid/src/cache_manager.c	Fri Nov 15 01:10:32 2002
@@ -38,7 +38,11 @@
 #define MGR_PASSWD_SZ 128
 
 typedef struct {
+#ifdef DSA	
+    InstanceEntry *entry;
+#else    
     StoreEntry *entry;
+#endif    
     char *action;
     char *user_name;
     char *passwd;
@@ -187,26 +191,45 @@
     safe_free(mgr->action);
     safe_free(mgr->user_name);
     safe_free(mgr->passwd);
-    payloadUnlockObject(mgr->entry->p);
+#ifdef DSA    
+    storeUnlockObject(mgr->entry->p);
+#else    
+    storeUnlockObject(mgr->entry);
+#endif    
     xfree(mgr);
 }
 
 void
+#ifdef DSA
+cachemgrStart(int fd, request_t * request, InstanceEntry * entry)
+#else
 cachemgrStart(int fd, request_t * request, StoreEntry * entry)
+#endif
 {
     cachemgrStateData *mgr = NULL;
     ErrorState *err = NULL;
     action_table *a;
+#ifdef DSA    
+    debug(16, 3) ("objectcacheStart: '%s'\n", storeUrl(entry->p));
+    if ((mgr = cachemgrParseUrl(storeUrl(entry->p))) == NULL) {
+	err = errorCon(ERR_INVALID_URL, HTTP_NOT_FOUND);
+	err->url = xstrdup(storeUrl(entry->p));
+#else	    
     debug(16, 3) ("objectcacheStart: '%s'\n", storeUrl(entry));
     if ((mgr = cachemgrParseUrl(storeUrl(entry))) == NULL) {
 	err = errorCon(ERR_INVALID_URL, HTTP_NOT_FOUND);
 	err->url = xstrdup(storeUrl(entry));
+#endif	    
 	errorAppendEntry(entry, err);
 	entry->expires = squid_curtime;
 	return;
     }
     mgr->entry = entry;
-    payloadLockObject(entry->p);
+#ifdef DSA    
+    storeLockObject(entry->p);
+#else    
+    storeLockObject(entry);
+#endif    
     entry->expires = squid_curtime;
     debug(16, 5) ("CACHEMGR: %s requesting '%s'\n",
 	fd_table[fd].ipaddr, mgr->action);
@@ -236,11 +259,19 @@
 	 */
 	httpHeaderPutAuth(&rep->header, "Basic", mgr->action);
 	/* move info to the mem_obj->reply */
+#ifdef DSA	
 	httpReplyAbsorb(entry->p->mem_obj->reply, rep);
 	/* store the reply */
-	httpReplySwapOut(entry->p->mem_obj->reply, entry);
+	httpReplySwapOut(entry->p->mem_obj->reply, entry->p);
 	entry->expires = squid_curtime;
-	storeComplete(entry);
+	storeComplete(entry->p);
+#else	
+	httpReplyAbsorb(entry->e->mem_obj->reply, rep);
+	/* store the reply */
+	httpReplySwapOut(entry->e->mem_obj->reply, entry);
+	entry->expires = squid_curtime;
+	storeComplete(entry->e);
+#endif	
 	cachemgrStateFree(mgr);
 	return;
     }
@@ -251,10 +282,18 @@
     a = cachemgrFindAction(mgr->action);
     assert(a != NULL);
     if (a->flags.atomic)
+#ifdef DSA	    
+	storeBuffer(entry->p);
+#else    
 	storeBuffer(entry);
+#endif	
     {
 	http_version_t version;
+#ifdef DSA	
 	HttpReply *rep = entry->p->mem_obj->reply;
+#else	
+	HttpReply *rep = entry->mem_obj->reply;
+#endif	
 	/* prove there are no previous reply headers around */
 	assert(0 == rep->sline.status);
 	httpBuildVersion(&version, 1, 0);
@@ -266,12 +305,23 @@
 	    -1,			/* C-Len */
 	    squid_curtime,	/* LMT */
 	    squid_curtime);
+#ifdef DSA
+	httpReplySwapOut(rep, entry->p);
+#else	
 	httpReplySwapOut(rep, entry);
+#endif	
     }
+#ifdef DSA	    
+    a->handler(entry->p);
+    if (a->flags.atomic) {
+	storeBufferFlush(entry->p);
+	storeComplete(entry->p);
+#else	
     a->handler(entry);
     if (a->flags.atomic) {
 	storeBufferFlush(entry);
 	storeComplete(entry);
+#endif	
     }
     cachemgrStateFree(mgr);
 }
Index: squid/src/client_side.c
diff -u squid/src/client_side.c:1.5.2.8.2.2 squid/src/client_side.c:1.5.2.9.2.11.2.10
--- squid/src/client_side.c:1.5.2.8.2.2	Wed Aug 14 04:27:28 2002
+++ squid/src/client_side.c	Wed Mar 10 22:02:57 2004
@@ -94,7 +94,14 @@
 static void clientCheckNoCache(clientHttpRequest *);
 static void clientCheckNoCacheDone(int answer, void *data);
 static STCB clientHandleIMSReply;
+#ifdef DTD
+static STCB clientHandleHEADReply;
+#endif
+#ifdef DSA
+static int clientGetsOldEntry(InstanceEntry * new, InstanceEntry * old, request_t * request);
+#else
 static int clientGetsOldEntry(StoreEntry * new, StoreEntry * old, request_t * request);
+#endif
 static int checkAccelOnly(clientHttpRequest *);
 #if USE_IDENT
 static IDCB clientIdentDone;
@@ -117,6 +124,147 @@
 static int clientReplyBodyTooLarge(int clen);
 static int clientRequestBodyTooLarge(int clen);
 
+#ifdef DTD
+static void
+clientHandleHEADReply(void *data, char *buf, ssize_t size)
+{
+    clientHttpRequest *http = data;
+    StoreEntry *entry = http->entry ? http->entry->p : NULL;
+    MemObject *mem;
+    const char *url = storeUrl(entry);
+    http_status status;
+    debug(33, 3) ("clientHandleHEADReply: %s, %d bytes\n", url, (int) size);
+    if (entry == NULL) {
+	memFree(buf, MEM_CLIENT_SOCK_BUF);
+	return;
+    }
+    if (size < 0 && !EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
+	memFree(buf, MEM_CLIENT_SOCK_BUF);
+	return;
+    }
+    mem = entry->mem_obj;
+    status = mem->reply->sline.status;
+    if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
+	debug(33, 3) ("clientHandleHEADReply: ABORTED '%s'\n", url);
+	/* We have an existing entry, but failed to validate it */
+	/* Its okay to send the old one anyway */
+	http->log_type = LOG_TCP_REFRESH_FAIL_HIT;
+	storeUnregister(http->sc, entry, http);
+	storeUnlockObject(entry);
+	http->entry = http->old_entry;
+	entry = http->entry ? http->entry->p : NULL;
+	http->sc = http->old_sc;
+    } else if (STORE_PENDING == entry->store_status && 0 == status) {
+	debug(33, 3) ("clientHandleHEADReply: Incomplete headers for '%s'\n", url);
+	if (size >= CLIENT_SOCK_SZ) {
+	    /* will not get any bigger than that */
+	    debug(33, 3) ("clientHandleHEADReply: Reply is too large '%s', using old entry\n", url);
+	    /* use old entry, this repeats the code abovez */
+	    http->log_type = LOG_TCP_REFRESH_FAIL_HIT;
+	    storeUnregister(http->sc, entry, http);
+	    storeUnlockObject(entry);
+	    http->entry = http->old_entry;
+	    entry = http->entry ? http->entry->p : NULL;
+	    http->sc = http->old_sc;
+	    /* continue */
+	} else {
+	    storeClientCopy(http->sc, entry,
+		http->out.offset + size,
+		http->out.offset,
+		CLIENT_SOCK_SZ,
+		buf,
+		clientHandleHEADReply,
+		http);
+	    return;
+	}
+    } else {
+	MemObject * mem = entry->mem_obj;
+	/* now we got the HEAD reply, see what we get in Content-MD5 */
+	if (strLen(mem->reply->content_md5) == MD5_DIGEST_CHARS) {
+	    StoreEntry * p = storeGet(strBuf(mem->reply->content_md5));
+	    if (p && storeValidToSend(p)) { /* DTD hit */
+#if 0
+		int unlink_request = 0;
+
+		if (http->old_entry->p->mem_obj->request == NULL) {
+		    http->old_entry->p->mem_obj->request = requestLink(mem->request);
+		    unlink_request = 1;
+		}
+#endif
+		EBIT_SET(http->entry->p->flags, ENTRY_FWD_HDR_WAIT);
+		storeTimestampsSet(http->old_entry);
+		http->old_entry->lastmod = http->entry->lastmod;
+//		arrayDelete(http->entry->p->instances, http->entry);
+		storeUnregister(http->sc, http->entry->p, http);
+		http->sc = http->old_sc;
+		storeUnlockObject(http->entry->p);
+		http->entry = http->old_entry;
+		http->entry->timestamp = squid_curtime;
+#if 0
+		if (unlink_request) {
+		    requestUnlink(http->entry->p->mem_obj->request);
+		    http->entry->p->mem_obj->request = NULL;
+		}
+#endif
+		http->old_entry = NULL;
+		http->old_sc = NULL;
+		/* set the StoreEntry for DTD to the parameters of the
+		 * StoreEntry in cache */
+//		storeUnregister(http->sc, http->entry->p, http);
+		EBIT_CLR(http->entry->flags, ENTRY_DISPATCHED);
+		if (http->entry->p->hash.key) {
+		    storeKeyFree(http->entry->p->hash.key);
+		    http->entry->p->hash.key = NULL;
+		}
+		http->entry->p->hash.key = storeKeyDup(strBuf(mem->reply->content_md5));
+		storeAddInstanceEntry(p, http->entry);
+		EBIT_CLR(http->entry->p->flags, KEY_PRIVATE);
+		EBIT_SET(http->entry->p->flags, ENTRY_FWD_HDR_WAIT);
+		http->entry->p->flags = p->flags;
+		http->entry->p->mem_obj->object_sz = -1;
+		http->entry->p->swap_file_sz = p->swap_file_sz;
+		http->entry->p->swap_filen = p->swap_filen;
+		http->entry->p->swap_dirn = p->swap_dirn;
+		http->entry->p->store_status = STORE_OK;
+		http->entry->p->swap_status = SWAPOUT_DONE;
+		http->request->method = METHOD_GET;
+		http->sc->type = STORE_DISK_CLIENT;
+		http->out.offset = 0;
+		p->lastref = http->entry->p->lastref;
+		p->refcount += http->entry->p->refcount;
+
+		/* this section copies from clientProcessRequest */
+//		storeLockObject(http->entry->p);
+		storeCreateMemObject(http->entry->p, http->uri, http->log_uri);
+//		http->sc = storeClientListAdd(http->entry->p, http);
+		http->log_type = LOG_TCP_HIT;
+
+		storeClientCopy(http->sc, http->entry->p,
+			http->out.offset, 
+			http->out.offset,
+			CLIENT_SOCK_SZ,
+			memAllocate(MEM_CLIENT_SOCK_BUF),
+			clientCacheHit,
+			http);
+	    }
+	    else { /* DTD miss */
+	        if (entry->hash.key) {
+		    storeKeyFree(entry->hash.key);
+		    entry->hash.key = NULL;
+	        }	 
+		entry->hash.key = storeKeyDup(strBuf(mem->reply->content_md5));
+		EBIT_CLR(entry->flags, KEY_PRIVATE);
+assert(entry->hash.key);		
+		storeClientCopy(http->sc, http->entry->p, mem->inmem_hi, 0, CLIENT_SOCK_SZ, memAllocate(MEM_CLIENT_SOCK_BUF), clientSendMoreData, http);
+	    }    
+	}
+	else { /* Invalid or missing Content-MD5 tag, a cache miss */
+	    storeClientCopy(http->sc, http->entry->p, mem->inmem_hi, 0, CLIENT_SOCK_SZ, memAllocate(MEM_CLIENT_SOCK_BUF), clientSendMoreData, http);
+	}
+    }
+}
+#endif
+
 static int
 checkAccelOnly(clientHttpRequest * http)
 {
@@ -191,6 +339,30 @@
 	EBIT_TEST(r->cache_control->mask, CC_ONLY_IF_CACHED);
 }
 
+#ifdef DSA
+InstanceEntry *
+clientCreateStoreEntry(clientHttpRequest * h, method_t m, request_flags flags)
+{
+    InstanceEntry *e;
+    /*
+     * For erroneous requests, we might not have a h->request,
+     * so make a fake one.
+     */
+    if (h->request == NULL)
+	h->request = requestLink(requestCreate(m, PROTO_NONE, null_string));
+    e = instanceCreateEntry(h->uri, h->log_uri, flags, m);
+    h->sc = storeClientListAdd(e->p, h);
+#if DELAY_POOLS
+    delaySetStoreClient(h->sc, delayClient(h->request));
+#endif
+#ifdef DTD
+    if (h->request->method != METHOD_GET || h->request->flags.ims || h->request->flags.refresh || h->request->flags.nocache || !h->request->flags.cachable)
+#endif
+    storeClientCopy(h->sc, e->p, 0, 0, CLIENT_SOCK_SZ,
+	memAllocate(MEM_CLIENT_SOCK_BUF), clientSendMoreData, h);
+    return e;
+}
+#else
 StoreEntry *
 clientCreateStoreEntry(clientHttpRequest * h, method_t m, request_flags flags)
 {
@@ -202,7 +374,6 @@
     if (h->request == NULL)
 	h->request = requestLink(requestCreate(m, PROTO_NONE, null_string));
     e = storeCreateEntry(h->uri, h->log_uri, flags, m);
-	/* initialize PayloadEntry */
     h->sc = storeClientListAdd(e, h);
 #if DELAY_POOLS
     delaySetStoreClient(h->sc, delayClient(h->request));
@@ -211,6 +382,7 @@
 	memAllocate(MEM_CLIENT_SOCK_BUF), clientSendMoreData, h);
     return e;
 }
+#endif
 
 void
 clientAccessCheckDone(int answer, void *data)
@@ -345,7 +517,11 @@
 {
     clientHttpRequest *http = data;
     char *url = http->uri;
+#ifdef DSA
+    InstanceEntry *entry = NULL;
+#else
     StoreEntry *entry = NULL;
+#endif
     debug(33, 3) ("clientProcessExpired: '%s'\n", http->uri);
     assert(http->entry->lastmod >= 0);
     /*
@@ -366,12 +542,21 @@
      * freed from memory before we need to access it.
      */
     assert(http->sc->callback_data == http);
+#ifdef DSA
+    entry = instanceCreateEntry(url,
+	http->log_uri,
+	http->request->flags,
+	http->request->method);
+    /* NOTE, don't call storeLockObject(), storeCreateEntry() does it */
+    http->sc = storeClientListAdd(entry->p, http);
+#else
     entry = storeCreateEntry(url,
 	http->log_uri,
-	http->request->flags,	
+	http->request->flags,
 	http->request->method);
     /* NOTE, don't call storeLockObject(), storeCreateEntry() does it */
     http->sc = storeClientListAdd(entry, http);
+#endif
 #if DELAY_POOLS
     /* delay_id is already set on original store client */
     delaySetStoreClient(http->sc, delayClient(http->request));
@@ -382,9 +567,15 @@
     http->out.offset = 0;
     fwdStart(http->conn->fd, http->entry, http->request);
     /* Register with storage manager to receive updates when data comes in. */
+#ifdef DSA
+    if (EBIT_TEST(entry->p->flags, ENTRY_ABORTED))
+	debug(33, 0) ("clientProcessExpired: found ENTRY_ABORTED object\n");
+    storeClientCopy(http->sc, entry->p,
+#else
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED))
 	debug(33, 0) ("clientProcessExpired: found ENTRY_ABORTED object\n");
     storeClientCopy(http->sc, entry,
+#endif
 	http->out.offset,
 	http->out.offset,
 	CLIENT_SOCK_SZ,
@@ -394,9 +585,15 @@
 }
 
 static int
-clientGetsOldEntry(StoreEntry * new_entry, StoreEntry * old_entry, request_t * request)
+#ifdef DSA
+clientGetsOldEntry(InstanceEntry * new_entry, InstanceEntry * old_entry, request_t * request)
 {
     const http_status status = new_entry->p->mem_obj->reply->sline.status;
+#else
+clientGetsOldEntry(StoreEntry * new_entry, StoreEntry * old_entry, request_t * request)
+{
+    const http_status status = new_entry->mem_obj->reply->sline.status;
+#endif
     if (0 == status) {
 	debug(33, 5) ("clientGetsOldEntry: YES, broken HTTP reply\n");
 	return 1;
@@ -435,11 +632,19 @@
 clientHandleIMSReply(void *data, char *buf, ssize_t size)
 {
     clientHttpRequest *http = data;
+#ifdef DSA
+    InstanceEntry *entry = http->entry;
+    MemObject *mem;
+    const char *url = storeUrl(entry->p);
+    int unlink_request = 0;
+    InstanceEntry *oldentry;
+#else
     StoreEntry *entry = http->entry;
     MemObject *mem;
     const char *url = storeUrl(entry);
     int unlink_request = 0;
     StoreEntry *oldentry;
+#endif
     int recopy = 1;
     http_status status;
     debug(33, 3) ("clientHandleIMSReply: %s, %d bytes\n", url, (int) size);
@@ -447,35 +652,62 @@
 	memFree(buf, MEM_CLIENT_SOCK_BUF);
 	return;
     }
+#ifdef DSA
+    if (size < 0 && !EBIT_TEST(entry->p->flags, ENTRY_ABORTED)) {
+#else
     if (size < 0 && !EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
+#endif
 	memFree(buf, MEM_CLIENT_SOCK_BUF);
 	return;
     }
+#ifdef DSA
     mem = entry->p->mem_obj;
     status = mem->reply->sline.status;
+    if (EBIT_TEST(entry->p->flags, ENTRY_ABORTED)) {
+#else
+    mem = entry->mem_obj;
+    status = mem->reply->sline.status;
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
+#endif
 	debug(33, 3) ("clientHandleIMSReply: ABORTED '%s'\n", url);
 	/* We have an existing entry, but failed to validate it */
 	/* Its okay to send the old one anyway */
 	http->log_type = LOG_TCP_REFRESH_FAIL_HIT;
+#ifdef DSA
+	storeUnregister(http->sc, entry->p, http);
+	storeUnlockObject(entry->p);
+	entry = http->entry = http->old_entry;
+	http->sc = http->old_sc;
+    } else if (STORE_PENDING == entry->p->store_status && 0 == status) {
+#else
 	storeUnregister(http->sc, entry, http);
-	payloadUnlockObject(entry->p);
+	storeUnlockObject(entry);
 	entry = http->entry = http->old_entry;
 	http->sc = http->old_sc;
     } else if (STORE_PENDING == entry->store_status && 0 == status) {
+#endif
 	debug(33, 3) ("clientHandleIMSReply: Incomplete headers for '%s'\n", url);
 	if (size >= CLIENT_SOCK_SZ) {
 	    /* will not get any bigger than that */
 	    debug(33, 3) ("clientHandleIMSReply: Reply is too large '%s', using old entry\n", url);
 	    /* use old entry, this repeats the code abovez */
 	    http->log_type = LOG_TCP_REFRESH_FAIL_HIT;
+#ifdef DSA
+	    storeUnregister(http->sc, entry->p, http);
+	    storeUnlockObject(entry->p);
+#else
 	    storeUnregister(http->sc, entry, http);
-	    payloadUnlockObject(entry->p);
+	    storeUnlockObject(entry);
+#endif
 	    entry = http->entry = http->old_entry;
 	    http->sc = http->old_sc;
 	    /* continue */
 	} else {
+#ifdef DSA
+	    storeClientCopy(http->sc, entry->p,
+#else
 	    storeClientCopy(http->sc, entry,
+#endif
 		http->out.offset + size,
 		http->out.offset,
 		CLIENT_SOCK_SZ,
@@ -490,46 +722,79 @@
 	 * headers have been loaded from disk. */
 	oldentry = http->old_entry;
 	http->log_type = LOG_TCP_REFRESH_HIT;
+#ifdef DSA
 	if (oldentry->p->mem_obj->request == NULL) {
 	    oldentry->p->mem_obj->request = requestLink(mem->request);
+#else
+	if (oldentry->mem_obj->request == NULL) {
+	    oldentry->mem_obj->request = requestLink(mem->request);
+#endif
 	    unlink_request = 1;
 	}
 	/* Don't memcpy() the whole reply structure here.  For example,
 	 * www.thegist.com (Netscape/1.13) returns a content-length for
 	 * 304's which seems to be the length of the 304 HEADERS!!! and
 	 * not the body they refer to.  */
+#ifdef DSA
 	httpReplyUpdateOnNotModified(oldentry->p->mem_obj->reply, mem->reply);
 	storeTimestampsSet(oldentry);
+	storeUnregister(http->sc, entry->p, http);
+	http->sc = http->old_sc;
+	storeUnlockObject(entry->p);
+#else
+	httpReplyUpdateOnNotModified(oldentry->mem_obj->reply, mem->reply);
+	storeTimestampsSet(oldentry);
 	storeUnregister(http->sc, entry, http);
 	http->sc = http->old_sc;
-	payloadUnlockObject(entry->p);
+	storeUnlockObject(entry);
+#endif
 	entry = http->entry = oldentry;
 	entry->timestamp = squid_curtime;
 	if (unlink_request) {
+#ifdef DSA
 	    requestUnlink(entry->p->mem_obj->request);
 	    entry->p->mem_obj->request = NULL;
+#else
+	    requestUnlink(entry->mem_obj->request);
+	    entry->mem_obj->request = NULL;
+#endif
 	}
     } else {
 	/* the client can handle this reply, whatever it is */
 	http->log_type = LOG_TCP_REFRESH_MISS;
 	if (HTTP_NOT_MODIFIED == mem->reply->sline.status) {
+#ifdef DSA
 	    httpReplyUpdateOnNotModified(http->old_entry->p->mem_obj->reply,
 		mem->reply);
 	    storeTimestampsSet(http->old_entry);
 	    http->log_type = LOG_TCP_REFRESH_HIT;
 	}
-	else { /* REFRESH_MISS, remove StoreEntry from PayloadEntry */
-	    payloadRemoveStoreEntry(http->old_entry->p, http->old_entry);	
-	}	
+	else
+	    storeRemoveInstanceEntry(http->old_entry->p, http->old_entry);	
+	storeUnregister(http->old_sc, http->old_entry->p, http);
+	storeUnlockObject(http->old_entry->p);
+#else
+	    httpReplyUpdateOnNotModified(http->old_entry->mem_obj->reply,
+		mem->reply);
+	    storeTimestampsSet(http->old_entry);
+	    http->log_type = LOG_TCP_REFRESH_HIT;
+	}
 	storeUnregister(http->old_sc, http->old_entry, http);
-	payloadUnlockObject(http->old_entry->p);
+	storeUnlockObject(http->old_entry);
+#endif
 	recopy = 0;
     }
     http->old_entry = NULL;	/* done with old_entry */
     http->old_sc = NULL;
+#ifdef DSA
+    assert(!EBIT_TEST(entry->p->flags, ENTRY_ABORTED));
+    if (recopy) {
+	storeClientCopy(http->sc, entry->p,
+#else
     assert(!EBIT_TEST(entry->flags, ENTRY_ABORTED));
     if (recopy) {
 	storeClientCopy(http->sc, entry,
+#endif
 	    http->out.offset,
 	    http->out.offset,
 	    CLIENT_SOCK_SZ,
@@ -542,12 +807,24 @@
 }
 
 int
+#ifdef DSA
+modifiedSince(InstanceEntry * entry, request_t * request)
+#else
 modifiedSince(StoreEntry * entry, request_t * request)
+#endif
 {
     int object_length;
+#ifdef DSA
     MemObject *mem = entry->p->mem_obj;
+#else
+    MemObject *mem = entry->mem_obj;
+#endif
     time_t mod_time = entry->lastmod;
+#ifdef DSA
+    debug(33, 3) ("modifiedSince: '%s'\n", storeUrl(entry->p));
+#else
     debug(33, 3) ("modifiedSince: '%s'\n", storeUrl(entry));
+#endif
     if (mod_time < 0)
 	mod_time = entry->timestamp;
     debug(33, 3) ("modifiedSince: mod_time = %d\n", (int) mod_time);
@@ -556,7 +833,11 @@
     /* Find size of the object */
     object_length = mem->reply->content_length;
     if (object_length < 0)
+#ifdef DSA
+	object_length = contentLen(entry->p);
+#else
 	object_length = contentLen(entry);
+#endif
     if (mod_time > request->ims) {
 	debug(33, 3) ("--> YES: entry newer than client\n");
 	return 1;
@@ -578,7 +859,11 @@
 void
 clientPurgeRequest(clientHttpRequest * http)
 {
+#ifdef DSA
+    InstanceEntry *entry;
+#else
     StoreEntry *entry;
+#endif
     ErrorState *err = NULL;
     HttpReply *r;
     http_status status;
@@ -596,26 +881,58 @@
     http->log_type = LOG_TCP_MISS;
     /* Release both IP and object cache entries */
     ipcacheInvalidate(http->request->host);
+#ifdef DSA
+    if ((entry = instanceGetPublic(http->uri, METHOD_GET)) == NULL) {
+	status = HTTP_NOT_FOUND;
+    } else {
+	instanceRelease(entry);
+#else
     if ((entry = storeGetPublic(http->uri, METHOD_GET)) == NULL) {
 	status = HTTP_NOT_FOUND;
     } else {
 	storeRelease(entry);
+#endif
 	status = HTTP_OK;
     }
     debug(33, 4) ("clientPurgeRequest: Not modified '%s'\n",
+#ifdef DSA
+	storeUrl(entry->p));
+#else
 	storeUrl(entry));
+#endif
     /*
      * Make a new entry to hold the reply to be written
      * to the client.
      */
     http->entry = clientCreateStoreEntry(http, http->request->method, null_request_flags);
+#ifdef DSA
     httpReplyReset(r = http->entry->p->mem_obj->reply);
     httpBuildVersion(&version, 1, 0);
     httpReplySetHeaders(r, version, status, NULL, NULL, 0, 0, -1);
+    httpReplySwapOut(r, http->entry->p);
+    storeComplete(http->entry->p);
+#else
+    httpReplyReset(r = http->entry->mem_obj->reply);
+    httpBuildVersion(&version, 1, 0);
+    httpReplySetHeaders(r, version, status, NULL, NULL, 0, 0, -1);
     httpReplySwapOut(r, http->entry);
     storeComplete(http->entry);
+#endif
 }
 
+#ifdef DSA
+int
+checkNegativeHit(InstanceEntry * e)
+{
+    if (!EBIT_TEST(e->flags, ENTRY_NEGCACHED))
+	return 0;
+    if (e->expires <= squid_curtime)
+	return 0;
+    if (e->p->store_status != STORE_OK)
+	return 0;
+    return 1;
+}
+#else
 int
 checkNegativeHit(StoreEntry * e)
 {
@@ -627,6 +944,7 @@
 	return 0;
     return 1;
 }
+#endif
 
 void
 clientUpdateCounters(clientHttpRequest * http)
@@ -698,10 +1016,18 @@
     clientHttpRequest *http = data;
     clientHttpRequest **H;
     ConnStateData *conn = http->conn;
+#ifdef DSA
+    InstanceEntry *e;
+#else
     StoreEntry *e;
+#endif
     request_t *request = http->request;
     MemObject *mem = NULL;
+#ifdef DSA
+    debug(33, 3) ("httpRequestFree: %s\n", storeUrl(http->entry->p));
+#else
     debug(33, 3) ("httpRequestFree: %s\n", storeUrl(http->entry));
+#endif
     if (!clientCheckTransferDone(http)) {
 #if MYSTERIOUS_CODE
 	/*
@@ -712,15 +1038,25 @@
 	if ((e = http->entry)) {
 	    http->entry = NULL;
 	    storeUnregister(http->sc, e, http);
-	    payloadUnlockObject(e);
+	    storeUnlockObject(e);
 	}
 #endif
+#ifdef DSA
+	if (http->entry && http->entry->p && http->entry->p->ping_status == PING_WAITING)
+	    storeReleaseRequest(http->entry->p);
+#else
 	if (http->entry && http->entry->ping_status == PING_WAITING)
 	    storeReleaseRequest(http->entry);
+#endif
     }
     assert(http->log_type < LOG_TYPE_MAX);
-    if (http->entry)
+#ifdef DSA
+    if (http->entry && http->entry->p)
 	mem = http->entry->p->mem_obj;
+#else
+    if (http->entry)
+	mem = http->entry->mem_obj;
+#endif
     if (http->out.size || http->log_type) {
 	http->al.icp.opcode = ICP_INVALID;
 	http->al.url = http->log_uri;
@@ -765,18 +1101,64 @@
     safe_free(http->redirect.location);
     stringClean(&http->range_iter.boundary);
     if ((e = http->entry)) {
+#ifdef DSA
+	/* ymc:
+	 * In this version, StoreEntry is the argument
+	 * for most store.c functions. That means
+	 * when there is a MISS and the StoreEntry
+	 * created for the connection between
+	 * proxy and server will remain attached
+	 * to the InstanceEntry until the end of that
+	 * connection. Sometimes, when we already
+	 * have this StoreEntry in cache (ie web object
+	 * of the same Content Digest is in the cache)
+	 * We will have to replace the link from 
+	 * our InstanceEntry to that old StoreEntry
+	 * That's exactly what we are doing here.
+	 */ 
+	if (!EBIT_TEST(e->p->flags, ENTRY_FWD_HDR_WAIT)) {   
+	StoreEntry * p = NULL;
+	StoreEntry * op = http->entry->p;
+        p = storeGet(op->hash.key);	
+	http->entry = NULL;
+	if (p == op) storeLockObject(p);
+	storeUnregister(http->sc, e->p, http);
+	if (p && p != op && storeValidToSend(p) && !EBIT_TEST(e->flags, RELEASE_REQUEST)) {
+	    arrayDelete(op->instances, e);
+	    storeSetPublicKey(e);
+#ifdef DTD
+	    e->p->swap_file_sz = -1;
+	    e->p->swap_filen = -1;
+	    e->p->swap_dirn = -1;
+	    e->p = p;
+	    storeLockObject(p);
+#else
+	    e->p = p;
+#endif
+	}
+        }
+	http->sc = NULL;
+	storeUnlockObject(e->p);
+#else
 	http->entry = NULL;
 	storeUnregister(http->sc, e, http);
 	http->sc = NULL;
-	payloadUnlockObject(e->p);
+	storeUnlockObject(e);
+#endif
     }
     /* old_entry might still be set if we didn't yet get the reply
      * code in clientHandleIMSReply() */
     if ((e = http->old_entry)) {
 	http->old_entry = NULL;
+#ifdef DSA
+	storeUnregister(http->old_sc, e->p, http);
+	http->old_sc = NULL;
+	storeUnlockObject(e->p);
+#else
 	storeUnregister(http->old_sc, e, http);
 	http->old_sc = NULL;
-	payloadUnlockObject(e->p);
+	storeUnlockObject(e);
+#endif
     }
     requestUnlink(http->request);
     assert(http != http->next);
@@ -1097,14 +1479,22 @@
     const HttpHdrRangeSpec *spec;
     MemBuf mb;
 
+#ifdef DSA    
     assert(http->entry->p->mem_obj);
+#else
+    assert(http->entry->mem_obj);
+#endif
 
     memBufDefInit(&mb);
     while ((spec = httpHdrRangeGetSpec(http->request->range, &pos))) {
 
 	/* account for headers for this range */
 	memBufReset(&mb);
+#ifdef DSA
 	clientPackRangeHdr(http->entry->p->mem_obj->reply,
+#else
+	clientPackRangeHdr(http->entry->mem_obj->reply,
+#endif
 	    spec, http->range_iter.boundary, &mb);
 	clen += mb.size;
 
@@ -1141,7 +1531,11 @@
 	range_err = "origin server does ranges";
     else if (rep->content_length < 0)
 	range_err = "unknown length";
+#ifdef DSA
     else if (rep->content_length != http->entry->p->mem_obj->reply->content_length)
+#else
+    else if (rep->content_length != http->entry->mem_obj->reply->content_length)
+#endif
 	range_err = "INCONSISTENT length";	/* a bug? */
     else if (httpHeaderHas(&http->request->header, HDR_IF_RANGE) && !clientIfRangeMatch(http, rep))
 	range_err = "If-Range match failed";
@@ -1299,7 +1693,7 @@
      * debugger [hdr->entries.count-1].
      */
     httpHeaderPutStr(hdr, HDR_X_REQUEST_URI,
-	http->entry->p->mem_obj->url ? http->entry->p->mem_obj->url : http->uri);
+	http->entry->mem_obj->url ? http->entry->mem_obj->url : http->uri);
 #endif
 }
 
@@ -1341,7 +1735,11 @@
 clientCacheHit(void *data, char *buf, ssize_t size)
 {
     clientHttpRequest *http = data;
+#ifdef DSA
+    InstanceEntry *e = http->entry;
+#else
     StoreEntry *e = http->entry;
+#endif
     MemObject *mem;
     request_t *r = http->request;
     debug(33, 3) ("clientCacheHit: %s, %d bytes\n", http->uri, (int) size);
@@ -1354,24 +1752,41 @@
 	memFree(buf, MEM_CLIENT_SOCK_BUF);
 	debug(33, 3) ("clientCacheHit: swapin failure for %s\n", http->uri);
 	http->log_type = LOG_TCP_SWAPFAIL_MISS;
+#ifdef DSA
+	if ((e = http->entry) && e->p) {
+	    http->entry = NULL;
+	    storeUnregister(http->sc, e->p, http);
+	    http->sc = NULL;
+	    storeUnlockObject(e->p);
+#else
 	if ((e = http->entry)) {
 	    http->entry = NULL;
 	    storeUnregister(http->sc, e, http);
 	    http->sc = NULL;
-	    payloadUnlockObject(e->p);
+	    storeUnlockObject(e);
+#endif
 	}
 	clientProcessMiss(http);
 	return;
     }
     assert(size > 0);
+#ifdef DSA
     mem = e->p->mem_obj;
+    assert(!EBIT_TEST(e->p->flags, ENTRY_ABORTED));
+#else
+    mem = e->mem_obj;
     assert(!EBIT_TEST(e->flags, ENTRY_ABORTED));
+#endif
     if (mem->reply->sline.status == 0) {
 	/*
 	 * we don't have full reply headers yet; either wait for more or
 	 * punt to clientProcessMiss.
 	 */
-	if (e->p->mem_status == IN_MEMORY || e->store_status == STORE_OK) {
+#ifdef DSA
+	if (e->p->mem_status == IN_MEMORY || e->p->store_status == STORE_OK) {
+#else
+	if (e->mem_status == IN_MEMORY || e->store_status == STORE_OK) {
+#endif
 	    memFree(buf, MEM_CLIENT_SOCK_BUF);
 	    clientProcessMiss(http);
 	} else if (size == CLIENT_SOCK_SZ && http->out.offset == 0) {
@@ -1379,7 +1794,11 @@
 	    clientProcessMiss(http);
 	} else {
 	    debug(33, 3) ("clientCacheHit: waiting for HTTP reply headers\n");
+#ifdef DSA
+	    storeClientCopy(http->sc, e->p,
+#else
 	    storeClientCopy(http->sc, e,
+#endif
 		http->out.offset + size,
 		http->out.offset,
 		CLIENT_SOCK_SZ,
@@ -1402,7 +1821,11 @@
 	 * request.  We cannot validate a cached object for a HEAD
 	 * request, nor can we return 304.
 	 */
+#ifdef DSA
 	if (e->p->mem_status == IN_MEMORY)
+#else
+	if (e->mem_status == IN_MEMORY)
+#endif
 	    http->log_type = LOG_TCP_MEM_HIT;
 	clientSendMoreData(data, buf, size);
     } else if (refreshCheckHTTP(e, r) && !http->flags.internal) {
@@ -1463,12 +1886,21 @@
 	    clientSendMoreData(data, buf, size);
 	} else {
 	    time_t timestamp = e->timestamp;
+#ifdef DSA
 	    MemBuf mb = httpPacked304Reply(e->p->mem_obj->reply);
 	    http->log_type = LOG_TCP_IMS_HIT;
 	    memFree(buf, MEM_CLIENT_SOCK_BUF);
+	    storeUnregister(http->sc, e->p, http);
+	    http->sc = NULL;
+	    storeUnlockObject(e->p);
+#else
+	    MemBuf mb = httpPacked304Reply(e->mem_obj->reply);
+	    http->log_type = LOG_TCP_IMS_HIT;
+	    memFree(buf, MEM_CLIENT_SOCK_BUF);
 	    storeUnregister(http->sc, e, http);
 	    http->sc = NULL;
-	    payloadUnlockObject(e->p);
+	    storeUnlockObject(e);
+#endif
 	    e = clientCreateStoreEntry(http, http->request->method, null_request_flags);
 	    /*
 	     * Copy timestamp from the original entry so the 304
@@ -1476,16 +1908,27 @@
 	     */
 	    e->timestamp = timestamp;
 	    http->entry = e;
+#ifdef DSA
 	    httpReplyParse(e->p->mem_obj->reply, mb.buf, mb.size);
+	    storeAppend(e->p, mb.buf, mb.size);
+	    memBufClean(&mb);
+	    storeComplete(e->p);
+#else
+	    httpReplyParse(e->mem_obj->reply, mb.buf, mb.size);
 	    storeAppend(e, mb.buf, mb.size);
 	    memBufClean(&mb);
 	    storeComplete(e);
+#endif
 	}
     } else {
 	/*
 	 * plain ol' cache hit
 	 */
+#ifdef DSA
 	if (e->p->mem_status == IN_MEMORY)
+#else
+	if (e->mem_status == IN_MEMORY)
+#endif
 	    http->log_type = LOG_TCP_MEM_HIT;
 	else if (Config.onoff.offline)
 	    http->log_type = LOG_TCP_OFFLINE_HIT;
@@ -1554,9 +1997,15 @@
      * multi-range
      */
     if (http->request->range->specs.count > 1 && i->debt_size == i->spec->length) {
+#ifdef DSA
 	assert(http->entry->p->mem_obj);
 	clientPackRangeHdr(
 	    http->entry->p->mem_obj->reply,	/* original reply */
+#else
+	assert(http->entry->mem_obj);
+	clientPackRangeHdr(
+	    http->entry->mem_obj->reply,	/* original reply */
+#endif	    
 	    i->spec,		/* current range */
 	    i->boundary,	/* boundary, the same for all */
 	    mb
@@ -1688,7 +2137,11 @@
 clientSendMoreData(void *data, char *buf, ssize_t size)
 {
     clientHttpRequest *http = data;
+#ifdef DSA
+    StoreEntry *entry = http->entry ? http->entry->p : NULL;
+#else
     StoreEntry *entry = http->entry;
+#endif
     ConnStateData *conn = http->conn;
     int fd = conn->fd;
     HttpReply *rep = NULL;
@@ -1737,9 +2190,15 @@
 	if (rep && clientReplyBodyTooLarge(rep->content_length)) {
 	    ErrorState *err = errorCon(ERR_TOO_BIG, HTTP_FORBIDDEN);
 	    err->request = requestLink(http->request);
+#ifdef DSA
+	    storeUnregister(http->sc, http->entry->p, http);
+	    http->sc = NULL;
+	    storeUnlockObject(http->entry->p);
+#else
 	    storeUnregister(http->sc, http->entry, http);
 	    http->sc = NULL;
-	    payloadUnlockObject(http->entry->p);
+	    storeUnlockObject(http->entry);
+#endif
 	    http->entry = clientCreateStoreEntry(http, http->request->method,
 		null_request_flags);
 	    errorAppendEntry(http->entry, err);
@@ -1873,7 +2332,11 @@
 	/*
 	 * Note, the FD may be closed at this point.
 	 */
+#ifdef DSA
+    } else if ((entry = http->entry->p) == NULL) {
+#else
     } else if ((entry = http->entry) == NULL) {
+#endif
 	/*
 	 * this request is in progress, maybe doing an ACL or a redirect,
 	 * execution will resume after the operation completes.
@@ -1900,7 +2363,11 @@
 clientWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *data)
 {
     clientHttpRequest *http = data;
+#ifdef DSA
+    StoreEntry *entry = http->entry ? http->entry->p : NULL;
+#else
     StoreEntry *entry = http->entry;
+#endif
     int done;
     http->out.size += size;
     debug(33, 5) ("clientWriteComplete: FD %d, sz %d, err %d, off %d, len %d\n",
@@ -1922,7 +2389,7 @@
     } else if ((done = clientCheckTransferDone(http)) != 0 || size == 0) {
 	debug(33, 5) ("clientWriteComplete: FD %d transfer is DONE\n", fd);
 	/* We're finished case */
-	if (httpReplyBodySize(http->request->method, entry->p->mem_obj->reply) < 0) {
+	if (httpReplyBodySize(http->request->method, entry->mem_obj->reply) < 0) {
 	    debug(33, 5) ("clientWriteComplete: closing, content_length < 0\n");
 	    comm_close(fd);
 	} else if (!done) {
@@ -1944,6 +2411,9 @@
 	 * storage manager. */
 	if (EBIT_TEST(entry->flags, ENTRY_ABORTED))
 	    debug(33, 0) ("clientWriteComplete 2: ENTRY_ABORTED\n");
+#ifdef DTD
+	if (http->sc->entry != entry) http->sc->entry = entry;
+#endif
 	storeClientCopy(http->sc, entry,
 	    http->out.offset,
 	    http->out.offset,
@@ -1972,10 +2442,17 @@
     err = errorCon(ERR_ONLY_IF_CACHED_MISS, HTTP_GATEWAY_TIMEOUT);
     err->request = requestLink(r);
     err->src_addr = http->conn->peer.sin_addr;
+#ifdef DSA
+    if (http->entry) {
+	storeUnregister(http->sc, http->entry->p, http);
+	http->sc = NULL;
+	storeUnlockObject(http->entry->p);
+#else
     if (http->entry) {
 	storeUnregister(http->sc, http->entry, http);
 	http->sc = NULL;
-	payloadUnlockObject(http->entry->p);
+	storeUnlockObject(http->entry);
+#endif
     }
     http->entry = clientCreateStoreEntry(http, r->method, null_request_flags);
     errorAppendEntry(http->entry, err);
@@ -2005,8 +2482,8 @@
      * if the part we want is already cached.  If so, we don't
      * force a miss.
      */
-    assert(NULL != entry->p->mem_obj);
-    if (httpHdrRangeFirstOffset(range) <= entry->p->mem_obj->inmem_hi)
+    assert(NULL != entry->mem_obj);
+    if (httpHdrRangeFirstOffset(range) <= entry->mem_obj->inmem_hi)
 	return 0;
     /*
      * Even though we have a PENDING copy of the object, we
@@ -2021,11 +2498,31 @@
 clientProcessRequest2(clientHttpRequest * http)
 {
     request_t *r = http->request;
+#ifdef DSA
+    InstanceEntry *e;
+    e = http->entry = instanceGetPublic(http->uri, r->method);
+    /*
+    if (e && e->p == NULL) {
+	EBIT_CLR(e->flags, ENTRY_CACHABLE);
+	instanceRelease(e);
+	e = http->entry = NULL;
+    }	    
+    if (e && e->p && e->p->hash.key == NULL) {
+	EBIT_CLR(e->flags, ENTRY_CACHABLE);
+	instanceRelease(e);
+	e = http->entry = NULL;
+    }
+    */
+    if (r->method == METHOD_HEAD && e == NULL) {
+	/* We can generate a HEAD reply from a cached GET object */
+	e = http->entry = instanceGetPublic(http->uri, METHOD_GET);
+#else
     StoreEntry *e;
     e = http->entry = storeGetPublic(http->uri, r->method);
     if (r->method == METHOD_HEAD && e == NULL) {
 	/* We can generate a HEAD reply from a cached GET object */
 	e = http->entry = storeGetPublic(http->uri, METHOD_GET);
+#endif
     }
     /* Release negatively cached IP-cache entries on reload */
     if (r->flags.nocache)
@@ -2064,10 +2561,17 @@
 	return LOG_TCP_HIT;
     }
 #if HTTP_VIOLATIONS
+#ifdef DSA
+    if (e->p->store_status == STORE_PENDING) {
+	if (r->flags.nocache || r->flags.nocache_hack) {
+	    debug(33, 3) ("Clearing no-cache for STORE_PENDING request\n\t%s\n",
+		storeUrl(e->p));
+#else
     if (e->store_status == STORE_PENDING) {
 	if (r->flags.nocache || r->flags.nocache_hack) {
 	    debug(33, 3) ("Clearing no-cache for STORE_PENDING request\n\t%s\n",
 		storeUrl(e));
+#endif
 	    r->flags.nocache = 0;
 	    r->flags.nocache_hack = 0;
 	}
@@ -2091,7 +2595,11 @@
 	debug(33, 3) ("clientProcessRequest2: complex range MISS\n");
 	http->entry = NULL;
 	return LOG_TCP_MISS;
+#ifdef DSA
+    } else if (clientCheckRangeForceMiss(e->p, r->range)) {
+#else
     } else if (clientCheckRangeForceMiss(e, r->range)) {
+#endif
 	debug(33, 3) ("clientProcessRequest2: forcing miss due to range_offset_limit\n");
 	http->entry = NULL;
 	return LOG_TCP_MISS;
@@ -2122,16 +2630,28 @@
     } else if (r->method == METHOD_TRACE) {
 	if (r->max_forwards == 0) {
 	    http->entry = clientCreateStoreEntry(http, r->method, null_request_flags);
+#ifdef DSA
+	    storeReleaseRequest(http->entry->p);
+	    storeBuffer(http->entry->p);
+#else
 	    storeReleaseRequest(http->entry);
 	    storeBuffer(http->entry);
+#endif
 	    rep = httpReplyCreate();
 	    httpBuildVersion(&version, 1, 0);
 	    httpReplySetHeaders(rep, version, HTTP_OK, NULL, "text/plain",
 		httpRequestPrefixLen(r), 0, squid_curtime);
+#ifdef DSA
+	    httpReplySwapOut(rep, http->entry->p);
+	    httpReplyDestroy(rep);
+	    httpRequestSwapOut(r, http->entry->p);
+	    storeComplete(http->entry->p);
+#else
 	    httpReplySwapOut(rep, http->entry);
 	    httpReplyDestroy(rep);
 	    httpRequestSwapOut(r, http->entry);
 	    storeComplete(http->entry);
+#endif
 	    return;
 	}
 	/* yes, continue */
@@ -2150,15 +2670,27 @@
 	log_tags[http->log_type],
 	http->uri);
     http->out.offset = 0;
+#ifdef DSA
+    if (NULL != http->entry && NULL != http->entry->p) {
+	storeLockObject(http->entry->p);
+	storeCreateMemObject(http->entry->p, http->uri, http->log_uri);
+	http->entry->p->mem_obj->method = r->method;
+	http->sc = storeClientListAdd(http->entry->p, http);
+#else
     if (NULL != http->entry) {
-	payloadLockObject(http->entry->p);
+	storeLockObject(http->entry);
 	storeCreateMemObject(http->entry, http->uri, http->log_uri);
-	http->entry->p->mem_obj->method = r->method;
+	http->entry->mem_obj->method = r->method;
 	http->sc = storeClientListAdd(http->entry, http);
+#endif
 #if DELAY_POOLS
 	delaySetStoreClient(http->sc, delayClient(r));
 #endif
+#ifdef DSA
+	storeClientCopy(http->sc, http->entry->p,
+#else
 	storeClientCopy(http->sc, http->entry,
+#endif
 	    http->out.offset,
 	    http->out.offset,
 	    CLIENT_SOCK_SZ,
@@ -2190,11 +2722,19 @@
 	if (EBIT_TEST(http->entry->flags, ENTRY_SPECIAL)) {
 	    debug(33, 0) ("clientProcessMiss: miss on a special object (%s).\n", url);
 	    debug(33, 0) ("\tlog_type = %s\n", log_tags[http->log_type]);
+#ifdef DSA
+	    storeEntryDump(http->entry->p, 1);
+	}
+	storeUnregister(http->sc, http->entry->p, http);
+	http->sc = NULL;
+	storeUnlockObject(http->entry->p);
+#else
 	    storeEntryDump(http->entry, 1);
 	}
 	storeUnregister(http->sc, http->entry, http);
 	http->sc = NULL;
-	payloadUnlockObject(http->entry->p);
+	storeUnlockObject(http->entry);
+#endif
 	http->entry = NULL;
     }
     if (clientOnlyIfCached(http)) {
@@ -2220,15 +2760,46 @@
 #if LOG_TCP_REDIRECTS
 	http->log_type = LOG_TCP_REDIRECT;
 #endif
+#ifdef DSA
+	storeReleaseRequest(http->entry->p);
+	httpRedirectReply(rep, http->redirect.status, http->redirect.location);
+	httpReplySwapOut(rep, http->entry->p);
+	httpReplyDestroy(rep);
+	storeComplete(http->entry->p);
+#else
 	storeReleaseRequest(http->entry);
 	httpRedirectReply(rep, http->redirect.status, http->redirect.location);
 	httpReplySwapOut(rep, http->entry);
 	httpReplyDestroy(rep);
 	storeComplete(http->entry);
+#endif
 	return;
     }
     if (http->flags.internal)
 	r->protocol = PROTO_INTERNAL;
+#ifdef DTD
+    if (http->request->method == METHOD_GET && !http->request->flags.ims && !http->request->flags.refresh && !http->request->flags.nocache && http->request->flags.cachable) {
+	http->request->flags.was_get = 1;
+	http->old_entry = http->entry;
+	http->old_sc = http->sc;
+	http->entry = instanceCreateEntry(url, http->log_uri, http->request->flags, http->request->method);
+	http->request->method = METHOD_HEAD;
+	http->sc = storeClientListAdd(http->entry->p, http);
+	http->request->lastmod = http->old_entry->lastmod;
+	http->out.offset = 0;
+	fwdStart(http->conn->fd, http->entry, r);
+	if (EBIT_TEST(http->entry->p->flags, ENTRY_ABORTED))
+	   debug(33, 0) ("clientProcessMiss: found ENTRY_ABORTED object\n");
+        storeClientCopy(http->sc, http->entry->p,
+	    http->out.offset,
+	    http->out.offset,
+            CLIENT_SOCK_SZ,
+	    memAllocate(MEM_CLIENT_SOCK_BUF),
+	    clientHandleHEADReply,
+	    http);
+    }
+    else
+#endif
     fwdStart(http->conn->fd, http->entry, r);
 }
 
@@ -2933,7 +3504,11 @@
 clientCheckTransferDone(clientHttpRequest * http)
 {
     int sending = SENDING_BODY;
+#ifdef DSA
+    StoreEntry *entry = http->entry->p;
+#else
     StoreEntry *entry = http->entry;
+#endif
     MemObject *mem;
     http_reply *reply;
     int sendlen;
@@ -2945,7 +3520,6 @@
      */
     if (http->flags.done_copying)
 	return 1;
-    if (entry->p->mem_obj == NULL) return 1;
     /*
      * Handle STORE_OK objects.
      * objectLen(entry) will be set proprely.
@@ -2959,7 +3533,7 @@
     /*
      * Now, handle STORE_PENDING objects
      */
-    mem = entry->p->mem_obj;
+    mem = entry->mem_obj;
     assert(mem != NULL);
     assert(http->request != NULL);
     reply = mem->reply;
@@ -3000,8 +3574,13 @@
 static int
 clientGotNotEnough(clientHttpRequest * http)
 {
+#ifdef DSA
     int cl = httpReplyBodySize(http->request->method, http->entry->p->mem_obj->reply);
     int hs = http->entry->p->mem_obj->reply->hdr_sz;
+#else
+    int cl = httpReplyBodySize(http->request->method, http->entry->mem_obj->reply);
+    int hs = http->entry->mem_obj->reply->hdr_sz;
+#endif
     assert(cl >= 0);
     if (http->out.offset < cl + hs)
 	return 1;
Index: squid/src/defines.h
diff -u squid/src/defines.h:1.3.4.2.8.1 squid/src/defines.h:1.3.4.2.10.1
--- squid/src/defines.h:1.3.4.2.8.1	Wed Aug 14 03:15:32 2002
+++ squid/src/defines.h	Sun Nov 17 21:05:57 2002
@@ -201,9 +201,12 @@
 #define SwapMetaType(x) (char)x[0]
 #define SwapMetaSize(x) &x[sizeof(char)]
 #define SwapMetaData(x) &x[STORE_META_TLD_START]
-#define STORE_HDR_METASIZE (3*sizeof(time_t)+sizeof(u_short))
-#define PAYLOAD_HDR_METASIZE (sizeof(time_t)+2*sizeof(u_short)+sizeof(size_t))
-
+#ifdef DSA
+#define STORE_HDR_METASIZE (sizeof(time_t)+2*sizeof(u_short)+sizeof(size_t))
+#define INSTANCE_HDR_METASIZE (3*sizeof(time_t)+sizeof(u_short))
+#else
+#define STORE_HDR_METASIZE (4*sizeof(time_t)+2*sizeof(u_short)+sizeof(size_t))
+#endif
 #define STORE_ENTRY_WITH_MEMOBJ		1
 #define STORE_ENTRY_WITHOUT_MEMOBJ	0
 
Index: squid/src/disk.c
diff -u squid/src/disk.c:1.4.4.1.8.1 squid/src/disk.c:1.4.4.1.10.1
--- squid/src/disk.c:1.4.4.1.8.1	Wed Aug 14 03:15:32 2002
+++ squid/src/disk.c	Fri Nov 15 21:53:26 2002
@@ -60,8 +60,10 @@
 file_open(const char *path, int mode)
 {
     int fd;
-//    if (mode & O_WRONLY)
-//	mode |= O_APPEND;
+#ifndef DSA
+    if (mode & O_WRONLY)
+	mode |= O_APPEND;
+#endif
     mode |= SQUID_NONBLOCK;
     errno = 0;
     fd = open(path, mode, 0644);
@@ -190,10 +192,14 @@
     debug(6, 3) ("diskHandleWrite: FD %d writing %d bytes\n",
 	fd, (int) (fdd->write_q->len - fdd->write_q->buf_offset));
     errno = 0;
-    if (fdd->write_q->file_offset != -1) 
-	len = lseek(fd, fdd->write_q->file_offset, SEEK_END);
+    if (fdd->write_q->file_offset != -1)
+#ifdef DSA
+	lseek(fd, fdd->write_q->file_offset, SEEK_END);
     else
-	len = lseek(fd, 0, SEEK_END);
+	lseek(fd, 0, SEEK_END);
+#else
+	lseek(fd, fdd->write_q->file_offset, SEEK_SET);
+#endif
     len = write(fd,
 	fdd->write_q->buf + fdd->write_q->buf_offset,
 	fdd->write_q->len - fdd->write_q->buf_offset);
Index: squid/src/enums.h
diff -u squid/src/enums.h:1.5.2.2.6.2 squid/src/enums.h:1.5.2.3.2.3
--- squid/src/enums.h:1.5.2.2.6.2	Wed Aug 14 04:27:28 2002
+++ squid/src/enums.h	Sun Dec  8 22:35:02 2002
@@ -487,6 +487,25 @@
     ENTRY_DONT_LOG		/* hack for gross 'Pump' entries */
 };
 
+#if 0
+typedef enum {
+    S_ENTRY_SPECIAL,
+    S_ENTRY_REVALIDATE,
+    S_DELAY_SENDING,
+    S_RELEASE_REQUEST,
+    S_REFRESH_REQUEST,
+    S_ENTRY_CACHABLE,
+    S_ENTRY_DISPATCHED,
+    S_KEY_PRIVATE, /* SET when we haven't finalized our MD5 */
+    S_ENTRY_FWD_HDR_WAIT,
+    S_ENTRY_NEGCACHED,
+    S_ENTRY_VALIDATED,
+    S_ENTRY_BAD_LENGTH,
+    S_ENTRY_ABORTED,
+    S_ENTRY_DONT_LOG		/* hack for gross 'Pump' entries */
+} store_flags;
+#endif
+
 typedef enum {
     ACCESS_DENIED,
     ACCESS_ALLOWED,
@@ -577,7 +596,6 @@
     MEM_NETDBENTRY,
     MEM_NET_DB_NAME,
     MEM_NET_DB_PEER,
-    MEM_PAYLOADENTRY,
     MEM_PEER,
 #if USE_CACHE_DIGESTS
     MEM_PEER_DIGEST,
@@ -595,6 +613,9 @@
     MEM_STATCOUNTERS,
     MEM_STMEM_BUF,
     MEM_STOREENTRY,
+#ifdef DSA
+    MEM_INSTANCEENTRY,
+#endif
     MEM_STORE_CLIENT,
     MEM_SWAPDIR,
     MEM_USHORTLIST,
Index: squid/src/errorpage.c
diff -u squid/src/errorpage.c:1.4.2.3.8.1 squid/src/errorpage.c:1.4.2.3.10.3
--- squid/src/errorpage.c:1.4.2.3.8.1	Wed Aug 14 03:15:32 2002
+++ squid/src/errorpage.c	Sun Dec  8 22:35:02 2002
@@ -258,10 +258,16 @@
  *            for an error.
  */
 void
+#ifdef DSA
+errorAppendEntry(InstanceEntry * e, ErrorState * err)
+{
+    StoreEntry * entry = e->p;
+#else
 errorAppendEntry(StoreEntry * entry, ErrorState * err)
 {
+#endif
     HttpReply *rep;
-    MemObject *mem = entry->p->mem_obj;
+    MemObject *mem = entry->mem_obj;
     assert(mem != NULL);
     assert(mem->inmem_hi == 0);
     if (entry->store_status != STORE_PENDING) {
@@ -275,7 +281,7 @@
 	errorStateFree(err);
 	return;
     }
-    payloadLockObject(entry->p);
+    storeLockObject(entry);
     storeBuffer(entry);
     rep = errorBuildReply(err);
     /* Add authentication header */
@@ -301,9 +307,14 @@
     EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
     storeBufferFlush(entry);
     storeComplete(entry);
+#ifdef DSA
+    storeNegativeCache(e);
+    storeReleaseRequest(e->p);
+#else
     storeNegativeCache(entry);
     storeReleaseRequest(entry);
-    payloadUnlockObject(entry->p);
+#endif
+    storeUnlockObject(entry);
     errorStateFree(err);
 }
 
Index: squid/src/forward.c
diff -u squid/src/forward.c:1.4.4.1.8.1 squid/src/forward.c:1.4.4.1.10.5.2.5
--- squid/src/forward.c:1.4.4.1.8.1	Wed Aug 14 03:15:32 2002
+++ squid/src/forward.c	Wed Mar 10 22:02:57 2004
@@ -17,8 +17,10 @@
  *  incorporates software developed and/or copyrighted by other
  *  sources; see the CREDITS file for full details.
  *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
+ *  This program is free software; you can redistribute it and/or 
+modify
+ *  it under the terms of the GNU General Public License as published 
+by
  *  the Free Software Foundation; either version 2 of the License, or
  *  (at your option) any later version.
  *  
@@ -29,7 +31,8 @@
  *  
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, 
+USA.
  *
  */
 
@@ -51,7 +54,8 @@
 static STABH fwdAbort;
 
 #define MAX_FWD_STATS_IDX 9
-static int FwdReplyCodes[MAX_FWD_STATS_IDX + 1][HTTP_INVALID_HEADER + 1];
+static int FwdReplyCodes[MAX_FWD_STATS_IDX + 1][HTTP_INVALID_HEADER + 
+1];
 
 #if WIP_FWD_LOG
 static void fwdLog(FwdState * fwdState);
@@ -69,20 +73,32 @@
 static void
 fwdStateFree(FwdState * fwdState)
 {
+#ifdef	DTD
+    const char *host;
+    unsigned short port;
+#endif
+#ifdef DSA	
+    StoreEntry *e = fwdState->entry->p;
+#else    
     StoreEntry *e = fwdState->entry;
+#endif    
     int sfd;
     debug(17, 3) ("fwdStateFree: %p\n", fwdState);
-    assert(e->p->mem_obj != NULL);
+    assert(e->mem_obj);
 #if URL_CHECKSUM_DEBUG
-    assert(e->p->mem_obj->chksum == url_checksum(e->p->mem_obj->url));
+    assert(e->mem_obj->chksum == url_checksum(e->mem_obj->url));
 #endif
 #if WIP_FWD_LOG
     fwdLog(fwdState);
 #endif
     if (e->store_status == STORE_PENDING) {
-	if (e->p->mem_obj->inmem_hi == 0) {
+	if (e->mem_obj->inmem_hi == 0) {
 	    assert(fwdState->err);
+#ifdef DSA
+	    errorAppendEntry(fwdState->entry, fwdState->err);
+#else
 	    errorAppendEntry(e, fwdState->err);
+#endif
 	    fwdState->err = NULL;
 	} else {
 	    EBIT_CLR(e->flags, ENTRY_FWD_HDR_WAIT);
@@ -93,19 +109,46 @@
     if (storePendingNClients(e) > 0)
 	assert(!EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT));
     fwdServersFree(&fwdState->servers);
+#ifdef	DTD
+    host = fwdState->request->host;
+    port = fwdState->request->port;
+#endif
     requestUnlink(fwdState->request);
     fwdState->request = NULL;
     if (fwdState->err)
 	errorStateFree(fwdState->err);
+#ifdef DTD
+    if (fwdState->entry && !EBIT_TEST(fwdState->entry->p->flags, 
+ENTRY_FWD_HDR_WAIT) && !EBIT_TEST(fwdState->entry->flags, RELEASE_REQUEST)) 
+{   
+	StoreEntry * p = NULL;
+	StoreEntry * op = fwdState->entry->p;
+        p = storeGet(op->hash.key);
+	if (p == op) storeLockObject(p);	
+	if (p && p != op && storeValidToSend(p)) {
+	    arrayDelete(op->instances, fwdState->entry);
+	    fwdState->entry->p->swap_file_sz = -1;
+	    fwdState->entry->p->swap_filen = -1;
+	    fwdState->entry->p->swap_dirn = -1;
+	    fwdState->entry->p = p;
+	    storeSetPublicKey(fwdState->entry);
+	    storeLockObject(p);
+	}
+    }
+#endif
     storeUnregisterAbort(e);
-    payloadUnlockObject(e->p);
+    storeUnlockObject(e);
     fwdState->entry = NULL;
     sfd = fwdState->server_fd;
     if (sfd > -1) {
 	comm_remove_close_handler(sfd, fwdServerClosed, fwdState);
 	fwdState->server_fd = -1;
 	debug(17, 3) ("fwdStateFree: closing FD %d\n", sfd);
+#ifdef	DTD
+	pconnPush(sfd, host, port);
+#else
 	comm_close(sfd);
+#endif
     }
     cbdataFree(fwdState);
 }
@@ -113,9 +156,15 @@
 static int
 fwdCheckRetry(FwdState * fwdState)
 {
-    if (fwdState->entry->store_status != STORE_PENDING)
+#ifdef DSA	
+    if (fwdState->entry->p->store_status != STORE_PENDING)
 	return 0;
     if (fwdState->entry->p->mem_obj->inmem_hi > 0)
+#else	    
+    if (fwdState->entry->store_status != STORE_PENDING)
+	return 0;
+    if (fwdState->entry->mem_obj->inmem_hi > 0)
+#endif	    
 	return 0;
     if (fwdState->n_tries > 10)
 	return 0;
@@ -133,7 +182,13 @@
 fwdServerClosed(int fd, void *data)
 {
     FwdState *fwdState = data;
-    debug(17, 2) ("fwdServerClosed: FD %d %s\n", fd, storeUrl(fwdState->entry));
+#ifdef DSA    
+    debug(17, 2) ("fwdServerClosed: FD %d %s\n", fd, 
+storeUrl(fwdState->entry->p));
+#else    
+    debug(17, 2) ("fwdServerClosed: FD %d %s\n", fd, 
+storeUrl(fwdState->entry));
+#endif    
     assert(fwdState->server_fd == fd);
     fwdState->server_fd = -1;
     if (fwdCheckRetry(fwdState)) {
@@ -206,14 +261,26 @@
 	    peerConnectFailed(fs->peer);
 	comm_close(server_fd);
     } else {
-	debug(17, 3) ("fwdConnectDone: FD %d: '%s'\n", server_fd, storeUrl(fwdState->entry));
+#ifdef DSA	    
+	debug(17, 3) ("fwdConnectDone: FD %d: '%s'\n", server_fd, 
+storeUrl(fwdState->entry->p));
+#else	
+	debug(17, 3) ("fwdConnectDone: FD %d: '%s'\n", server_fd, 
+storeUrl(fwdState->entry));
+#endif	
 	if (fs->peer)
-	    hierarchyNote(&fwdState->request->hier, fs->code, fs->peer->host);
+	    hierarchyNote(&fwdState->request->hier, fs->code, 
+fs->peer->host);
 	else if (Config.onoff.log_ip_on_direct)
-	    hierarchyNote(&fwdState->request->hier, fs->code, fd_table[server_fd].ipaddr);
+	    hierarchyNote(&fwdState->request->hier, fs->code, 
+fd_table[server_fd].ipaddr);
 	else
 	    hierarchyNote(&fwdState->request->hier, fs->code, request->host);
+#ifdef DSA	
+	fd_note(server_fd, storeUrl(fwdState->entry->p));
+#else	
 	fd_note(server_fd, storeUrl(fwdState->entry));
+#endif	
 	fd_table[server_fd].uses++;
 	if (fs->peer)
 	    peerConnectSucceded(fs->peer);
@@ -226,11 +293,16 @@
 fwdConnectTimeout(int fd, void *data)
 {
     FwdState *fwdState = data;
+#ifdef DSA    
+    StoreEntry *entry = fwdState->entry->p;
+#else    
     StoreEntry *entry = fwdState->entry;
+#endif    
     ErrorState *err;
-    debug(17, 2) ("fwdConnectTimeout: FD %d: '%s'\n", fd, storeUrl(entry));
+    debug(17, 2) ("fwdConnectTimeout: FD %d: '%s'\n", fd, 
+storeUrl(entry));
     assert(fd == fwdState->server_fd);
-    if (entry->p->mem_obj->inmem_hi == 0) {
+    if (entry->mem_obj->inmem_hi == 0) {
 	err = errorCon(ERR_CONNECT_FAIL, HTTP_GATEWAY_TIMEOUT);
 	err->request = requestLink(fwdState->request);
 	err->xerrno = ETIMEDOUT;
@@ -249,7 +321,11 @@
 fwdConnectStart(void *data)
 {
     FwdState *fwdState = data;
+#ifdef DSA    
+    const char *url = storeUrl(fwdState->entry->p);
+#else    
     const char *url = storeUrl(fwdState->entry);
+#endif    
     int fd;
     ErrorState *err;
     FwdServer *fs = fwdState->servers;
@@ -283,7 +359,7 @@
 	return;
     }
 #if URL_CHECKSUM_DEBUG
-    assert(fwdState->entry->p->mem_obj->chksum == url_checksum(url));
+    assert(fwdState->entry->mem_obj->chksum == url_checksum(url));
 #endif
     fd = comm_open(SOCK_STREAM,
 	0,
@@ -314,7 +390,13 @@
 fwdStartComplete(FwdServer * servers, void *data)
 {
     FwdState *fwdState = data;
-    debug(17, 3) ("fwdStartComplete: %s\n", storeUrl(fwdState->entry));
+#ifdef DSA    
+    debug(17, 3) ("fwdStartComplete: %s\n", 
+storeUrl(fwdState->entry->p));
+#else   
+    debug(17, 3) ("fwdStartComplete: %s\n", 
+storeUrl(fwdState->entry));
+#endif    
     if (servers != NULL) {
 	fwdState->servers = servers;
 	fwdConnectStart(fwdState);
@@ -327,7 +409,11 @@
 fwdStartFail(FwdState * fwdState)
 {
     ErrorState *err;
+#ifdef DSA    
+    debug(17, 3) ("fwdStartFail: %s\n", storeUrl(fwdState->entry->p));
+#else    
     debug(17, 3) ("fwdStartFail: %s\n", storeUrl(fwdState->entry));
+#endif    
     err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
     err->request = requestLink(fwdState->request);
     err->xerrno = errno;
@@ -340,7 +426,11 @@
 {
     peer *p;
     request_t *request = fwdState->request;
+#ifdef DSA    
+    StoreEntry *entry = fwdState->entry->p;
+#else    
     StoreEntry *entry = fwdState->entry;
+#endif    
     ErrorState *err;
     debug(17, 3) ("fwdDispatch: FD %d: Fetching '%s %s'\n",
 	fwdState->client_fd,
@@ -348,11 +438,16 @@
 	storeUrl(entry));
     /*assert(!EBIT_TEST(entry->flags, ENTRY_DISPATCHED)); */
     assert(entry->ping_status != PING_WAITING);
-    assert(entry->p->lock_count);
+    assert(entry->lock_count);
+#ifdef DSA
+    EBIT_SET(fwdState->entry->flags, ENTRY_DISPATCHED);
+#else
     EBIT_SET(entry->flags, ENTRY_DISPATCHED);
+#endif
     netdbPingSite(request->host);
     /*
-     * Assert that server_fd is set.  This is to guarantee that fwdState
+     * Assert that server_fd is set.  This is to guarantee that 
+fwdState
      * is attached to something and will be deallocated when server_fd
      * is closed.
      */
@@ -409,15 +504,26 @@
 static int
 fwdReforward(FwdState * fwdState)
 {
+#ifdef DSA	
+    StoreEntry *e = fwdState->entry->p;
+#else    
     StoreEntry *e = fwdState->entry;
+#endif    
     FwdServer *fs = fwdState->servers;
     http_status s;
     assert(e->store_status == STORE_PENDING);
-    assert(e->p->mem_obj);
+    assert(e->mem_obj);
 #if URL_CHECKSUM_DEBUG
-    assert(e->p->mem_obj->chksum == url_checksum(e->p->mem_obj->url));
+    assert(e->mem_obj->chksum == url_checksum(e->mem_obj->url));
 #endif
     debug(17, 3) ("fwdReforward: %s?\n", storeUrl(e));
+#ifdef DTD
+    if (fwdState->entry->p->mem_obj->swapout.sio == NULL && 
+fwdState->request->flags.was_get == 1 && fwdState->request->method == 
+METHOD_HEAD) {
+	return 1;
+    }
+#endif
     if (!EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT)) {
 	debug(17, 3) ("fwdReforward: No, ENTRY_FWD_HDR_WAIT isn't set\n");
 	return 0;
@@ -434,7 +540,7 @@
 	debug(17, 3) ("fwdReforward: No forward-servers left\n");
 	return 0;
     }
-    s = e->p->mem_obj->reply->sline.status;
+    s = e->mem_obj->reply->sline.status;
     debug(17, 3) ("fwdReforward: status %d\n", (int) s);
     return fwdReforwardableStatus(s);
 }
@@ -452,7 +558,11 @@
 }
 
 void
+#ifdef DSA
+fwdStart(int fd, InstanceEntry * e, request_t * r)
+#else	
 fwdStart(int fd, StoreEntry * e, request_t * r)
+#endif	
 {
     FwdState *fwdState;
     aclCheck_t ch;
@@ -465,7 +575,8 @@
      */
     if (r->client_addr.s_addr != no_addr.s_addr) {
 	/*      
-	 * Check if this host is allowed to fetch MISSES from us (miss_access)
+	 * Check if this host is allowed to fetch MISSES from us 
+(miss_access)
 	 */
 	memset(&ch, '\0', sizeof(aclCheck_t));
 	ch.src_addr = r->client_addr;
@@ -481,11 +592,17 @@
 	    return;
 	}
     }
-    debug(17, 3) ("fwdStart: '%s'\n", storeUrl(e));
+#ifdef DSA
+    debug(17, 3) ("fwdStart: '%s'\n", storeUrl(e->p));
     e->p->mem_obj->request = requestLink(r);
     e->p->mem_obj->fd = fd;
+#else    
+    debug(17, 3) ("fwdStart: '%s'\n", storeUrl(e));
+    e->mem_obj->request = requestLink(r);
+    e->mem_obj->fd = fd;
+#endif    
 #if URL_CHECKSUM_DEBUG
-    assert(e->p->mem_obj->chksum == url_checksum(e->p->mem_obj->url));
+    assert(e->mem_obj->chksum == url_checksum(e->mem_obj->url));
 #endif
     if (shutting_down) {
 	/* more yuck */
@@ -517,9 +634,15 @@
     fwdState->server_fd = -1;
     fwdState->request = requestLink(r);
     fwdState->start = squid_curtime;
-    payloadLockObject(e->p);
+#ifdef DSA    
+    storeLockObject(e->p);
+    EBIT_SET(e->p->flags, ENTRY_FWD_HDR_WAIT);
+    storeRegisterAbort(e->p, fwdAbort, fwdState);
+#else    
+    storeLockObject(e);
     EBIT_SET(e->flags, ENTRY_FWD_HDR_WAIT);
     storeRegisterAbort(e, fwdAbort, fwdState);
+#endif    
     peerSelect(r, e, fwdStartComplete, fwdState);
 }
 
@@ -527,12 +650,12 @@
 fwdCheckDeferRead(int fd, void *data)
 {
     StoreEntry *e = data;
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     int rc = 0;
     if (mem == NULL)
 	return 0;
 #if URL_CHECKSUM_DEBUG
-    assert(e->p->mem_obj->chksum == url_checksum(e->p->mem_obj->url));
+    assert(e->mem_obj->chksum == url_checksum(e->mem_obj->url));
 #endif
 #if DELAY_POOLS
     if (fd < 0)
@@ -552,7 +675,8 @@
 #endif
     if (EBIT_TEST(e->flags, ENTRY_FWD_HDR_WAIT))
 	return rc;
-    if (mem->inmem_hi - storeLowestMemReaderOffset(e) < READ_AHEAD_GAP)
+    if (mem->inmem_hi - storeLowestMemReaderOffset(e) < 
+READ_AHEAD_GAP)
 	return rc;
     return 1;
 }
@@ -560,11 +684,19 @@
 void
 fwdFail(FwdState * fwdState, ErrorState * errorState)
 {
+#ifdef DSA
+    assert(EBIT_TEST(fwdState->entry->p->flags, ENTRY_FWD_HDR_WAIT));
+#else
     assert(EBIT_TEST(fwdState->entry->flags, ENTRY_FWD_HDR_WAIT));
+#endif
     debug(17, 3) ("fwdFail: %s \"%s\"\n\t%s\n",
 	err_type_str[errorState->type],
 	httpStatusString(errorState->http_status),
+#ifdef DSA	
+	storeUrl(fwdState->entry->p));
+#else    
 	storeUrl(fwdState->entry));
+#endif	
     if (fwdState->err)
 	errorStateFree(fwdState->err);
     fwdState->err = errorState;
@@ -577,7 +709,11 @@
 fwdAbort(void *data)
 {
     FwdState *fwdState = data;
+#ifdef DSA    
+    debug(17, 2) ("fwdAbort: %s\n", storeUrl(fwdState->entry->p));
+#else    
     debug(17, 2) ("fwdAbort: %s\n", storeUrl(fwdState->entry));
+#endif    
     fwdStateFree(fwdState);
 }
 
@@ -587,7 +723,12 @@
 void
 fwdUnregister(int fd, FwdState * fwdState)
 {
+#ifdef DSA
+    debug(17, 3) ("fwdUnregister: %s\n", 
+storeUrl(fwdState->entry->p));
+#else   
     debug(17, 3) ("fwdUnregister: %s\n", storeUrl(fwdState->entry));
+#endif    
     assert(fd = fwdState->server_fd);
     assert(fd > -1);
     comm_remove_close_handler(fd, fwdServerClosed, fwdState);
@@ -603,25 +744,37 @@
 void
 fwdComplete(FwdState * fwdState)
 {
+#ifdef DSA	
+    StoreEntry *e = fwdState->entry->p;
+#else    
     StoreEntry *e = fwdState->entry;
+#endif
     assert(e->store_status == STORE_PENDING);
     debug(17, 3) ("fwdComplete: %s\n\tstatus %d\n", storeUrl(e),
-	e->p->mem_obj->reply->sline.status);
+	e->mem_obj->reply->sline.status);
 #if URL_CHECKSUM_DEBUG
-    assert(e->p->mem_obj->chksum == url_checksum(e->p->mem_obj->url));
+    assert(e->mem_obj->chksum == url_checksum(e->mem_obj->url));
 #endif
-    fwdLogReplyStatus(fwdState->n_tries, e->p->mem_obj->reply->sline.status);
+    fwdLogReplyStatus(fwdState->n_tries, 
+e->mem_obj->reply->sline.status);
     if (fwdReforward(fwdState)) {
 	debug(17, 3) ("fwdComplete: re-forwarding %d %s\n",
-	    e->p->mem_obj->reply->sline.status,
+	    e->mem_obj->reply->sline.status,
 	    storeUrl(e));
 	if (fwdState->server_fd > -1)
 	    fwdUnregister(fwdState->server_fd, fwdState);
+#ifdef DTD
+	if (fwdState->request->flags.was_get == 1) {
+	    fwdState->request->method = METHOD_GET;
+	    fwdState->request->flags.was_get = 0;
+	    fwdState->request->flags.hierarchical = 1;
+	}
+#endif
 	storeEntryReset(e);
 	fwdStartComplete(fwdState->servers, fwdState);
     } else {
 	debug(17, 3) ("fwdComplete: not re-forwarding status %d\n",
-	    e->p->mem_obj->reply->sline.status);
+	    e->mem_obj->reply->sline.status);
 	EBIT_CLR(e->flags, ENTRY_FWD_HDR_WAIT);
 	storeComplete(e);
 	/*
Index: squid/src/ftp.c
diff -u squid/src/ftp.c:1.4.2.6.2.2 squid/src/ftp.c:1.4.2.7.2.4
--- squid/src/ftp.c:1.4.2.6.2.2	Wed Aug 14 04:27:28 2002
+++ squid/src/ftp.c	Sun Dec 15 02:29:41 2002
@@ -81,7 +81,11 @@
 };
 
 typedef struct _Ftpdata {
+#ifdef DSA	
+    InstanceEntry *entry;
+#else    
     StoreEntry *entry;
+#endif    
     request_t *request;
     char user[MAX_URL];
     char password[MAX_URL];
@@ -265,9 +269,15 @@
     FtpStateData *ftpState = data;
     if (ftpState == NULL)
 	return;
+#ifdef DSA    
+    debug(9, 3) ("ftpStateFree: %s\n", storeUrl(ftpState->entry->p));
+    storeUnregisterAbort(ftpState->entry->p);
+    storeUnlockObject(ftpState->entry->p);
+#else
     debug(9, 3) ("ftpStateFree: %s\n", storeUrl(ftpState->entry));
     storeUnregisterAbort(ftpState->entry);
-    payloadUnlockObject(ftpState->entry->p);
+    storeUnlockObject(ftpState->entry);
+#endif
     if (ftpState->reply_hdr) {
 	memFree(ftpState->reply_hdr, MEM_8K_BUF);
 	/* this seems unnecessary, but people report SEGV's
@@ -335,8 +345,13 @@
 ftpTimeout(int fd, void *data)
 {
     FtpStateData *ftpState = data;
+#ifdef DSA    
+    InstanceEntry *entry = ftpState->entry;
+    debug(9, 4) ("ftpTimeout: FD %d: '%s'\n", fd, storeUrl(entry->p));
+#else    
     StoreEntry *entry = ftpState->entry;
     debug(9, 4) ("ftpTimeout: FD %d: '%s'\n", fd, storeUrl(entry));
+#endif    
     if (SENT_PASV == ftpState->state && fd == ftpState->data.fd) {
 	/* stupid ftp.netscape.com */
 	ftpState->fwd->flags.dont_retry = 0;
@@ -350,7 +365,11 @@
 static void
 ftpListingStart(FtpStateData * ftpState)
 {
+#ifdef DSA	
+    StoreEntry *e = ftpState->entry->p;
+#else    
     StoreEntry *e = ftpState->entry;
+#endif    
     wordlist *w;
     char *dirup;
     int i, j, k;
@@ -414,7 +433,11 @@
 static void
 ftpListingFinish(FtpStateData * ftpState)
 {
+#ifdef DSA	
+    StoreEntry *e = ftpState->entry->p;
+#else    
     StoreEntry *e = ftpState->entry;
+#endif    
     storeBuffer(e);
     storeAppendPrintf(e, "</PRE>\n");
     if (ftpState->flags.listformat_unknown && !ftpState->flags.tried_nlst) {
@@ -803,7 +826,11 @@
     char *t;
     size_t linelen;
     size_t usable;
+#ifdef DSA    
+    StoreEntry *e = ftpState->entry->p;
+#else    
     StoreEntry *e = ftpState->entry;
+#endif    
     int len = ftpState->data.offset;
     /*
      * We need a NULL-terminated buffer for scanning, ick
@@ -880,8 +907,12 @@
     int len;
     int j;
     int bin;
+#ifdef DSA    
+    StoreEntry *entry = ftpState->entry->p;
+#else    
     StoreEntry *entry = ftpState->entry;
-    MemObject *mem = entry->p->mem_obj;
+#endif    
+    MemObject *mem = entry->mem_obj;
     size_t read_sz;
 #if DELAY_POOLS
     delay_id delay_id = delayMostBytesAllowed(mem);
@@ -1053,20 +1084,29 @@
 ftpStart(FwdState * fwd)
 {
     request_t *request = fwd->request;
-    StoreEntry *entry = fwd->entry;
     int fd = fwd->server_fd;
     LOCAL_ARRAY(char, realm, 8192);
+#ifdef DSA    
+    StoreEntry *entry = fwd->entry->p;
+    InstanceEntry *pe = NULL;
+#else    
+    StoreEntry *entry = fwd->entry;
+    StoreEntry *pe = NULL;
+#endif    
     const char *url = storeUrl(entry);
     FtpStateData *ftpState = xcalloc(1, sizeof(FtpStateData));
     HttpReply *reply;
-    StoreEntry *pe = NULL;
     const cache_key *key = NULL;
     cbdataAdd(ftpState, cbdataXfree, 0);
     debug(9, 3) ("ftpStart: '%s'\n", url);
     statCounter.server.all.requests++;
     statCounter.server.ftp.requests++;
-    payloadLockObject(entry->p);
+    storeLockObject(entry);
+#ifdef DSA    
+    ftpState->entry = fwd->entry;
+#else    
     ftpState->entry = entry;
+#endif    
     ftpState->request = requestLink(request);
     ftpState->ctrl.fd = fd;
     ftpState->data.fd = -1;
@@ -1092,11 +1132,16 @@
 		ftpState->user, request->port);
 	}
 	/* eject any old cached object */
-	key = storeKeyPublic(entry->p->mem_obj->url, entry->p->mem_obj->method);
+	key = storeKeyPublic(entry->mem_obj->url, entry->mem_obj->method);
+#ifdef DSA	
+	if ((pe = instanceGet(key)) != NULL)
+	    storeRelease(pe->p);
+#else		
 	if ((pe = storeGet(key)) != NULL)
 	    storeRelease(pe);
+#endif		
 	/* create reply */
-	reply = entry->p->mem_obj->reply;
+	reply = entry->mem_obj->reply;
 	assert(reply != NULL);
 	/* create appropriate reply */
 	ftpAuthRequired(reply, request, realm);
@@ -1253,7 +1298,11 @@
 ftpReadControlReply(int fd, void *data)
 {
     FtpStateData *ftpState = data;
+#ifdef DSA    
+    StoreEntry *entry = ftpState->entry->p;
+#else
     StoreEntry *entry = ftpState->entry;
+#endif    
     int len;
     debug(9, 5) ("ftpReadControlReply\n");
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
@@ -1674,7 +1723,11 @@
 	 * ftpReadControlReply() and before here, probably when
 	 * trying to write to the client.
 	 */
+#ifdef DSA
+	if (!EBIT_TEST(ftpState->entry->p->flags, ENTRY_ABORTED))
+#else
 	if (!EBIT_TEST(ftpState->entry->flags, ENTRY_ABORTED))
+#endif
 	    fwdComplete(ftpState->fwd);
 	ftpSendQuit(ftpState);
 	return;
@@ -1706,7 +1759,11 @@
 	addr.sin_addr,
 	0,
 	COMM_NONBLOCKING,
+#ifdef DSA	
+	storeUrl(ftpState->entry->p));
+#else    
 	storeUrl(ftpState->entry));
+#endif	
     debug(9, 3) ("ftpSendPasv: Unconnected data socket created on FD %d\n", fd);
     if (fd < 0) {
 	ftpFail(ftpState);
@@ -1851,7 +1908,11 @@
 	addr.sin_addr,
 	port,
 	COMM_NONBLOCKING | (fallback ? COMM_REUSEADDR : 0),
+#ifdef DSA	
+	storeUrl(ftpState->entry->p));
+#else    
 	storeUrl(ftpState->entry));
+#endif	
     debug(9, 3) ("ftpOpenListenSocket: Unconnected data socket created on FD %d\n", fd);
     if (fd < 0) {
 	debug(9, 0) ("ftpOpenListenSocket: comm_open failed\n");
@@ -1914,8 +1975,11 @@
     FtpStateData *ftpState = data;
     struct sockaddr_in my_peer, me;
     debug(9, 3) ("ftpAcceptDataConnection\n");
-
+#ifdef DSA
+    if (EBIT_TEST(ftpState->entry->p->flags, ENTRY_ABORTED)) {
+#else
     if (EBIT_TEST(ftpState->entry->flags, ENTRY_ABORTED)) {
+#endif
 	comm_close(ftpState->ctrl.fd);
 	return;
     }
@@ -2354,8 +2418,12 @@
 static void
 ftpFailed(FtpStateData * ftpState, err_type error)
 {
+#ifdef DSA	
+    StoreEntry *entry = ftpState->entry->p;
+#else    
     StoreEntry *entry = ftpState->entry;
-    if (entry->p->mem_obj->inmem_hi == 0)
+#endif    
+    if (entry->mem_obj->inmem_hi == 0)
 	ftpFailedErrorMessage(ftpState, error);
     if (ftpState->data.fd > -1) {
 	comm_close(ftpState->data.fd);
@@ -2470,7 +2538,11 @@
     http_status http_code;
     err_type err_code = ERR_NONE;
     debug(9, 5) ("ftpSendReply: %s, code %d\n",
+#ifdef DSA		    
+	storeUrl(ftpState->entry->p), code);
+#else    
 	storeUrl(ftpState->entry), code);
+#endif	
     if (cbdataValid(ftpState))
 	debug(9, 5) ("ftpSendReply: ftpState (%p) is valid!\n", ftpState);
     if (code == 226) {
@@ -2496,7 +2568,11 @@
     else
 	err->ftp.reply = xstrdup("");
     errorAppendEntry(ftpState->entry, err);
+#ifdef DSA    
+    storeBufferFlush(ftpState->entry->p);
+#else    
     storeBufferFlush(ftpState->entry);
+#endif    
     ftpSendQuit(ftpState);
 }
 
@@ -2508,14 +2584,19 @@
     String urlpath = ftpState->request->urlpath;
     const char *filename = NULL;
     const char *t = NULL;
+#ifdef DSA    
+    StoreEntry *e = ftpState->entry->p;
+    InstanceEntry *pe = NULL;
+#else    
     StoreEntry *e = ftpState->entry;
     StoreEntry *pe = NULL;
-    http_reply *reply = e->p->mem_obj->reply;
+#endif    
+    http_reply *reply = e->mem_obj->reply;
     http_version_t version;
     if (ftpState->flags.http_header_sent)
 	return;
     ftpState->flags.http_header_sent = 1;
-    assert(e->p->mem_obj->inmem_hi == 0);
+    assert(e->mem_obj->inmem_hi == 0);
     EBIT_CLR(e->flags, ENTRY_FWD_HDR_WAIT);
     filename = (t = strRChr(urlpath, '/')) ? t + 1 : strBuf(urlpath);
     if (ftpState->flags.isdir) {
@@ -2558,21 +2639,38 @@
 	httpHeaderPutStr(&reply->header, HDR_CONTENT_ENCODING, mime_enc);
     httpReplySwapOut(reply, e);
     storeBufferFlush(e);
-    reply->hdr_sz = e->p->mem_obj->inmem_hi;
+    reply->hdr_sz = e->mem_obj->inmem_hi;
+#ifdef DSA    
+    storeTimestampsSet(ftpState->entry);
+#else    
     storeTimestampsSet(e);
+#endif    
     if (ftpState->flags.authenticated) {
 	/*
 	 * Authenticated requests can't be cached. Eject any old cached
 	 * object
 	 */
-	pe = storeGetPublic(e->p->mem_obj->url, e->p->mem_obj->method);
+#ifdef DSA	
+	pe = instanceGetPublic(e->mem_obj->url, e->mem_obj->method);
+	if (pe)
+	    instanceRelease(pe);
+	instanceRelease(ftpState->entry);
+#else	
+	pe = storeGetPublic(e->mem_obj->url, e->mem_obj->method);
 	if (pe)
 	    storeRelease(pe);
 	storeRelease(e);
+#endif	
     } else if (EBIT_TEST(e->flags, ENTRY_CACHABLE) && !ftpState->restarted_offset) {
+#ifdef DSA
+	storeSetPublicKey(ftpState->entry);
+    } else {
+	instanceRelease(ftpState->entry);
+#else	
 	storeSetPublicKey(e);
     } else {
 	storeRelease(e);
+#endif	
     }
 }
 
Index: squid/src/globals.h
diff -u squid/src/globals.h:1.4.2.2.8.1 squid/src/globals.h:1.4.2.2.10.1
--- squid/src/globals.h:1.4.2.2.8.1	Wed Aug 14 03:15:33 2002
+++ squid/src/globals.h	Fri Nov 15 01:10:34 2002
@@ -125,8 +125,9 @@
 extern double current_dtime;
 extern int store_hash_buckets;	/* 0 */
 extern hash_table *store_table;	/* NULL */
-extern int payload_hash_buckets;	/* 0 */
-extern hash_table *payload_table;	/* NULL */
+#ifdef DSA
+extern hash_table *instance_table;	/* NULL */
+#endif
 extern dlink_list ClientActiveRequests;
 extern const String StringNull;	/* { 0, 0, NULL } */
 extern const MemBuf MemBufNull;	/* MemBufNULL */
@@ -148,7 +149,7 @@
 extern int store_open_disk_fd;	/* 0 */
 extern const char *SwapDirType[];
 extern storefs_entry_t *storefs_list;	/* NULL */
-extern payloadrepl_entry_t *payloadrepl_list;	/* NULL */
+extern storerepl_entry_t *storerepl_list;	/* NULL */
 extern int store_swap_low;	/* 0 */
 extern int store_swap_high;	/* 0 */
 extern int store_pages_max;	/* 0 */
Index: squid/src/gopher.c
diff -u squid/src/gopher.c:1.4.2.2.8.2 squid/src/gopher.c:1.4.2.3.2.2
--- squid/src/gopher.c:1.4.2.2.8.2	Wed Aug 14 04:27:28 2002
+++ squid/src/gopher.c	Sun Dec  8 11:26:50 2002
@@ -67,7 +67,11 @@
 #define MAX_CSO_RESULT      1024
 
 typedef struct gopher_ds {
+#ifdef DSA	
+    InstanceEntry *entry;
+#else    
     StoreEntry *entry;
+#endif    
     enum {
 	NORMAL,
 	HTML_DIR,
@@ -111,8 +115,13 @@
     GopherStateData *gopherState = data;
     if (gopherState == NULL)
 	return;
+#ifdef DSA    
+    if (gopherState->entry && gopherState->entry->p) {
+	storeUnlockObject(gopherState->entry->p);
+#else	
     if (gopherState->entry) {
-	payloadUnlockObject(gopherState->entry->p);
+	storeUnlockObject(gopherState->entry);
+#endif	
     }
     if (gopherState->req) {
 	requestUnlink(gopherState->req);
@@ -187,7 +196,11 @@
     }
     memBufPrintf(&mb, "\r\n");
     EBIT_CLR(gopherState->entry->flags, ENTRY_FWD_HDR_WAIT);
+#ifdef DSA    
+    storeAppend(gopherState->entry->p, mb.buf, mb.size);
+#else    
     storeAppend(gopherState->entry, mb.buf, mb.size);
+#endif    
     memBufClean(&mb);
 }
 
@@ -242,7 +255,11 @@
 gopherEndHTML(GopherStateData * gopherState)
 {
     if (!gopherState->data_in)
+#ifdef DSA	    
+	storeAppendPrintf(gopherState->entry->p,
+#else			
 	storeAppendPrintf(gopherState->entry,
+#endif		
 	    "<HTML><HEAD><TITLE>Server Return Nothing.</TITLE>\n"
 	    "</HEAD><BODY><HR><H1>Server Return Nothing.</H1></BODY></HTML>\n");
 }
@@ -270,9 +287,11 @@
 
     memset(tmpbuf, '\0', TEMP_BUF_SIZE);
     memset(line, '\0', TEMP_BUF_SIZE);
-
+#ifdef DSA
+    entry = gopherState->entry->p;
+#else    
     entry = gopherState->entry;
-
+#endif
     if (gopherState->conversion == HTML_INDEX_PAGE) {
 	char *html_url = html_quote(storeUrl(entry));
 	storeAppendPrintf(entry,
@@ -576,10 +595,14 @@
 gopherTimeout(int fd, void *data)
 {
     GopherStateData *gopherState = data;
+#ifdef DSA    
+    StoreEntry *entry = gopherState->entry->p;
+#else    
     StoreEntry *entry = gopherState->entry;
+#endif    
     debug(10, 4) ("gopherTimeout: FD %d: '%s'\n", fd, storeUrl(entry));
     if (entry->store_status == STORE_PENDING) {
-	if (entry->p->mem_obj->inmem_hi == 0) {
+	if (entry->mem_obj->inmem_hi == 0) {
 	    fwdFail(gopherState->fwdState,
 		errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT));
 	}
@@ -593,14 +616,18 @@
 gopherReadReply(int fd, void *data)
 {
     GopherStateData *gopherState = data;
+#ifdef DSA    
+    StoreEntry *entry = gopherState->entry->p;
+#else    
     StoreEntry *entry = gopherState->entry;
+#endif    
     char *buf = NULL;
     int len;
     int clen;
     int bin;
     size_t read_sz;
 #if DELAY_POOLS
-    delay_id delay_id = delayMostBytesAllowed(entry->p->mem_obj);
+    delay_id delay_id = delayMostBytesAllowed(entry->mem_obj);
 #endif
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
 	comm_close(fd);
@@ -635,29 +662,41 @@
 	debug(50, 1) ("gopherReadReply: error reading: %s\n", xstrerror());
 	if (ignoreErrno(errno)) {
 	    commSetSelect(fd, COMM_SELECT_READ, gopherReadReply, data, 0);
-	} else if (entry->p->mem_obj->inmem_hi == 0) {
+	} else if (entry->mem_obj->inmem_hi == 0) {
 	    ErrorState *err;
 	    err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
 	    err->xerrno = errno;
 	    err->url = xstrdup(storeUrl(entry));
+#ifdef DSA
+	    errorAppendEntry(gopherState->entry, err);
+#else
 	    errorAppendEntry(entry, err);
+#endif
 	    comm_close(fd);
 	} else {
 	    comm_close(fd);
 	}
-    } else if (len == 0 && entry->p->mem_obj->inmem_hi == 0) {
+    } else if (len == 0 && entry->mem_obj->inmem_hi == 0) {
 	ErrorState *err;
 	err = errorCon(ERR_ZERO_SIZE_OBJECT, HTTP_SERVICE_UNAVAILABLE);
 	err->xerrno = errno;
 	err->url = xstrdup(gopherState->request);
+#ifdef DSA
+	errorAppendEntry(gopherState->entry, err);
+#else
 	errorAppendEntry(entry, err);
+#endif
 	comm_close(fd);
     } else if (len == 0) {
 	/* Connection closed; retrieval done. */
 	/* flush the rest of data in temp buf if there is one. */
 	if (gopherState->conversion != NORMAL)
 	    gopherEndHTML(data);
+#ifdef DSA	
+	storeTimestampsSet(gopherState->entry);
+#else	
 	storeTimestampsSet(entry);
+#endif	
 	storeBufferFlush(entry);
 	fwdComplete(gopherState->fwdState);
 	comm_close(fd);
@@ -682,7 +721,11 @@
 gopherSendComplete(int fd, char *buf, size_t size, int errflag, void *data)
 {
     GopherStateData *gopherState = (GopherStateData *) data;
+#ifdef DSA    
+    StoreEntry *entry = gopherState->entry->p;
+#else    
     StoreEntry *entry = gopherState->entry;
+#endif    
     debug(10, 5) ("gopherSendComplete: FD %d size: %d errflag: %d\n",
 	fd, size, errflag);
     if (size > 0) {
@@ -697,7 +740,11 @@
 	err->host = xstrdup(gopherState->req->host);
 	err->port = gopherState->req->port;
 	err->url = xstrdup(storeUrl(entry));
+#ifdef DSA
+	errorAppendEntry(gopherState->entry, err);
+#else
 	errorAppendEntry(entry, err);
+#endif
 	comm_close(fd);
 	if (buf)
 	    memFree(buf, MEM_4K_BUF);	/* Allocated by gopherSendRequest. */
@@ -766,7 +813,11 @@
 	gopherSendComplete,
 	data,
 	memFree4K);
+#ifdef DSA
+    if (EBIT_TEST(gopherState->entry->p->flags, ENTRY_CACHABLE))
+#else
     if (EBIT_TEST(gopherState->entry->flags, ENTRY_CACHABLE))
+#endif
 	storeSetPublicKey(gopherState->entry);	/* Make it public */
 }
 
@@ -774,10 +825,18 @@
 gopherStart(FwdState * fwdState)
 {
     int fd = fwdState->server_fd;
+#ifdef DSA    
+    StoreEntry *entry = fwdState->entry->p;
+#else    
     StoreEntry *entry = fwdState->entry;
+#endif   
     GopherStateData *gopherState = CreateGopherStateData();
-    payloadLockObject(entry->p);
+    storeLockObject(entry);
+#ifdef DSA    
+    gopherState->entry = fwdState->entry;
+#else    
     gopherState->entry = entry;
+#endif    
     gopherState->fwdState = fwdState;
     debug(10, 3) ("gopherStart: %s\n", storeUrl(entry));
     statCounter.server.all.requests++;
Index: squid/src/http.c
diff -u squid/src/http.c:1.4.4.3.2.2 squid/src/http.c:1.4.4.4.2.8.2.4
--- squid/src/http.c:1.4.4.3.2.2	Wed Aug 14 04:27:28 2002
+++ squid/src/http.c	Wed Mar 10 22:02:57 2004
@@ -50,11 +50,19 @@
 static void httpSendRequest(HttpStateData *);
 static PF httpStateFree;
 static PF httpTimeout;
+#ifdef DSA
+static void httpCacheNegatively(InstanceEntry *);
+static void httpMakePrivate(InstanceEntry *);
+static void httpMakePublic(InstanceEntry *);
+static int httpCachableReply(HttpStateData *);
+static void httpMaybeRemovePublic(InstanceEntry *, http_status);
+#else
 static void httpCacheNegatively(StoreEntry *);
 static void httpMakePrivate(StoreEntry *);
 static void httpMakePublic(StoreEntry *);
 static int httpCachableReply(HttpStateData *);
 static void httpMaybeRemovePublic(StoreEntry *, http_status);
+#endif
 
 static void
 httpStateFree(int fd, void *data)
@@ -65,7 +73,11 @@
 #endif
     if (httpState == NULL)
 	return;
-    payloadUnlockObject(httpState->entry->p);
+#ifdef DSA    
+    storeUnlockObject(httpState->entry->p);
+#else    
+    storeUnlockObject(httpState->entry);
+#endif    
     if (httpState->reply_hdr) {
 	memFree(httpState->reply_hdr, MEM_8K_BUF);
 	httpState->reply_hdr = NULL;
@@ -91,10 +103,14 @@
 httpTimeout(int fd, void *data)
 {
     HttpStateData *httpState = data;
+#ifdef DSA    
+    StoreEntry *entry = httpState->entry->p;
+#else    
     StoreEntry *entry = httpState->entry;
+#endif    
     debug(11, 4) ("httpTimeout: FD %d: '%s'\n", fd, storeUrl(entry));
     if (entry->store_status == STORE_PENDING) {
-	if (entry->p->mem_obj->inmem_hi == 0) {
+	if (entry->mem_obj->inmem_hi == 0) {
 	    fwdFail(httpState->fwd,
 		errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT));
 	}
@@ -104,36 +120,68 @@
 
 /* This object can be cached for a long time */
 static void
+#ifdef DSA
+httpMakePublic(InstanceEntry * entry)
+{
+#ifdef DTD
+    if (!EBIT_TEST(entry->flags, RELEASE_REQUEST) && EBIT_TEST(entry->p->flags, ENTRY_CACHABLE))
+#else
+    if (EBIT_TEST(entry->p->flags, ENTRY_CACHABLE))
+#endif
+#else    
 httpMakePublic(StoreEntry * entry)
 {
     if (EBIT_TEST(entry->flags, ENTRY_CACHABLE))
+#endif    
 	storeSetPublicKey(entry);
 }
 
 /* This object should never be cached at all */
 static void
+#ifdef DSA
+httpMakePrivate(InstanceEntry * entry)
+{
+    storeExpireNow(entry);
+    storeReleaseRequest(entry->p);	/* delete object when not used */
+#else
 httpMakePrivate(StoreEntry * entry)
 {
     storeExpireNow(entry);
     storeReleaseRequest(entry);	/* delete object when not used */
+#endif	
     /* storeReleaseRequest clears ENTRY_CACHABLE flag */
 }
 
 /* This object may be negatively cached */
 static void
+#ifdef DSA
+httpCacheNegatively(InstanceEntry * entry)
+{
+    storeNegativeCache(entry);
+    if (EBIT_TEST(entry->p->flags, ENTRY_CACHABLE))
+#else	    
 httpCacheNegatively(StoreEntry * entry)
 {
     storeNegativeCache(entry);
     if (EBIT_TEST(entry->flags, ENTRY_CACHABLE))
+#endif	    
 	storeSetPublicKey(entry);
 }
 
 static void
+#ifdef DSA
+httpMaybeRemovePublic(InstanceEntry * e, http_status status)
+#else
 httpMaybeRemovePublic(StoreEntry * e, http_status status)
+#endif	
 {
     int remove = 0;
     int forbidden = 0;
+#ifdef DSA    
+    InstanceEntry *pe;
+#else    
     StoreEntry *pe;
+#endif    
     if (!EBIT_TEST(e->flags, KEY_PRIVATE))
 	return;
     switch (status) {
@@ -167,22 +215,39 @@
     }
     if (!remove && !forbidden)
 	return;
+#ifdef DSA    
     assert(e->p->mem_obj);
-    if ((pe = storeGetPublic(e->p->mem_obj->url, e->p->mem_obj->method)) != NULL) {
+    if ((pe = instanceGetPublic(e->p->mem_obj->url, e->p->mem_obj->method)) != NULL) {
+	assert(e != pe);
+	instanceRelease(pe);
+#else	    
+    assert(e->mem_obj);
+    if ((pe = storeGetPublic(e->mem_obj->url, e->mem_obj->method)) != NULL) {
 	assert(e != pe);
 	storeRelease(pe);
+#endif	    
     }
     /*
      * Also remove any cached HEAD response in case the object has
      * changed.
      */
-    if ((pe = storeGetPublic(e->p->mem_obj->url, METHOD_HEAD)) != NULL) {
+#ifdef DSA   
+    if ((pe = instanceGetPublic(e->p->mem_obj->url, METHOD_HEAD)) != NULL) {
+	assert(e != pe);
+	instanceRelease(pe);
+#else	    
+    if ((pe = storeGetPublic(e->mem_obj->url, METHOD_HEAD)) != NULL) {
 	assert(e != pe);
 	storeRelease(pe);
+#endif	    
     }
     if (forbidden)
 	return;
+#ifdef DSA    
     switch (e->p->mem_obj->method) {
+#else	    
+    switch (e->mem_obj->method) {
+#endif	    
     case METHOD_PUT:
     case METHOD_DELETE:
     case METHOD_PROPPATCH:
@@ -194,9 +259,15 @@
 	 * Remove any cached GET object if it is beleived that the
 	 * object may have changed as a result of other methods
 	 */
-	if ((pe = storeGetPublic(e->p->mem_obj->url, METHOD_GET)) != NULL) {
+#ifdef DSA	    
+	if ((pe = instanceGetPublic(e->p->mem_obj->url, METHOD_GET)) != NULL) {
+	    assert(e != pe);
+	    instanceRelease(pe);
+#else		
+	if ((pe = storeGetPublic(e->mem_obj->url, METHOD_GET)) != NULL) {
 	    assert(e != pe);
 	    storeRelease(pe);
+#endif		
 	}
 	break;
     }
@@ -205,7 +276,11 @@
 static int
 httpCachableReply(HttpStateData * httpState)
 {
+#ifdef DSA	
     HttpReply *rep = httpState->entry->p->mem_obj->reply;
+#else 
+    HttpReply *rep = httpState->entry->mem_obj->reply;
+#endif
     HttpHeader *hdr = &rep->header;
     const int cc_mask = (rep->cache_control) ? rep->cache_control->mask : 0;
     const char *v;
@@ -247,7 +322,11 @@
     if ((v = httpHeaderGetStr(hdr, HDR_CONTENT_TYPE)))
 	if (!strncasecmp(v, "multipart/x-mixed-replace", 25))
 	    return 0;
+#ifdef DSA 
     switch (httpState->entry->p->mem_obj->reply->sline.status) {
+#else	    
+    switch (httpState->entry->mem_obj->reply->sline.status) {
+#endif 
 	/* Responses that are cacheable */
     case HTTP_OK:
     case HTTP_NON_AUTHORITATIVE_INFORMATION:
@@ -319,10 +398,18 @@
 httpProcessReplyHeader(HttpStateData * httpState, const char *buf, int size)
 {
     char *t = NULL;
+#ifdef DSA 
+    InstanceEntry *entry = httpState->entry;
+#else 
     StoreEntry *entry = httpState->entry;
+#endif 
     int room;
     size_t hdr_len;
+#ifdef DSA
     HttpReply *reply = entry->p->mem_obj->reply;
+#else
+    HttpReply *reply = entry->mem_obj->reply;
+#endif
     Ctx ctx;
     debug(11, 3) ("httpProcessReplyHeader: key '%s'\n",
 	storeKeyText(entry->hash.key));
@@ -352,7 +439,11 @@
     *t = '\0';
     httpState->reply_hdr_state++;
     assert(httpState->reply_hdr_state == 1);
+#ifdef DSA
     ctx = ctx_enter(entry->p->mem_obj->url);
+#else
+    ctx = ctx_enter(entry->mem_obj->url);
+#endif
     httpState->reply_hdr_state++;
     debug(11, 9) ("GOT HTTP REPLY HDR:\n---------\n%s\n----------\n",
 	httpState->reply_hdr);
@@ -406,7 +497,11 @@
 httpPconnTransferDone(HttpStateData * httpState)
 {
     /* return 1 if we got the last of the data on a persistent connection */
+#ifdef DSA
     MemObject *mem = httpState->entry->p->mem_obj;
+#else
+    MemObject *mem = httpState->entry->mem_obj;
+#endif
     HttpReply *reply = mem->reply;
     int clen;
     debug(11, 3) ("httpPconnTransferDone: FD %d\n", httpState->fd);
@@ -457,7 +552,11 @@
 {
     HttpStateData *httpState = data;
     LOCAL_ARRAY(char, buf, SQUID_TCP_SO_RCVBUF);
+#ifdef DSA
+    StoreEntry *entry = httpState->entry->p;
+#else
     StoreEntry *entry = httpState->entry;
+#endif
     const request_t *request = httpState->request;
     int len;
     int bin;
@@ -470,7 +569,7 @@
     if (delayIsNoDelay(fd))
 	delay_id = 0;
     else
-	delay_id = delayMostBytesAllowed(entry->p->mem_obj);
+	delay_id = delayMostBytesAllowed(entry->mem_obj);
 #endif
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
 	comm_close(fd);
@@ -513,7 +612,7 @@
 	    fd, xstrerror());
 	if (ignoreErrno(errno)) {
 	    commSetSelect(fd, COMM_SELECT_READ, httpReadReply, httpState, 0);
-	} else if (entry->p->mem_obj->inmem_hi == 0) {
+	} else if (entry->mem_obj->inmem_hi == 0) {
 	    ErrorState *err;
 	    err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
 	    err->request = requestLink((request_t *) request);
@@ -523,7 +622,7 @@
 	} else {
 	    comm_close(fd);
 	}
-    } else if (len == 0 && entry->p->mem_obj->inmem_hi == 0) {
+    } else if (len == 0 && entry->mem_obj->inmem_hi == 0) {
 	ErrorState *err;
 	err = errorCon(ERR_ZERO_SIZE_OBJECT, HTTP_SERVICE_UNAVAILABLE);
 	err->xerrno = errno;
@@ -532,9 +631,22 @@
 	httpState->eof = 1;
 	comm_close(fd);
     } else if (len == 0) {
-	   /* ymc: Finalize MD5 digest */
-	MD5Final(entry->p->hash.key, &entry->p->ctx);
-    	storeWrite(entry->p->mem_obj->swapout.sio, entry->p->hash.key, MD5_DIGEST_CHARS, 10-entry->p->mem_obj->swapout.queue_offset-entry->p->mem_obj->swap_hdr_sz, NULL);
+#ifdef DSA
+	    /* Finalize MD5 digest */
+	if (EBIT_TEST(entry->flags, KEY_PRIVATE)) {	
+	     cache_key key[MD5_DIGEST_CHARS];	    
+	     MD5Final(key, &entry->ctx);
+	     if (entry->hash.key) {
+		 storeKeyFree(entry->hash.key);
+		 entry->hash.key = NULL;
+	     }	 
+	     entry->hash.key = storeKeyDup(key);
+	     EBIT_CLR(entry->flags, KEY_PRIVATE);
+//	     storeAddInstanceEntry(entry, httpState->entry);
+	     if (entry->mem_obj->swapout.sio)
+	         storeWrite(entry->mem_obj->swapout.sio, entry->hash.key, MD5_DIGEST_CHARS, 10-entry->mem_obj->swapout.queue_offset-entry->mem_obj->swap_hdr_sz, NULL);
+	}
+#endif
 	/* Connection closed; retrieval done. */
 	httpState->eof = 1;
 	if (httpState->reply_hdr_state < 2)
@@ -551,7 +663,7 @@
 	if (httpState->reply_hdr_state < 2) {
 	    httpProcessReplyHeader(httpState, buf, len);
 	    if (httpState->reply_hdr_state == 2) {
-		http_status s = entry->p->mem_obj->reply->sline.status;
+		http_status s = entry->mem_obj->reply->sline.status;
 #if WIP_FWD_LOG
 		fwdStatus(httpState->fwd, s);
 #endif
@@ -563,11 +675,15 @@
 		    EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
 	    }
 	}
+#ifdef DSA
 	/* ymc: Update the MD5 digest, skip the header */
-	if (entry->p->mem_obj->inmem_hi >= entry->p->mem_obj->reply->hdr_sz) 
-	    MD5Update(&entry->p->ctx, buf, len);
-	else if (len - entry->p->mem_obj->reply->hdr_sz > 0)
-	    MD5Update(&entry->p->ctx, buf + entry->p->mem_obj->reply->hdr_sz, len - entry->p->mem_obj->reply->hdr_sz);
+	if (EBIT_TEST(entry->flags, KEY_PRIVATE)) {	
+	    if (entry->mem_obj->inmem_hi >= entry->mem_obj->reply->hdr_sz) 
+	        MD5Update(&entry->ctx, buf, len);
+   	    else if (len - entry->mem_obj->reply->hdr_sz > 0)
+	        MD5Update(&entry->ctx, buf + entry->mem_obj->reply->hdr_sz, len - entry->mem_obj->reply->hdr_sz);
+	} 
+#endif	
 	storeAppend(entry, buf, len);
 	if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
 	    /*
@@ -577,9 +693,22 @@
 	     */
 	    (void) 0;
 	} else if (httpPconnTransferDone(httpState)) {
-	   /* ymc: Finalize MD5 digest */
-	MD5Final(entry->p->hash.key, &entry->p->ctx);
-    	storeWrite(entry->p->mem_obj->swapout.sio, entry->p->hash.key, MD5_DIGEST_CHARS, 10-entry->p->mem_obj->swapout.queue_offset-entry->p->mem_obj->swap_hdr_sz, NULL);
+#ifdef DSA
+	   /* Finalize MD5 digest */
+	    if (EBIT_TEST(entry->flags, KEY_PRIVATE)) {
+	        cache_key key[MD5_DIGEST_CHARS];	    
+		MD5Final(key, &entry->ctx);
+	        if (entry->hash.key) {
+	   	    storeKeyFree(entry->hash.key);
+		    entry->hash.key = NULL;
+	        }	 
+	        entry->hash.key = storeKeyDup(key);
+	        EBIT_CLR(entry->flags, KEY_PRIVATE);
+//		storeAddInstanceEntry(entry, httpState->entry);
+		if (entry->mem_obj->swapout.sio)
+		storeWrite(entry->mem_obj->swapout.sio, entry->hash.key, MD5_DIGEST_CHARS, 10-entry->mem_obj->swapout.queue_offset-entry->mem_obj->swap_hdr_sz, NULL);
+	    }
+#endif
 	    /* yes we have to clear all these! */
 	    commSetDefer(fd, NULL, NULL);
 	    commSetTimeout(fd, -1, NULL, NULL);
@@ -606,12 +735,16 @@
 httpSendComplete(int fd, char *bufnotused, size_t size, int errflag, void *data)
 {
     HttpStateData *httpState = data;
+#ifdef DSA
+    StoreEntry *entry = httpState->entry->p;
+#else
     StoreEntry *entry = httpState->entry;
+#endif
     ErrorState *err;
     debug(11, 5) ("httpSendComplete: FD %d: size %d: errflag %d.\n",
 	fd, size, errflag);
 #if URL_CHECKSUM_DEBUG
-    assert(entry->p->mem_obj->chksum == url_checksum(entry->p->mem_obj->url));
+    assert(entry->mem_obj->chksum == url_checksum(entry->mem_obj->url));
 #endif
     if (size > 0) {
 	fd_bytes(fd, size, FD_WRITE);
@@ -624,7 +757,11 @@
 	err = errorCon(ERR_WRITE_ERROR, HTTP_INTERNAL_SERVER_ERROR);
 	err->xerrno = errno;
 	err->request = requestLink(httpState->orig_request);
+#ifdef DSA
+	errorAppendEntry(httpState->entry, err);
+#else
 	errorAppendEntry(entry, err);
+#endif
 	comm_close(fd);
 	return;
     } else {
@@ -861,7 +998,11 @@
 {
     MemBuf mb;
     request_t *req = httpState->request;
+#ifdef DSA
+    StoreEntry *entry = httpState->entry->p;
+#else
     StoreEntry *entry = httpState->entry;
+#endif
     int cfd;
     peer *p = httpState->peer;
     CWCB *sendHeaderDone;
@@ -875,10 +1016,10 @@
 
     if (!opt_forwarded_for)
 	cfd = -1;
-    else if (entry->p->mem_obj == NULL)
+    else if (entry->mem_obj == NULL)
 	cfd = -1;
     else
-	cfd = entry->p->mem_obj->fd;
+	cfd = entry->mem_obj->fd;
     assert(-1 == cfd || FD_SOCKET == fd_table[cfd].type);
     if (p != NULL)
 	httpState->flags.proxying = 1;
@@ -917,9 +1058,17 @@
     request_t *orig_req = fwd->request;
     debug(11, 3) ("httpStart: \"%s %s\"\n",
 	RequestMethodStr[orig_req->method],
+#ifdef DSA
+	storeUrl(fwd->entry->p));
+#else
 	storeUrl(fwd->entry));
+#endif
     cbdataAdd(httpState, memFree, MEM_HTTP_STATE_DATA);
-    payloadLockObject(fwd->entry->p);
+#ifdef DSA
+    storeLockObject(fwd->entry->p);
+#else
+    storeLockObject(fwd->entry);
+#endif
     httpState->fwd = fwd;
     httpState->entry = fwd->entry;
     httpState->fd = fd;
@@ -927,7 +1076,11 @@
 	httpState->peer = fwd->servers->peer;	/* might be NULL */
     if (httpState->peer) {
 	proxy_req = requestCreate(orig_req->method,
+#ifdef DSA
+	    PROTO_NONE, storeUrl(httpState->entry->p));
+#else
 	    PROTO_NONE, storeUrl(httpState->entry));
+#endif
 	xstrncpy(proxy_req->host, httpState->peer->host, SQUIDHOSTNAMELEN);
 	proxy_req->port = httpState->peer->http_port;
 	proxy_req->flags = orig_req->flags;
@@ -941,7 +1094,11 @@
 	 * for example, the request to this neighbor fails.
 	 */
 	if (httpState->peer->options.proxy_only)
+#ifdef DSA
+	    storeReleaseRequest(httpState->entry->p);
+#else
 	    storeReleaseRequest(httpState->entry);
+#endif
 #if DELAY_POOLS
 	assert(delayIsNoDelay(fd) == 0);
 	if (httpState->peer->options.no_delay)
@@ -969,7 +1126,11 @@
 httpSendRequestEntry(int fd, char *bufnotused, size_t size, int errflag, void *data)
 {
     HttpStateData *httpState = data;
+#ifdef DSA
+    StoreEntry *entry = httpState->entry->p;
+#else
     StoreEntry *entry = httpState->entry;
+#endif
     ErrorState *err;
     debug(11, 5) ("httpSendRequestEntry: FD %d: size %d: errflag %d.\n",
 	fd, size, errflag);
@@ -984,7 +1145,11 @@
 	err = errorCon(ERR_WRITE_ERROR, HTTP_INTERNAL_SERVER_ERROR);
 	err->xerrno = errno;
 	err->request = requestLink(httpState->orig_request);
+#ifdef DSA
+	errorAppendEntry(httpState->entry, err);
+#else
 	errorAppendEntry(entry, err);
+#endif
 	comm_close(fd);
 	return;
     }
@@ -999,7 +1164,11 @@
 httpSendRequestEntryDone(int fd, char *bufnotused, size_t size, int errflag, void *data)
 {
     HttpStateData *httpState = data;
+#ifdef DSA
+    InstanceEntry *entry = httpState->entry;
+#else
     StoreEntry *entry = httpState->entry;
+#endif
     ErrorState *err;
     aclCheck_t ch;
     debug(11, 5) ("httpSendRequestEntryDone: FD %d: size %d: errflag %d.\n",
Index: squid/src/icp_v2.c
diff -u squid/src/icp_v2.c:1.3.4.1 squid/src/icp_v2.c:1.3.4.1.8.1
--- squid/src/icp_v2.c:1.3.4.1	Mon Jan 15 14:49:19 2001
+++ squid/src/icp_v2.c	Fri Nov 15 01:10:34 2002
@@ -169,11 +169,20 @@
 {
     if (e == NULL)
 	return 0;
+#ifdef DSA
+    /* these changes are WRONG!!! Just want to make it compiles... -ymc */
+    if (!storeEntryValidToSend((InstanceEntry *) e))
+#else
     if (!storeEntryValidToSend(e))
+#endif
 	return 0;
     if (Config.onoff.icp_hit_stale)
 	return 1;
+#ifdef DSA    
+    if (refreshCheckICP((InstanceEntry *) e, request))
+#else	    
     if (refreshCheckICP(e, request))
+#endif	    
 	return 0;
     return 1;
 }
Index: squid/src/internal.c
diff -u squid/src/internal.c:1.3.4.3.8.1 squid/src/internal.c:1.3.4.3.10.1
--- squid/src/internal.c:1.3.4.3.8.1	Wed Aug 14 03:15:33 2002
+++ squid/src/internal.c	Fri Nov 15 01:10:34 2002
@@ -40,8 +40,14 @@
  * return HTTP_NOT_FOUND for others
  */
 void
+#ifdef DSA
+internalStart(request_t * request, InstanceEntry * e)
+{
+    StoreEntry * entry = e->p;
+#else	
 internalStart(request_t * request, StoreEntry * entry)
 {
+#endif	
     ErrorState *err;
     const char *upath = strBuf(request->urlpath);
     http_version_t version;
@@ -56,7 +62,7 @@
 	const char *msgbuf = "This cache does not suport Cache Digests.\n";
 #endif
 	httpBuildVersion(&version, 1, 0);
-	httpReplySetHeaders(entry->p->mem_obj->reply,
+	httpReplySetHeaders(entry->mem_obj->reply,
 	    version,
 	    HTTP_NOT_FOUND,
 	    "Not Found",
@@ -64,7 +70,7 @@
 	    strlen(msgbuf),
 	    squid_curtime,
 	    -2);
-	httpReplySwapOut(entry->p->mem_obj->reply, entry);
+	httpReplySwapOut(entry->mem_obj->reply, entry);
 	storeAppend(entry, msgbuf, strlen(msgbuf));
 	storeComplete(entry);
     } else {
@@ -72,7 +78,11 @@
 	    request, (ObjPackMethod) & httpRequestPack);
 	err = errorCon(ERR_INVALID_REQ, HTTP_NOT_FOUND);
 	err->request = requestLink(request);
+#ifdef DSA
+	errorAppendEntry(e, err);
+#else
 	errorAppendEntry(entry, err);
+#endif
     }
 }
 
Index: squid/src/mem.c
diff -u squid/src/mem.c:1.3.4.1.8.1 squid/src/mem.c:1.3.4.1.10.1
--- squid/src/mem.c:1.3.4.1.8.1	Wed Aug 14 03:15:33 2002
+++ squid/src/mem.c	Fri Nov 15 01:10:34 2002
@@ -255,7 +255,6 @@
     memDataInit(MEM_NETDBENTRY, "netdbEntry", sizeof(netdbEntry), 0);
     memDataInit(MEM_NET_DB_NAME, "net_db_name", sizeof(net_db_name), 0);
     memDataInit(MEM_NET_DB_PEER, "net_db_peer", sizeof(net_db_peer), 0);
-    memDataInit(MEM_PAYLOADENTRY, "PayloadEntry", sizeof(PayloadEntry), 0);
     memDataInit(MEM_PEER, "peer", sizeof(peer), 0);
 #if USE_CACHE_DIGESTS
     memDataInit(MEM_PEER_DIGEST, "PeerDigest", sizeof(PeerDigest), 0);
@@ -278,6 +277,9 @@
     memDataInit(MEM_STMEM_BUF, "Store Mem Buffer", SM_PAGE_SIZE,
 	Config.memMaxSize / SM_PAGE_SIZE);
     memDataInit(MEM_STOREENTRY, "StoreEntry", sizeof(StoreEntry), 0);
+#ifdef DSA
+    memDataInit(MEM_INSTANCEENTRY, "InstanceEntry", sizeof(InstanceEntry), 0);
+#endif
     memDataInit(MEM_STORE_CLIENT, "store_client", sizeof(store_client), 0);
     memDataInit(MEM_SWAPDIR, "SwapDir", sizeof(SwapDir), 0);
     memDataInit(MEM_USHORTLIST, "ushort_list", sizeof(ushortlist), 0);
Index: squid/src/mime.c
diff -u squid/src/mime.c:1.3.4.3.8.1 squid/src/mime.c:1.3.4.3.10.5
--- squid/src/mime.c:1.3.4.3.8.1	Wed Aug 14 03:15:33 2002
+++ squid/src/mime.c	Sun Dec 22 16:13:28 2002
@@ -387,13 +387,17 @@
 static void
 mimeLoadIconFile(const char *icon)
 {
-    cache_key digest[MD5_DIGEST_CHARS];
-    PayloadEntry * p = NULL;
     int fd;
     int n;
     request_flags flags;
     struct stat sb;
+#ifdef DSA
+    InstanceEntry *e;
+    StoreEntry * p = NULL;
+    cache_key digest[MD5_DIGEST_CHARS];
+#else
     StoreEntry *e;
+#endif
     LOCAL_ARRAY(char, path, MAXPATHLEN);
     LOCAL_ARRAY(char, url, MAX_URL);
     char *buf;
@@ -404,7 +408,11 @@
 	fatal("Unknown icon format while reading mime.conf\n");
     buf = internalLocalUri("/squid-internal-static/icons/", icon);
     xstrncpy(url, buf, MAX_URL);
+#ifdef DSA
+    if (instanceGetPublic(url, METHOD_GET))
+#else
     if (storeGetPublic(url, METHOD_GET))
+#endif
 	return;
     snprintf(path, MAXPATHLEN, "%s/%s", Config.icons.directory, icon);
     fd = file_open(path, O_RDONLY | O_BINARY);
@@ -418,46 +426,77 @@
     }
     flags = null_request_flags;
     flags.cachable = 1;
-    e = storeCreateEntry(url, url, flags, METHOD_GET);
+#ifdef DSA
+    e = instanceCreateEntry(url,
+#else
+    e = storeCreateEntry(url,
+#endif
+	url,
+	flags,
+	METHOD_GET);
     assert(e != NULL);
     storeSetPublicKey(e);
-    storeBuffer(e);
+#ifdef DSA
+    storeBuffer(e->p);
     e->p->mem_obj->request = requestLink(urlParse(METHOD_GET, url));
     httpReplyReset(reply = e->p->mem_obj->reply);
+#else
+    storeBuffer(e);
+    e->mem_obj->request = requestLink(urlParse(METHOD_GET, url));
+    httpReplyReset(reply = e->mem_obj->reply);
+#endif
     httpBuildVersion(&version, 1, 0);
     httpReplySetHeaders(reply, version, HTTP_OK, NULL,
 	type, (int) sb.st_size, sb.st_mtime, -1);
     reply->cache_control = httpHdrCcCreate();
     httpHdrCcSetMaxAge(reply->cache_control, 86400);
     httpHeaderPutCc(&reply->header, reply->cache_control);
-    httpReplySwapOut(reply, e);
+#ifdef DSA
+    httpReplySwapOut(reply, e->p);
     reply->hdr_sz = e->p->mem_obj->inmem_hi;	/* yuk */
+#else
+    httpReplySwapOut(reply, e);
+    reply->hdr_sz = e->mem_obj->inmem_hi;	/* yuk */
+#endif
     /* read the file into the buffer and append it to store */
     buf = memAllocate(MEM_4K_BUF);
+#ifdef DSA
     while ((n = read(fd, buf, 4096)) > 0) {
 	MD5Update(&e->p->ctx, buf, n);	    
-	storeAppend(e, buf, n);
+	storeAppend(e->p, buf, n);
     }
     MD5Final(digest, &e->p->ctx);
-    p = payloadGet(digest);
+    p = storeGet(digest);
     if (p == NULL) {
-	payloadHashInsert(e->p, digest);
+	EBIT_CLR(e->p->flags, KEY_PRIVATE);
+	e->p->hash.key = storeKeyDup(digest);
+//	storeHashInsert(e->p);
         EBIT_SET(e->flags, ENTRY_SPECIAL);
-        storeBufferFlush(e);
-        storeComplete(e);
+        EBIT_SET(e->p->flags, ENTRY_SPECIAL);
+        storeBufferFlush(e->p);
+        storeComplete(e->p);
     }	
     else {
         EBIT_SET(e->flags, ENTRY_SPECIAL);
-        storeBufferFlush(e);
-        storeComplete(e);
-	storeUnlink(e);
-	payloadRelease(e->p);
+        EBIT_SET(e->p->flags, ENTRY_SPECIAL);
+        storeBufferFlush(e->p);
+        storeComplete(e->p);
+	storeUnlink(e->p);
+	storeRelease(e->p);
 	e->p = p;
     }
-    payloadAddStoreEntry(e->p, e);
+#else
+    while ((n = read(fd, buf, 4096)) > 0)
+	storeAppend(e, buf, n);
+#endif
     file_close(fd);
+#ifndef DSA
+    EBIT_SET(e->flags, ENTRY_SPECIAL);
+    storeBufferFlush(e);
+    storeComplete(e);
     storeTimestampsSet(e);
     debug(25, 3) ("Loaded icon %s\n", url);
-    payloadUnlockObject(e->p);
+    storeUnlockObject(e);
+#endif
     memFree(buf, MEM_4K_BUF);
 }
Index: squid/src/neighbors.c
diff -u squid/src/neighbors.c:1.5.2.4.2.1 squid/src/neighbors.c:1.5.2.4.4.4
--- squid/src/neighbors.c:1.5.2.4.2.1	Wed Aug 14 03:15:33 2002
+++ squid/src/neighbors.c	Sun Dec  8 22:35:02 2002
@@ -404,7 +404,7 @@
     int *timeout)
 {
     const char *url = storeUrl(entry);
-    MemObject *mem = entry->p->mem_obj;
+    MemObject *mem = entry->mem_obj;
     peer *p = NULL;
     int i;
     int reqnum = 0;
@@ -419,7 +419,7 @@
 	return 0;
     if (theOutIcpConnection < 0)
 	fatal("neighborsUdpPing: There is no ICP socket!");
-    assert(entry->p->swap_status == SWAPOUT_NONE);
+    assert(entry->swap_status == SWAPOUT_NONE);
     mem->start_ping = current_time;
     mem->ping_reply_callback = callback;
     mem->ircb_data = callback_data;
@@ -786,7 +786,7 @@
     debug(15, 6) ("neighborsUdpAck: opcode %d '%s'\n",
 	(int) opcode, storeKeyText(key));
     if (NULL != (entry = storeGet(key)))
-	mem = entry->p->mem_obj;
+	mem = entry->mem_obj;
     if ((p = whichPeer(from)))
 	neighborAlive(p, mem, header);
     if (opcode > ICP_END)
@@ -802,14 +802,18 @@
 	return;
     }
     /* check if someone is already fetching it */
+#ifdef DSA
+    if (EBIT_TEST(entry->mem_obj->e->flags, ENTRY_DISPATCHED)) {
+#else
     if (EBIT_TEST(entry->flags, ENTRY_DISPATCHED)) {
+#endif
 	debug(15, 3) ("neighborsUdpAck: '%s' already being fetched.\n",
 	    storeKeyText(key));
 	neighborCountIgnored(p);
 	return;
     }
     if (mem == NULL) {
-	debug(15, 2) ("Ignoring %s for missing p->mem_obj: %s\n",
+	debug(15, 2) ("Ignoring %s for missing mem_obj: %s\n",
 	    opcode_d, storeKeyText(key));
 	neighborCountIgnored(p);
 	return;
@@ -820,7 +824,7 @@
 	neighborCountIgnored(p);
 	return;
     }
-    if (entry->p->lock_count == 0) {
+    if (entry->lock_count == 0) {
 	debug(12, 1) ("neighborsUdpAck: '%s' has no locks\n",
 	    storeKeyText(key));
 	neighborCountIgnored(p);
@@ -1116,7 +1120,11 @@
 {
     peer *p = data;
     ps_state *psstate = xcalloc(1, sizeof(ps_state));
+#ifdef DSA    
+    InstanceEntry *fake;
+#else    
     StoreEntry *fake;
+#endif    
     MemObject *mem;
     icp_common_t *query;
     int reqnum;
@@ -1124,14 +1132,22 @@
     assert(p->type == PEER_MULTICAST);
     p->mcast.flags.count_event_pending = 0;
     snprintf(url, MAX_URL, "http://%s/", inet_ntoa(p->in_addr.sin_addr));
+#ifdef DSA    
+    fake = instanceCreateEntry(url, url, null_request_flags, METHOD_GET);
+#else    
     fake = storeCreateEntry(url, url, null_request_flags, METHOD_GET);
+#endif    
     psstate->request = requestLink(urlParse(METHOD_GET, url));
     psstate->entry = fake;
     psstate->callback = NULL;
     psstate->callback_data = p;
     psstate->ping.start = current_time;
     cbdataAdd(psstate, cbdataXfree, 0);
+#ifdef DSA    
     mem = fake->p->mem_obj;
+#else
+    mem = fake->mem_obj;
+#endif    
     mem->request = requestLink(psstate->request);
     mem->start_ping = current_time;
     mem->ping_reply_callback = peerCountHandleIcpReply;
@@ -1145,7 +1161,11 @@
 	query,
 	LOG_ICP_QUERY,
 	0);
+#ifdef DSA   
+    fake->p->ping_status = PING_WAITING;
+#else    
     fake->ping_status = PING_WAITING;
+#endif    
     eventAdd("peerCountMcastPeersDone",
 	peerCountMcastPeersDone,
 	psstate,
@@ -1159,7 +1179,11 @@
 {
     ps_state *psstate = data;
     peer *p = psstate->callback_data;
+#ifdef DSA    
+    StoreEntry *fake = psstate->entry->p;
+#else    
     StoreEntry *fake = psstate->entry;
+#endif    
     p->mcast.flags.counting = 0;
     p->mcast.avg_n_members = doubleAverage(p->mcast.avg_n_members,
 	(double) psstate->ping.n_recv,
@@ -1172,10 +1196,10 @@
 	p->stats.rtt);
     p->mcast.n_replies_expected = (int) p->mcast.avg_n_members;
     EBIT_SET(fake->flags, ENTRY_ABORTED);
-    requestUnlink(fake->p->mem_obj->request);
-    fake->p->mem_obj->request = NULL;
+    requestUnlink(fake->mem_obj->request);
+    fake->mem_obj->request = NULL;
     storeReleaseRequest(fake);
-    payloadUnlockObject(fake->p);
+    storeUnlockObject(fake);
     requestUnlink(psstate->request);
     cbdataFree(psstate);
 }
@@ -1184,8 +1208,12 @@
 peerCountHandleIcpReply(peer * p, peer_t type, protocol_t proto, void *hdrnotused, void *data)
 {
     ps_state *psstate = data;
+#ifdef DSA    
+    StoreEntry *fake = psstate->entry->p;
+#else    
     StoreEntry *fake = psstate->entry;
-    MemObject *mem = fake->p->mem_obj;
+#endif    
+    MemObject *mem = fake->mem_obj;
     int rtt = tvSubMsec(mem->start_ping, current_time);
     assert(proto == PROTO_ICP);
     assert(fake);
@@ -1329,7 +1357,7 @@
     debug(15, 6) ("neighborsHtcpReply: %s %s\n",
 	htcp->hit ? "HIT" : "MISS", storeKeyText(key));
     if (NULL != (e = storeGet(key)))
-	mem = e->p->mem_obj;
+	mem = e->mem_obj;
     if ((p = whichPeer(from)))
 	neighborAliveHtcp(p, mem, htcp);
     /* Does the entry exist? */
@@ -1340,14 +1368,18 @@
 	return;
     }
     /* check if someone is already fetching it */
+#ifdef DSA
+    if (EBIT_TEST(e->mem_obj->e->flags, ENTRY_DISPATCHED)) {
+#else
     if (EBIT_TEST(e->flags, ENTRY_DISPATCHED)) {
+#endif
 	debug(15, 3) ("neighborsUdpAck: '%s' already being fetched.\n",
 	    storeKeyText(key));
 	neighborCountIgnored(p);
 	return;
     }
     if (mem == NULL) {
-	debug(15, 2) ("Ignoring reply for missing p->mem_obj: %s\n",
+	debug(15, 2) ("Ignoring reply for missing mem_obj: %s\n",
 	    storeKeyText(key));
 	neighborCountIgnored(p);
 	return;
Index: squid/src/net_db.c
diff -u squid/src/net_db.c:1.5.4.3.8.1 squid/src/net_db.c:1.5.4.3
--- squid/src/net_db.c:1.5.4.3.8.1	Wed Aug 14 03:15:34 2002
+++ squid/src/net_db.c	Mon Jan 15 14:49:19 2001
@@ -555,7 +555,7 @@
 	/* skip reply headers */
 	if ((hdr_sz = headersEnd(p, size))) {
 	    debug(38, 5) ("netdbExchangeHandleReply: hdr_sz = %d\n", hdr_sz);
-	    rep = ex->e->p->mem_obj->reply;
+	    rep = ex->e->mem_obj->reply;
 	    if (0 == rep->sline.status)
 		httpReplyParse(rep, buf, hdr_sz);
 	    debug(38, 3) ("netdbExchangeHandleReply: reply status %d\n",
@@ -627,8 +627,8 @@
 	debug(38, 3) ("netdbExchangeHandleReply: STORE_PENDING\n");
 	storeClientCopy(ex->sc, ex->e, ex->seen, ex->used, ex->buf_sz,
 	    ex->buf, netdbExchangeHandleReply, ex);
-    } else if (ex->seen < ex->e->p->mem_obj->inmem_hi) {
-	debug(38, 3) ("netdbExchangeHandleReply: ex->e->p->mem_obj->inmem_hi\n");
+    } else if (ex->seen < ex->e->mem_obj->inmem_hi) {
+	debug(38, 3) ("netdbExchangeHandleReply: ex->e->mem_obj->inmem_hi\n");
 	storeClientCopy(ex->sc, ex->e, ex->seen, ex->used, ex->buf_sz,
 	    ex->buf, netdbExchangeHandleReply, ex);
     } else {
@@ -918,7 +918,7 @@
 void
 netdbBinaryExchange(StoreEntry * s)
 {
-    http_reply *reply = s->p->mem_obj->reply;
+    http_reply *reply = s->mem_obj->reply;
     http_version_t version;
 #if USE_ICMP
     netdbEntry *n;
Index: squid/src/peer_digest.c
diff -u squid/src/peer_digest.c:1.3.4.1.6.1 squid/src/peer_digest.c:1.3.4.1.8.1
--- squid/src/peer_digest.c:1.3.4.1.6.1	Wed Aug 14 03:15:34 2002
+++ squid/src/peer_digest.c	Sun Dec  8 19:53:28 2002
@@ -310,8 +310,8 @@
     old_e = fetch->old_entry = storeGet(key);
     if (old_e) {
 	debug(72, 5) ("peerDigestRequest: found old entry\n");
-	payloadLockObject(old_e->p);
-	payloadCreateMemObject(old_e->p, url, url);
+	storeLockObject(old_e);
+	storeCreateMemObject(old_e, url, url);
 	fetch->old_sc = storeClientListAdd(old_e, fetch);
     }
     e = fetch->entry = storeCreateEntry(url, url, req->flags, req->method);
@@ -547,7 +547,11 @@
 	    reason = "swap failure";
 	else if (!fetch->entry)
 	    reason = "swap aborted?!";
+#ifdef DSA
+	else if (EBIT_TEST(fetch->entry->p->flags, ENTRY_ABORTED))
+#else
 	else if (EBIT_TEST(fetch->entry->flags, ENTRY_ABORTED))
+#endif
 	    reason = "swap aborted";
     }
     /* continue checking (maybe-successful eof case) */
Index: squid/src/peer_select.c
diff -u squid/src/peer_select.c:1.3.4.2.6.1 squid/src/peer_select.c:1.3.4.2.8.1
--- squid/src/peer_select.c:1.3.4.2.6.1	Wed Aug 14 03:15:34 2002
+++ squid/src/peer_select.c	Fri Nov 15 01:10:35 2002
@@ -102,8 +102,13 @@
     requestUnlink(psstate->request);
     psstate->request = NULL;
     if (psstate->entry) {
+#ifdef DSA	    
+	assert(psstate->entry->p->ping_status != PING_WAITING);
+	storeUnlockObject(psstate->entry->p);
+#else	
 	assert(psstate->entry->ping_status != PING_WAITING);
-	payloadUnlockObject(psstate->entry->p);
+	storeUnlockObject(psstate->entry);
+#endif	
 	psstate->entry = NULL;
     }
     cbdataFree(psstate);
@@ -130,13 +135,22 @@
 
 void
 peerSelect(request_t * request,
+#ifdef DSA		
+    InstanceEntry * entry,
+#else    
     StoreEntry * entry,
+#endif    
     PSC * callback,
     void *callback_data)
 {
     ps_state *psstate = memAllocate(MEM_PS_STATE);
+#ifdef DSA
+    if (entry && entry->p)
+	debug(44, 3) ("peerSelect: %s\n", storeUrl(entry->p));
+#else    
     if (entry)
 	debug(44, 3) ("peerSelect: %s\n", storeUrl(entry));
+#endif    
     else
 	debug(44, 3) ("peerSelect: %s\n", RequestMethodStr[request->method]);
     cbdataAdd(psstate, memFree, MEM_PS_STATE);
@@ -148,8 +162,13 @@
 #if USE_CACHE_DIGESTS
     request->hier.peer_select_start = current_time;
 #endif
+#ifdef DSA    
+    if (psstate->entry && psstate->entry->p)
+	storeLockObject(psstate->entry->p);
+#else    
     if (psstate->entry)
-	payloadLockObject(psstate->entry->p);
+	storeLockObject(psstate->entry);
+#endif    
     cbdataLock(callback_data);
     peerSelectFoo(psstate);
 }
@@ -177,7 +196,11 @@
 static void
 peerSelectCallback(ps_state * psstate)
 {
+#ifdef DSA	
+    StoreEntry *entry = psstate->entry->p;
+#else    
     StoreEntry *entry = psstate->entry;
+#endif    
     FwdServer *fs = psstate->servers;
     void *data = psstate->callback_data;
     if (entry) {
@@ -235,7 +258,11 @@
 static void
 peerSelectFoo(ps_state * ps)
 {
+#ifdef DSA	
+    StoreEntry *entry = ps->entry->p;
+#else    
     StoreEntry *entry = ps->entry;
+#endif    
     request_t *request = ps->request;
     debug(44, 3) ("peerSelectFoo: '%s %s'\n",
 	RequestMethodStr[request->method],
@@ -316,7 +343,11 @@
 static void
 peerGetSomeNeighbor(ps_state * ps)
 {
+#ifdef DSA	
+    StoreEntry *entry = ps->entry->p;
+#else    
     StoreEntry *entry = ps->entry;
+#endif    
     request_t *request = ps->request;
     peer *p;
     hier_code code = HIER_NONE;
@@ -382,7 +413,11 @@
     request_t *request = ps->request;
     peer *p = NULL;
     hier_code code = HIER_NONE;
+#ifdef DSA    
+    assert(ps->entry->p->ping_status == PING_WAITING);
+#else    
     assert(ps->entry->ping_status == PING_WAITING);
+#endif    
     assert(ps->direct != DIRECT_YES);
     if (peerCheckNetdbDirect(ps)) {
 	code = CLOSEST_DIRECT;
@@ -489,7 +524,11 @@
 peerPingTimeout(void *data)
 {
     ps_state *psstate = data;
+#ifdef DSA
+    StoreEntry *entry = psstate->entry->p;
+#else    
     StoreEntry *entry = psstate->entry;
+#endif    
     if (entry)
 	debug(44, 3) ("peerPingTimeout: '%s'\n", storeUrl(entry));
     if (!cbdataValid(psstate->callback_data)) {
@@ -548,7 +587,11 @@
     icp_opcode op = header->opcode;
     debug(44, 3) ("peerHandleIcpReply: %s %s\n",
 	icp_opcode_str[op],
+#ifdef DSA	
+	storeUrl(psstate->entry->p));
+#else    
 	storeUrl(psstate->entry));
+#endif	
 #if USE_CACHE_DIGESTS && 0
     /* do cd lookup to count false misses */
     if (p && request)
Index: squid/src/protos.h
diff -u squid/src/protos.h:1.4.4.8.2.2 squid/src/protos.h:1.4.4.9.2.4.2.1
--- squid/src/protos.h:1.4.4.8.2.2	Wed Aug 14 04:27:28 2002
+++ squid/src/protos.h	Wed Mar 10 22:02:57 2004
@@ -109,13 +109,19 @@
 
 extern void clientAccessCheck(void *);
 extern void clientAccessCheckDone(int, void *);
-extern int modifiedSince(StoreEntry *, request_t *);
 extern char *clientConstructTraceEcho(clientHttpRequest *);
 extern void clientPurgeRequest(clientHttpRequest *);
-extern int checkNegativeHit(StoreEntry *);
 extern void clientHttpConnectionsOpen(void);
 extern void clientHttpConnectionsClose(void);
+#ifdef DSA
+extern int checkNegativeHit(InstanceEntry *);
+extern int modifiedSince(InstanceEntry *, request_t *);
+extern InstanceEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags);
+#else
+extern int checkNegativeHit(StoreEntry *);
+extern int modifiedSince(StoreEntry *, request_t *);
 extern StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags);
+#endif
 extern int isTcpHit(log_type);
 
 extern int commSetNonBlocking(int fd);
@@ -663,12 +669,19 @@
 extern void netdbExchangeUpdatePeer(struct in_addr, peer *, double, double);
 extern peer *netdbClosestParent(request_t *);
 extern void netdbHostData(const char *host, int *samp, int *rtt, int *hops);
-
+#ifdef DSA
+extern void cachemgrStart(int fd, request_t * request, InstanceEntry * entry);
+#else
 extern void cachemgrStart(int fd, request_t * request, StoreEntry * entry);
+#endif
 extern void cachemgrRegister(const char *, const char *, OBJH *, int, int);
 extern void cachemgrInit(void);
 
+#ifdef DSA
+extern void peerSelect(request_t *, InstanceEntry *, PSC *, void *data);
+#else
 extern void peerSelect(request_t *, StoreEntry *, PSC *, void *data);
+#endif
 extern void peerSelectInit(void);
 
 /* peer_digest.c */
@@ -678,7 +691,11 @@
 extern void peerDigestStatsReport(const PeerDigest * pd, StoreEntry * e);
 
 /* forward.c */
+#ifdef DSA
+extern void fwdStart(int, InstanceEntry *, request_t *);
+#else
 extern void fwdStart(int, StoreEntry *, request_t *);
+#endif
 extern DEFER fwdCheckDeferRead;
 extern void fwdFail(FwdState *, ErrorState *);
 extern void fwdUnregister(int fd, FwdState *);
@@ -692,7 +709,11 @@
 extern void fwdStatus(FwdState *, http_status);
 #endif
 
+#ifdef DSA
+extern void urnStart(request_t *, InstanceEntry *);
+#else
 extern void urnStart(request_t *, StoreEntry *);
+#endif
 
 extern void redirectStart(clientHttpRequest *, RH *, void *);
 extern void redirectInit(void);
@@ -703,11 +724,19 @@
 extern void authenticateShutdown(void);
 
 extern void refreshAddToList(const char *, int, time_t, int, time_t);
+#ifdef DSA
+extern int refreshIsCachable(const InstanceEntry *);
+extern int refreshCheckHTTP(const InstanceEntry *, request_t *);
+extern int refreshCheckICP(const InstanceEntry *, request_t *);
+extern int refreshCheckHTCP(const InstanceEntry *, request_t *);
+extern int refreshCheckDigest(const InstanceEntry *, time_t delta);
+#else
 extern int refreshIsCachable(const StoreEntry *);
 extern int refreshCheckHTTP(const StoreEntry *, request_t *);
 extern int refreshCheckICP(const StoreEntry *, request_t *);
 extern int refreshCheckHTCP(const StoreEntry *, request_t *);
 extern int refreshCheckDigest(const StoreEntry *, time_t delta);
+#endif
 extern time_t getMaxAge(const char *url);
 extern void refreshInit(void);
 
@@ -805,63 +834,72 @@
 /* ----------------------------------------------------------------- */
 
 /*
- * payload.c
- */
-extern PayloadEntry * new_PayloadEntry();
-extern void payloadAddStoreEntry(PayloadEntry *, StoreEntry *);
-extern void payloadRemoveStoreEntry(PayloadEntry *, StoreEntry *);
-extern void payloadHashInsert(PayloadEntry *, const cache_key *);
-extern void payloadReplAdd(char *, REMOVALPOLICYCREATE *);
-extern void payloadLockObject(PayloadEntry *);
-extern int payloadUnlockObject(PayloadEntry *);
-extern PayloadEntry * payloadGet(const cache_key *);
-extern PayloadEntry * payloadCreateEntry();
-extern void payloadMaintainSwapSpace(void *);
-extern void payloadInit();
-extern void payloadFreeMemory();
-extern void payloadEntryDump();
-extern int payloadEntryLocked(const PayloadEntry *);
-extern void payloadRelease(PayloadEntry *);
-extern void payloadSetMemStatus(PayloadEntry *, int);
- 
-/* ----------------------------------------------------------------- */
-
-/*
  * store.c
  */
-extern StoreEntry *new_StoreEntry(int, const char *, const char *);
-extern void storeCreateMemObject(StoreEntry *, const char *, const char *);
 extern StoreEntry *storeGet(const cache_key *);
-extern StoreEntry *storeGetPublic(const char *, const method_t);
+extern StoreEntry *storeGetPublic(const char *uri, const method_t method);
+#ifdef DSA
+extern void storeAddInstanceEntry(StoreEntry *, InstanceEntry *);
+extern void storeRemoveInstanceEntry(StoreEntry *, InstanceEntry *);
+extern InstanceEntry *new_InstanceEntry(int, const char *, const char *);
+extern InstanceEntry *instanceCreateEntry(const char *, const char *, request_flags, method_t);
+extern StoreEntry *new_StoreEntry();
+extern InstanceEntry *instanceGet(const cache_key *);
+extern InstanceEntry *instanceGetPublic(const char *uri, const method_t method);
+extern InstanceEntry *instanceCreateEntry(const char *, const char *, request_flags, method_t);
+extern tlv * instanceSwapMetaBuild(InstanceEntry *);
+extern StoreEntry *storeCreateEntry();
+extern void storeSetPublicKey(InstanceEntry *);
+#else
+extern StoreEntry *new_StoreEntry(int, const char *, const char *);
 extern StoreEntry *storeCreateEntry(const char *, const char *, request_flags, method_t);
 extern void storeSetPublicKey(StoreEntry *);
+#endif
+extern void storeAbort(StoreEntry *);
 extern void storeComplete(StoreEntry *);
 extern void storeInit(void);
 extern int storeClientWaiting(const StoreEntry *);
-extern void storeAbort(StoreEntry *);
 extern void storeAppend(StoreEntry *, const char *, int);
+extern void storeLockObject(StoreEntry *);
+#ifdef DSA
+extern void instanceRelease(InstanceEntry *);
+extern void instanceReleaseRequest(InstanceEntry *);
+#endif
 extern void storeRelease(StoreEntry *);
+extern void storeReleaseRequest(StoreEntry *);
+extern int storeUnlockObject(StoreEntry *);
 extern int storePendingNClients(const StoreEntry *);
 extern EVH storeMaintainSwapSpace;
-extern void storeExpireNow(StoreEntry *);
-extern void storeReleaseRequest(StoreEntry *);
 extern off_t storeLowestMemReaderOffset(const StoreEntry *);
 extern void storeConfigure(void);
-extern void storeNegativeCache(StoreEntry *);
 extern void storeFreeMemory(void);
 extern int expiresMoreThan(time_t, time_t);
 extern void InvokeHandlers(StoreEntry *);
+#ifdef DTD
+int storeValidToSend(StoreEntry *);
+#endif
+#ifdef DSA
+extern void instanceHashInsert(InstanceEntry * e, const cache_key *);
+extern void storeExpireNow(InstanceEntry *);
+extern void storeNegativeCache(InstanceEntry *);
+extern int storeEntryValidToSend(InstanceEntry *);
+extern void storeTimestampsSet(InstanceEntry *);
+#else
+extern void storeExpireNow(StoreEntry *);
+extern void storeNegativeCache(StoreEntry *);
 extern int storeEntryValidToSend(StoreEntry *);
 extern void storeTimestampsSet(StoreEntry *);
+#endif
 extern void storeRegisterAbort(StoreEntry * e, STABH * cb, void *);
 extern void storeUnregisterAbort(StoreEntry * e);
 extern void storeMemObjectDump(MemObject * mem);
 extern void storeEntryDump(const StoreEntry * e, int debug_lvl);
 extern const char *storeUrl(const StoreEntry *);
+extern void storeCreateMemObject(StoreEntry *, const char *, const char *);
 extern void storeCopyNotModifiedReplyHeaders(MemObject * O, MemObject * N);
 extern void storeBuffer(StoreEntry *);
 extern void storeBufferFlush(StoreEntry *);
-extern void storeHashInsert(StoreEntry * e, const cache_key *);
+extern void storeSetMemStatus(StoreEntry * e, int);
 #if STDC_HEADERS
 extern void storeAppendPrintf(StoreEntry *, const char *,...);
 #else
@@ -869,7 +907,13 @@
 #endif
 extern void storeAppendVPrintf(StoreEntry *, const char *, va_list ap);
 extern int storeCheckCachable(StoreEntry * e);
+#ifdef DSA
+extern void storeSetPrivateKey(InstanceEntry *);
+extern void storeHashInsert(StoreEntry * e);
+#else
 extern void storeSetPrivateKey(StoreEntry *);
+extern void storeHashInsert(StoreEntry * e, const cache_key *);
+#endif
 extern int objectLen(const StoreEntry * e);
 extern int contentLen(const StoreEntry * e);
 extern HttpReply *storeEntryReply(StoreEntry *);
@@ -880,6 +924,7 @@
 extern void storeFsInit(void);
 extern void storeFsDone(void);
 extern void storeFsAdd(char *, STSETUP *);
+extern void storeReplAdd(char *, REMOVALPOLICYCREATE *);
 
 /* store_modules.c */
 extern void storeFsSetup(void);
@@ -949,12 +994,12 @@
 extern void storeDirDiskFull(sdirno);
 extern void storeDirInit(void);
 extern void storeDirOpenSwapLogs(void);
-extern void storeDirSwapLog(const PayloadEntry *, int op);
+extern void storeDirSwapLog(const StoreEntry *, int op);
 extern void storeDirUpdateSwapSize(SwapDir *, size_t size, int sign);
 extern void storeDirSync(void);
 extern void storeDirCallback(void);
-extern void storeDirLRUDelete(PayloadEntry *);
-extern void storeDirLRUAdd(PayloadEntry *);
+extern void storeDirLRUDelete(StoreEntry *);
+extern void storeDirLRUAdd(StoreEntry *);
 extern int storeDirGetBlkSize(const char *path, int *blksize);
 extern int storeDirGetUFSStats(const char *, int *, int *, int *, int *);
 
@@ -962,7 +1007,6 @@
  * store_swapmeta.c
  */
 extern char *storeSwapMetaPack(tlv * tlv_list, int *length);
-extern tlv *storeInstanceSwapMetaBuild(StoreEntry * e);
 extern tlv *storeSwapMetaBuild(StoreEntry * e);
 extern tlv *storeSwapMetaUnpack(const char *buf, int *hdrlen);
 extern void storeSwapTLVFree(tlv * n);
@@ -1079,7 +1123,11 @@
 extern void errorClean(void);
 extern HttpReply *errorBuildReply(ErrorState * err);
 extern void errorSend(int fd, ErrorState *);
+#ifdef DSA
+extern void errorAppendEntry(InstanceEntry *, ErrorState *);
+#else
 extern void errorAppendEntry(StoreEntry *, ErrorState *);
+#endif
 extern void errorStateFree(ErrorState * err);
 extern int errorReservePageId(const char *page_name);
 extern ErrorState *errorCon(err_type type, http_status);
@@ -1161,7 +1209,11 @@
 extern void cacheDigestGuessStatsReport(const cd_guess_stats * stats, StoreEntry * sentry, const char *label);
 extern void cacheDigestReport(CacheDigest * cd, const char *label, StoreEntry * e);
 
+#ifdef DSA
+extern void internalStart(request_t *, InstanceEntry *);
+#else
 extern void internalStart(request_t *, StoreEntry *);
+#endif
 extern int internalCheck(const char *urlpath);
 extern int internalStaticCheck(const char *urlpath);
 extern char *internalLocalUri(const char *dir, const char *name);
Index: squid/src/pump.c
diff -u squid/src/pump.c:1.4.4.1.8.1 squid/src/pump.c:1.4.4.1.10.3
--- squid/src/pump.c:1.4.4.1.8.1	Wed Aug 14 03:15:35 2002
+++ squid/src/pump.c	Sun Dec  8 22:35:02 2002
@@ -71,8 +71,13 @@
     flags.nocache = 1;
     snprintf(new_key, MAX_URL + 5, "%s|Pump", uri);
     cbdataAdd(p, memFree, MEM_PUMP_STATE_DATA);
+#ifdef DSA    
+    p->request_entry = instanceCreateEntry(new_key, new_key, flags, r->method);
+    p->sc = storeClientListAdd(p->request_entry->p, p);
+#else    
     p->request_entry = storeCreateEntry(new_key, new_key, flags, r->method);
     p->sc = storeClientListAdd(p->request_entry, p);
+#endif    
     EBIT_SET(p->request_entry->flags, ENTRY_DONT_LOG);
 #if DELAY_POOLS
     delaySetStoreClient(p->sc, delayClient(r));
@@ -117,25 +122,41 @@
     p->callback = callback;
     p->cbdata = cbdata;
     cbdataLock(p->cbdata);
-    payloadLockObject(p->reply_entry->p);
+#ifdef DSA    
+    storeLockObject(p->reply_entry->p);
+#else    
+    storeLockObject(p->reply_entry);
+#endif    
     comm_add_close_handler(p->s_fd, pumpServerClosed, p);
     /*
      * see if part of the body is in the request
      */
     if (p->rcvd < p->req->content_length && r->body_sz > 0) {
+#ifdef DSA	    
+	assert(p->request_entry->p->store_status == STORE_PENDING);
+#else	
 	assert(p->request_entry->store_status == STORE_PENDING);
+#endif	
 	assert(r->body != NULL);
 	assert(r->body_sz <= p->req->content_length);
 	copy_sz = XMIN(r->body_sz, p->req->content_length);
 	debug(61, 3) ("pumpStart: Appending %d bytes from r->body\n", copy_sz);
+#ifdef DSA	
+	storeAppend(p->request_entry->p, r->body, copy_sz);
+#else	
 	storeAppend(p->request_entry, r->body, copy_sz);
+#endif	
 	p->rcvd = copy_sz;
     }
     /*
      * Do we need to read more data from the client?
      */
     if (p->rcvd < p->req->content_length) {
+#ifdef DSA
+	assert(p->request_entry->p->store_status == STORE_PENDING);
+#else	
 	assert(p->request_entry->store_status == STORE_PENDING);
+#endif	
 	commSetSelect(p->c_fd, COMM_SELECT_READ, pumpReadFromClient, p, 0);
 	commSetTimeout(p->c_fd, Config.Timeout.read, pumpTimeout, p);
 	commSetDefer(p->c_fd, pumpReadDefer, p);
@@ -144,7 +165,11 @@
     if (p->sent == p->req->content_length) {
 	pumpServerCopyComplete(p->s_fd, NULL, 0, DISK_OK, p);
     } else {
+#ifdef DSA	    
+	storeClientCopy(p->sc, p->request_entry->p, p->sent, p->sent, 4096,
+#else			
 	storeClientCopy(p->sc, p->request_entry, p->sent, p->sent, 4096,
+#endif		
 	    memAllocate(MEM_4K_BUF),
 	    pumpServerCopy, p);
     }
@@ -184,7 +209,11 @@
 	pumpClose(p);
 	return;
     }
+#ifdef DSA
+    if (EBIT_TEST(p->request_entry->p->flags, ENTRY_ABORTED)) {
+#else
     if (EBIT_TEST(p->request_entry->flags, ENTRY_ABORTED)) {
+#endif
 	debug(61, 5) ("pumpServerCopyComplete: ENTRY_ABORTED\n");
 	pumpClose(p);
 	return;
@@ -192,7 +221,11 @@
     p->sent += size;
     assert(p->sent <= p->req->content_length);
     if (p->sent < p->req->content_length) {
+#ifdef DSA	    
+	storeClientCopy(p->sc, p->request_entry->p, p->sent, p->sent, 4096,
+#else			
 	storeClientCopy(p->sc, p->request_entry, p->sent, p->sent, 4096,
+#endif		
 	    memAllocate(MEM_4K_BUF),
 	    pumpServerCopy, p);
 	return;
@@ -207,7 +240,11 @@
     if (cbdataValid(p->cbdata))
 	p->callback(sfd, NULL, p->sent, 0, p->cbdata);
     cbdataUnlock(p->cbdata);
-    payloadUnlockObject(p->reply_entry->p);
+#ifdef DSA   
+    storeUnlockObject(p->reply_entry->p);
+#else    
+    storeUnlockObject(p->reply_entry);
+#endif    
     p->reply_entry = NULL;
     /*
      * and now we don't care about the client side either
@@ -222,7 +259,11 @@
 pumpReadFromClient(int fd, void *data)
 {
     PumpStateData *p = data;
+#ifdef DSA    
+    StoreEntry *req = p->request_entry->p;
+#else    
     StoreEntry *req = p->request_entry;
+#endif    
     LOCAL_ARRAY(char, buf, SQUID_TCP_SO_RCVBUF);
     int bytes_to_read = XMIN(p->req->content_length - p->rcvd, SQUID_TCP_SO_RCVBUF);
     int len = 0;
@@ -249,7 +290,7 @@
 	    pumpClose(p);
 	}
 	return;
-    } else if (req->p->mem_obj->inmem_hi == 0) {
+    } else if (req->mem_obj->inmem_hi == 0) {
 	debug(61, 2) ("pumpReadFromClient: FD %d: failed.\n", fd);
 	pumpClose(p);
 	return;
@@ -298,8 +339,13 @@
 pumpClose(void *data)
 {
     PumpStateData *p = data;
+#ifdef DSA    
+    StoreEntry *req = p->request_entry->p;
+    StoreEntry *rep = p->reply_entry->p;
+#else    
     StoreEntry *req = p->request_entry;
     StoreEntry *rep = p->reply_entry;
+#endif    
     cbdataLock(p);
     debug(61, 3) ("pumpClose: %p Server FD %d, Client FD %d\n",
 	p, p->s_fd, p->c_fd);
@@ -330,8 +376,13 @@
 {
     PumpStateData *p = NULL;
     PumpStateData *q = NULL;
+#ifdef DSA
+    InstanceEntry *req;
+    InstanceEntry *rep;
+#else
     StoreEntry *req;
     StoreEntry *rep;
+#endif
     debug(61, 3) ("pumpFree: FD %d, releasing %p!\n", fd, data);
     for (p = pump_head; p && p != data; q = p, p = p->next);
     if (p == NULL) {
@@ -347,13 +398,22 @@
     req = p->request_entry;
     rep = p->reply_entry;
     if (req != NULL) {
+#ifdef DSA
+	storeUnregister(p->sc, req->p, p);
+	storeUnlockObject(req->p);
+#else
 	storeUnregister(p->sc, req, p);
-	payloadUnlockObject(req->p);
+	storeUnlockObject(req);
+#endif
 	p->request_entry = NULL;
     }
     if (rep != NULL) {
 	debug(61, 3) ("pumpFree: did the server-side FD (%d) get closed?\n", p->s_fd);
-	payloadUnlockObject(rep->p);
+#ifdef DSA
+	storeUnlockObject(rep->p);
+#else
+	storeUnlockObject(rep);
+#endif
 	p->reply_entry = NULL;
     }
     requestUnlink(p->req);
@@ -410,7 +470,11 @@
 	debug(61, 3) ("pumpRestart: NO: Can't find pumpState!\n");
 	return 0;
     }
+#ifdef DSA    
     mem = p->request_entry->p->mem_obj;
+#else    
+    mem = p->request_entry->mem_obj;
+#endif    
     if (mem == NULL) {
 	debug(61, 3) ("pumpRestart: NO: request_entry->mem_obj == NULL!\n");
 	return 0;
Index: squid/src/refresh.c
diff -u squid/src/refresh.c:1.5.2.2.2.1 squid/src/refresh.c:1.5.2.2.4.1
--- squid/src/refresh.c:1.5.2.2.2.1	Wed Aug 14 03:15:35 2002
+++ squid/src/refresh.c	Fri Nov 15 01:10:36 2002
@@ -102,7 +102,11 @@
 static const refresh_t *refreshLimits(const char *);
 static const refresh_t *refreshUncompiledPattern(const char *);
 static OBJH refreshStats;
+#ifdef DSA
+static int refreshStaleness(const InstanceEntry *, time_t, time_t, const refresh_t *, stale_flags *);
+#else
 static int refreshStaleness(const StoreEntry *, time_t, time_t, const refresh_t *, stale_flags *);
+#endif
 
 static refresh_t DefaultRefresh;
 
@@ -143,7 +147,11 @@
  * times.
  */
 static int
+#ifdef DSA
+refreshStaleness(const InstanceEntry * entry, time_t check_time, time_t age, const refresh_t * R, stale_flags * sf)
+#else
 refreshStaleness(const StoreEntry * entry, time_t check_time, time_t age, const refresh_t * R, stale_flags * sf)
+#endif
 {
     /*
      * Check for an explicit expiration time.
@@ -209,7 +217,11 @@
  *  note: request maybe null (e.g. for cache digests build)
  */
 static int
+#ifdef DSA
+refreshCheck(const InstanceEntry * entry, request_t * request, time_t delta)
+#else	
 refreshCheck(const StoreEntry * entry, request_t * request, time_t delta)
+#endif	
 {
     const refresh_t *R;
     const char *uri = NULL;
@@ -217,8 +229,13 @@
     time_t check_time = squid_curtime + delta;
     int staleness;
     stale_flags sf;
+#ifdef DSA    
     if (entry->p->mem_obj)
 	uri = entry->p->mem_obj->url;
+#else    
+    if (entry->mem_obj)
+	uri = entry->mem_obj->url;
+#endif    
     else if (request)
 	uri = urlCanonical(request);
 
@@ -319,11 +336,15 @@
 }
 
 int
+#ifdef DSA
+refreshIsCachable(const InstanceEntry * entry)
+#else	
 refreshIsCachable(const StoreEntry * entry)
+#endif	
 {
     /*
      * Don't look at the request to avoid no-cache and other nuisances.
-     * the object should have a p->mem_obj so the URL will be found there.
+     * the object should have a mem_obj so the URL will be found there.
      * 60 seconds delta, to avoid objects which expire almost
      * immediately, and which can't be refreshed.
      */
@@ -336,13 +357,23 @@
     if (entry->lastmod < 0)
 	/* Last modified is needed to do a refresh */
 	return 0;
+#ifdef DSA    
     if (entry->p->mem_obj == NULL)
-	/* no p->mem_obj? */
+	/* no mem_obj? */
 	return 1;
     if (entry->p->mem_obj->reply == NULL)
 	/* no reply? */
 	return 1;
     if (entry->p->mem_obj->reply->content_length == 0)
+#else	    
+    if (entry->mem_obj == NULL)
+	/* no mem_obj? */
+	return 1;
+    if (entry->mem_obj->reply == NULL)
+	/* no reply? */
+	return 1;
+    if (entry->mem_obj->reply->content_length == 0)
+#endif	    
 	/* No use refreshing (caching?) 0 byte objects */
 	return 0;
     /* This seems to be refreshable. Cache it */
@@ -353,7 +384,11 @@
  * refreshCheck() function above */
 
 int
+#ifdef DSA
+refreshCheckHTTP(const InstanceEntry * entry, request_t * request)
+#else	
 refreshCheckHTTP(const StoreEntry * entry, request_t * request)
+#endif	
 {
     int reason = refreshCheck(entry, request, 0);
     refreshCounts[rcHTTP].total++;
@@ -362,7 +397,11 @@
 }
 
 int
+#ifdef DSA
+refreshCheckICP(const InstanceEntry * entry, request_t * request)
+#else	
 refreshCheckICP(const StoreEntry * entry, request_t * request)
+#endif	
 {
     int reason = refreshCheck(entry, request, 30);
     refreshCounts[rcICP].total++;
@@ -372,7 +411,11 @@
 
 #if USE_HTCP
 int
+#ifdef DSA
+refreshCheckHTCP(const InstanceEntry * entry, request_t * request)
+#else
 refreshCheckHTCP(const StoreEntry * entry, request_t * request)
+#endif	
 {
     int reason = refreshCheck(entry, request, 10);
     refreshCounts[rcHTCP].total++;
@@ -386,7 +429,7 @@
 refreshCheckDigest(const StoreEntry * entry, time_t delta)
 {
     int reason = refreshCheck(entry,
-	entry->p->mem_obj ? entry->p->mem_obj->request : NULL,
+	entry->mem_obj ? entry->mem_obj->request : NULL,
 	delta);
     refreshCounts[rcCDigest].total++;
     refreshCounts[rcCDigest].status[reason]++;
Index: squid/src/repl_modules.sh
diff -u squid/src/repl_modules.sh:1.2.124.1 squid/src/repl_modules.sh:1.2
--- squid/src/repl_modules.sh:1.2.124.1	Wed Aug 14 03:15:35 2002
+++ squid/src/repl_modules.sh	Sat Oct 21 08:16:13 2000
@@ -10,6 +10,6 @@
 echo "void storeReplSetup(void)"
 echo "{"
 for module in "$@"; do
-   echo "	payloadReplAdd(\"$module\", createRemovalPolicy_${module});"
+   echo "	storeReplAdd(\"$module\", createRemovalPolicy_${module});"
 done
 echo "}"
Index: squid/src/stat.c
diff -u squid/src/stat.c:1.4.4.2.2.1 squid/src/stat.c:1.4.4.2.4.1
--- squid/src/stat.c:1.4.4.2.2.1	Wed Aug 14 03:15:35 2002
+++ squid/src/stat.c	Fri Nov 15 01:10:36 2002
@@ -194,9 +194,10 @@
 describeStatuses(const StoreEntry * entry)
 {
     LOCAL_ARRAY(char, buf, 256);
-    snprintf(buf, 256, "%-13s %-13s %-12s",
+    snprintf(buf, 256, "%-13s %-13s %-12s %-12s",
 	storeStatusStr[entry->store_status],
-	memStatusStr[entry->p->mem_status],
+	memStatusStr[entry->mem_status],
+	swapStatusStr[entry->swap_status],
 	pingStatusStr[entry->ping_status]);
     return buf;
 }
@@ -243,17 +244,20 @@
 describeTimestamps(const StoreEntry * entry)
 {
     LOCAL_ARRAY(char, buf, 256);
-    snprintf(buf, 256, "LV:%-9d LM:%-9d EX:%-9d",
+#ifndef DSA    
+    snprintf(buf, 256, "LV:%-9d LU:%-9d LM:%-9d EX:%-9d",
 	(int) entry->timestamp,
+	(int) entry->lastref,
 	(int) entry->lastmod,
 	(int) entry->expires);
+#endif    
     return buf;
 }
 
 static void
 statStoreEntry(StoreEntry * s, StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     int i;
     struct _store_client *sc;
     dlink_node *node;
@@ -264,12 +268,12 @@
     storeAppendPrintf(s, "\t%s\n", describeStatuses(e));
     storeAppendPrintf(s, "\t%s\n", storeEntryFlags(e));
     storeAppendPrintf(s, "\t%s\n", describeTimestamps(e));
-    storeAppendPrintf(s, "\t%d locks, %d clients\n",
-	(int) e->p->lock_count,
-	storePendingNClients(e));
-//	(int) e->refcount);
-//    storeAppendPrintf(s, "\tSwap Dir %d, File %#08X\n",
-//	e->swap_dirn, e->swap_filen);
+    storeAppendPrintf(s, "\t%d locks, %d clients, %d refs\n",
+	(int) e->lock_count,
+	storePendingNClients(e),
+	(int) e->refcount);
+    storeAppendPrintf(s, "\tSwap Dir %d, File %#08X\n",
+	e->swap_dirn, e->swap_filen);
     if (mem != NULL) {
 	storeAppendPrintf(s, "\tinmem_lo: %d\n", (int) mem->inmem_lo);
 	storeAppendPrintf(s, "\tinmem_hi: %d\n", (int) mem->inmem_hi);
@@ -312,11 +316,11 @@
     hash_link *link_next = NULL;
     if (state->bucket >= store_hash_buckets) {
 	storeComplete(state->sentry);
-	payloadUnlockObject(state->sentry->p);
+	storeUnlockObject(state->sentry);
 	cbdataFree(state);
 	return;
     } else if (EBIT_TEST(state->sentry->flags, ENTRY_ABORTED)) {
-	payloadUnlockObject(state->sentry->p);
+	storeUnlockObject(state->sentry);
 	cbdataFree(state);
 	return;
     } else if (fwdCheckDeferRead(-1, state->sentry)) {
@@ -344,7 +348,7 @@
     StatObjectsState *state = xcalloc(1, sizeof(*state));
     state->sentry = sentry;
     state->filter = filter;
-    payloadLockObject(sentry->p);
+    storeLockObject(sentry);
     cbdataAdd(state, cbdataXfree, 0);
     eventAdd("statObjects", statObjects, state, 0.0, 1);
 }
@@ -358,7 +362,7 @@
 static int
 statObjectsVmFilter(const StoreEntry * e)
 {
-    return e->p->mem_obj ? 1 : 0;
+    return e->mem_obj ? 1 : 0;
 }
 
 static void
@@ -371,9 +375,9 @@
 static int
 statObjectsOpenfdFilter(const StoreEntry * e)
 {
-    if (e->p->mem_obj == NULL)
+    if (e->mem_obj == NULL)
 	return 0;
-    if (e->p->mem_obj->swapout.sio == NULL)
+    if (e->mem_obj->swapout.sio == NULL)
 	return 0;
     return 1;
 }
@@ -1422,9 +1426,17 @@
 	storeAppendPrintf(s, "out.offset %d, out.size %d\n",
 	    http->out.offset, http->out.size);
 	storeAppendPrintf(s, "req_sz %d\n", http->req_sz);
+#ifdef DSA	
+	e = http->entry->p;
+#else	
 	e = http->entry;
+#endif	
 	storeAppendPrintf(s, "entry %p/%s\n", e, e ? storeKeyText(e->hash.key) : "N/A");
+#ifdef DSA
+	e = http->old_entry->p;
+#else	
 	e = http->old_entry;
+#endif	
 	storeAppendPrintf(s, "old_entry %p/%s\n", e, e ? storeKeyText(e->hash.key) : "N/A");
 	storeAppendPrintf(s, "start %d.%06d (%f seconds ago)\n", http->start.tv_sec,
 	    http->start.tv_usec,
Index: squid/src/store.c
diff -u squid/src/store.c:1.4.4.5.4.1 squid/src/store.c:1.4.4.5.6.16.2.3
--- squid/src/store.c:1.4.4.5.4.1	Wed Aug 14 03:15:35 2002
+++ squid/src/store.c	Wed Mar 10 22:02:58 2004
@@ -73,15 +73,31 @@
 
 extern OBJH storeIOStats;
 
+#ifdef DSA
+static void instanceHashDelete(InstanceEntry *);
+static FREE destroy_InstanceEntry;
+#endif
 /*
  * local function prototypes
  */
 static int storeEntryValidLength(const StoreEntry *);
+static void storeGetMemSpace(int);
 static void storeHashDelete(StoreEntry *);
+static MemObject *new_MemObject(const char *, const char *);
+static void destroy_MemObject(StoreEntry *);
 static FREE destroy_StoreEntry;
+static void storePurgeMem(StoreEntry *);
+static void storeEntryReferenced(StoreEntry *);
+static void storeEntryDereferenced(StoreEntry *);
 static int getKeyCounter(void);
-static MemObject * new_MemObject(const char *, const char *);
+static int storeKeepInMemory(const StoreEntry *);
 static OBJH storeCheckCachableStats;
+static EVH storeLateRelease;
+
+/*
+ * local variables
+ */
+static Stack LateReleaseStack;
 
 #if URL_CHECKSUM_DEBUG
 unsigned int
@@ -98,27 +114,220 @@
 }
 #endif
 
+static MemObject *
+new_MemObject(const char *url, const char *log_url)
+{
+    MemObject *mem = memAllocate(MEM_MEMOBJECT);
+    mem->reply = httpReplyCreate();
+    mem->url = xstrdup(url);
+#if URL_CHECKSUM_DEBUG
+    mem->chksum = url_checksum(mem->url);
+#endif
+    mem->log_url = xstrdup(log_url);
+    mem->object_sz = -1;
+    mem->fd = -1;
+    /* XXX account log_url */
+    debug(20, 3) ("new_MemObject: returning %p\n", mem);
+    return mem;
+}
+
+#ifdef DSA
 void
-storeCreateMemObject(StoreEntry * e, const char *url, const char *log_url)
+storeReleaseRequest(StoreEntry * e)
+{
+    int i;	
+    if (EBIT_TEST(e->flags, RELEASE_REQUEST))
+	return;
+    debug(20, 3) ("storeReleaseRequest: '%s'\n", storeKeyText(e->hash.key));
+    EBIT_SET(e->flags, RELEASE_REQUEST);
+    /*
+     * Clear cachable flag here because we might get called before
+     * anyone else even looks at the cachability flag.  Also, this
+     * prevents httpMakePublic from really setting a public key.
+     */
+    EBIT_CLR(e->flags, ENTRY_CACHABLE);
+//    if (e->mem_obj && e->mem_obj->e)
+//        instanceReleaseRequest(e->mem_obj->e);
+    for (i = 0; i < e->instances->count; ++i) 
+	instanceReleaseRequest(e->instances->items[i]);
+}
+
+/* release an object from a cache */
+void
+storeRelease(StoreEntry * e)
 {
-    if (e->p->mem_obj)
+    int i;
+//    assert(p->instances);
+/*	
+    if (EBIT_TEST(p->flags, KEY_PRIVATE))
+	assert(p->hash.key == NULL);
+    else
+    */
+#ifdef DTD
+    /* just memFree bogus StoreEntry */
+    if (e->flags == 0) {
+	memFree(e, MEM_STOREENTRY);
 	return;
-    e->p->mem_obj = new_MemObject(url, log_url);
+    }
+#endif
+    if (!EBIT_TEST(e->flags, KEY_PRIVATE))
+	assert(e->hash.key);    
+    debug(20, 3) ("storeRelease: Releasing: '%s'\n", storeKeyText(e->hash.key));
+    /* If, for any reason we can't discard this object because of an
+     * outstanding request, mark it for pending release */
+    if (storeEntryLocked(e)) {
+	debug(20, 3) ("payloadRelease: Only setting RELEASE_REQUEST bit\n");
+	storeReleaseRequest(e);
+	return;
+    }
+    if (store_dirs_rebuilding && e->swap_filen > -1) {
+	if (e->swap_filen > -1) {
+	    /*
+	     * Fake a call to storeLockObject().  When rebuilding is done,
+	     * we'll just call storeUnlockObject() on these.
+	     */
+	    e->lock_count++;
+	    EBIT_SET(e->flags, RELEASE_REQUEST);
+	    stackPush(&LateReleaseStack, e);
+	    return;
+	} else {
+    for (i = 0; i < e->instances->count; ++i)
+	instanceRelease(e->instances->items[i]);
+    arrayDestroy(e->instances);
+    e->instances = NULL;
+	    destroy_StoreEntry(e);
+	}
+    }
+    for (i = 0; i < e->instances->count; ++i)
+	instanceRelease(e->instances->items[i]);
+    arrayDestroy(e->instances);
+    e->instances = NULL;
+    storeLog(STORE_LOG_RELEASE, e);
+    if (e->swap_filen > -1) {
+	storeUnlink(e);
+	if (e->swap_status == SWAPOUT_DONE)
+	    if (EBIT_TEST(e->flags, ENTRY_VALIDATED))
+		storeDirUpdateSwapSize(&Config.cacheSwap.swapDirs[e->swap_dirn], e->swap_file_sz, -1);
+	if (!EBIT_TEST(e->flags, KEY_PRIVATE))
+	    storeDirSwapLog(e, SWAP_LOG_DEL);
+    }
+    storeSetMemStatus(e, NOT_IN_MEMORY);
+    destroy_StoreEntry(e);
+}
+
+void
+instanceHashInsert(InstanceEntry * e, const cache_key * key)
+{
+    debug(20, 3) ("storeHashInsert: Inserting Entry %p key '%s'\n",
+	e, storeKeyText(key));
+    e->hash.key = storeKeyDup(key);
+    hash_join(instance_table, &e->hash);
+}
+
+static void
+instanceHashDelete(InstanceEntry * e)
+{
+    hash_remove_link(instance_table, &e->hash);
+    storeKeyFree(e->hash.key);
+    e->hash.key = NULL;
+}
+
+InstanceEntry *
+new_InstanceEntry(int mem_obj_flag, const char *url, const char *log_url)
+{
+    InstanceEntry *e = NULL;
+    e = memAllocate(MEM_INSTANCEENTRY);
+    if (mem_obj_flag) {
+	e->p = storeCreateEntry();
+	e->p->mem_obj = new_MemObject(url, log_url);
+	e->p->mem_obj->e = e;
+    }
+    debug(20, 3) ("new_InstanceEntry: returning %p\n", e);
+    e->expires = e->lastmod = e->timestamp = -1;
+    return e;
 }
 
+InstanceEntry *
+instanceCreateEntry(const char * url, const char * log_url, request_flags flags, method_t method)
+{
+    InstanceEntry *e = NULL;
+
+    e = new_InstanceEntry(STORE_ENTRY_WITH_MEMOBJ, url, log_url);
+    e->p->mem_obj->method = method;
+    if (neighbors_do_private_keys || !flags.hierarchical)
+	storeSetPrivateKey(e);
+    else
+	storeSetPublicKey(e);
+    if (e->p != NULL && !EBIT_TEST(e->p->flags, KEY_PRIVATE))
+	storeAddInstanceEntry(e->p, e);
+    if (flags.cachable) {
+	EBIT_CLR(e->flags, RELEASE_REQUEST);
+	EBIT_CLR(e->p->flags, RELEASE_REQUEST);
+    } else {
+	EBIT_CLR(e->flags, ENTRY_CACHABLE);
+	EBIT_CLR(e->p->flags, ENTRY_CACHABLE);
+	storeReleaseRequest(e->p);
+    }
+    e->timestamp = -1;		/* set in storeTimestampsSet() */
+    EBIT_SET(e->flags, ENTRY_VALIDATED);
+    return e;
+}
+
+InstanceEntry *
+instanceGet(const cache_key * key)
+{
+    debug(20, 3) ("storeGet: looking up %s\n", storeKeyText(key));
+    return (InstanceEntry *) hash_lookup(instance_table, key);
+}
+
+InstanceEntry *
+instanceGetPublic(const char *uri, const method_t method)
+{
+    return instanceGet(storeKeyPublic(uri, method));
+}
+#else
 StoreEntry *
 new_StoreEntry(int mem_obj_flag, const char *url, const char *log_url)
 {
     StoreEntry *e = NULL;
     e = memAllocate(MEM_STOREENTRY);
-    if (mem_obj_flag) {
-	e->p = payloadCreateEntry();
-	e->p->mem_obj = new_MemObject(url, log_url);
-    }	
+    if (mem_obj_flag)
+	e->mem_obj = new_MemObject(url, log_url);
     debug(20, 3) ("new_StoreEntry: returning %p\n", e);
-    e->expires = e->lastmod = e->timestamp = -1;
+    e->expires = e->lastmod = e->lastref = e->timestamp = -1;
+    e->swap_filen = -1;
+    e->swap_dirn = -1;
     return e;
 }
+#endif
+
+static void
+destroy_MemObject(StoreEntry * e)
+{
+    MemObject *mem = e->mem_obj;
+    const Ctx ctx = ctx_enter(mem->url);
+    debug(20, 3) ("destroy_MemObject: destroying %p\n", mem);
+#if URL_CHECKSUM_DEBUG
+    assert(mem->chksum == url_checksum(mem->url));
+#endif
+    e->mem_obj = NULL;
+    if (!shutting_down)
+	assert(mem->swapout.sio == NULL);
+    stmemFree(&mem->data_hdr);
+    mem->inmem_hi = 0;
+    /*
+     * There is no way to abort FD-less clients, so they might
+     * still have mem->clients set if mem->fd == -1
+     */
+    assert(mem->fd == -1 || mem->clients.head == NULL);
+    httpReplyDestroy(mem->reply);
+    requestUnlink(mem->request);
+    mem->request = NULL;
+    ctx_exit(ctx);		/* must exit before we free mem->url */
+    safe_free(mem->url);
+    safe_free(mem->log_url);	/* XXX account log_url */
+    memFree(mem, MEM_MEMOBJECT);
+}
 
 static void
 destroy_StoreEntry(void *data)
@@ -126,14 +335,36 @@
     StoreEntry *e = data;
     debug(20, 3) ("destroy_StoreEntry: destroying %p\n", e);
     assert(e != NULL);
+    if (e->mem_obj)
+	destroy_MemObject(e);
     storeHashDelete(e);
     assert(e->hash.key == NULL);
     memFree(e, MEM_STOREENTRY);
 }
 
 /* ----- INTERFACE BETWEEN STORAGE MANAGER AND HASH TABLE FUNCTIONS --------- */
+#ifdef DSA
+static void
+destroy_InstanceEntry(void *data)
+{
+    InstanceEntry *e = data;
+    debug(20, 3) ("destroy_StoreEntry: destroying %p\n", e);
+    assert(e != NULL);
+    instanceHashDelete(e);
+    assert(e->hash.key == NULL);
+    if (e->p) arrayDelete(e->p->instances, e);
+    memFree(e, MEM_INSTANCEENTRY);
+}
 
 void
+storeHashInsert(StoreEntry * e)
+{
+    debug(20, 3) ("storeHashInsert: Inserting Entry %p key '%s'\n",
+	e, storeKeyText(e->hash.key));
+    hash_join(store_table, &e->hash);
+}
+#else
+void
 storeHashInsert(StoreEntry * e, const cache_key * key)
 {
     debug(20, 3) ("storeHashInsert: Inserting Entry %p key '%s'\n",
@@ -141,10 +372,17 @@
     e->hash.key = storeKeyDup(key);
     hash_join(store_table, &e->hash);
 }
+#endif
 
 static void
 storeHashDelete(StoreEntry * e)
 {
+#ifdef DSA
+    StoreEntry * p = storeGet(e->hash.key);
+    EBIT_SET(e->flags, KEY_PRIVATE);
+    if (p == e) /* only remove hash entry from table
+		   in DSA miss */
+#endif
     hash_remove_link(store_table, &e->hash);
     storeKeyFree(e->hash.key);
     e->hash.key = NULL;
@@ -152,8 +390,74 @@
 
 /* -------------------------------------------------------------------------- */
 
+
+/* get rid of memory copy of the object */
+/* Only call this if storeCheckPurgeMem(e) returns 1 */
+static void
+storePurgeMem(StoreEntry * e)
+{
+    if (e->mem_obj == NULL)
+	return;
+    debug(20, 3) ("storePurgeMem: Freeing memory-copy of %s\n",
+	storeKeyText(e->hash.key));
+    storeSetMemStatus(e, NOT_IN_MEMORY);
+    destroy_MemObject(e);
+    if (e->swap_status != SWAPOUT_DONE)
+	storeRelease(e);
+}
+
+static void
+storeEntryReferenced(StoreEntry * e)
+{
+    SwapDir *SD;
+
+    /* Notify the fs that we're referencing this object again */
+    if (e->swap_dirn > -1) {
+	SD = INDEXSD(e->swap_dirn);
+	if (SD->refobj)
+	    SD->refobj(SD, e);
+    }
+    /* Notify the memory cache that we're referencing this object again */
+    if (e->mem_obj) {
+	if (mem_policy->Referenced)
+	    mem_policy->Referenced(mem_policy, e, &e->mem_obj->repl);
+    }
+}
+
+static void
+storeEntryDereferenced(StoreEntry * e)
+{
+    SwapDir *SD;
+
+    /* Notify the fs that we're not referencing this object any more */
+    if (e->swap_filen > -1) {
+	SD = INDEXSD(e->swap_dirn);
+	if (SD->unrefobj != NULL)
+	    SD->unrefobj(SD, e);
+    }
+    /* Notify the memory cache that we're not referencing this object any more */
+    if (e->mem_obj) {
+	if (mem_policy->Dereferenced)
+	    mem_policy->Dereferenced(mem_policy, e, &e->mem_obj->repl);
+    }
+}
+
 void
+storeLockObject(StoreEntry * e)
+{
+    e->lock_count++;
+    debug(20, 3) ("storeLockObject: key '%s' count=%d\n",
+	storeKeyText(e->hash.key), (int) e->lock_count);
+    e->lastref = squid_curtime;
+    storeEntryReferenced(e);
+}
+
+void
+#ifdef DSA
+instanceReleaseRequest(InstanceEntry * e)
+#else
 storeReleaseRequest(StoreEntry * e)
+#endif
 {
     if (EBIT_TEST(e->flags, RELEASE_REQUEST))
 	return;
@@ -164,10 +468,41 @@
      * anyone else even looks at the cachability flag.  Also, this
      * prevents httpMakePublic from really setting a public key.
      */
+#ifndef DSA
     EBIT_CLR(e->flags, ENTRY_CACHABLE);
+#endif
     storeSetPrivateKey(e);
 }
 
+/* unlock object, return -1 if object get released after unlock
+ * otherwise lock_count */
+int
+storeUnlockObject(StoreEntry * e)
+{
+    e->lock_count--;
+    debug(20, 3) ("storeUnlockObject: key '%s' count=%d\n",
+	storeKeyText(e->hash.key), e->lock_count);
+    if (e->lock_count)
+	return (int) e->lock_count;
+    if (e->store_status == STORE_PENDING)
+	EBIT_SET(e->flags, RELEASE_REQUEST);
+    assert(storePendingNClients(e) == 0);
+    if (EBIT_TEST(e->flags, RELEASE_REQUEST))
+	storeRelease(e);
+    else if (storeKeepInMemory(e)) {
+	storeEntryDereferenced(e);
+	storeSetMemStatus(e, IN_MEMORY);
+	requestUnlink(e->mem_obj->request);
+	e->mem_obj->request = NULL;
+    } else {
+	storePurgeMem(e);
+	storeEntryDereferenced(e);
+	if (EBIT_TEST(e->flags, KEY_PRIVATE))
+	    debug(20, 1) ("WARNING: %s:%d: found KEY_PRIVATE\n", __FILE__, __LINE__);
+    }
+    return 0;
+}
+
 /* Lookup an object in the cache.
  * return just a reference to object, don't start swapping in yet. */
 StoreEntry *
@@ -192,14 +527,83 @@
     return key_counter;
 }
 
+#ifdef DSA
 void
-storeSetPrivateKey(StoreEntry * e)
+storeSetPrivateKey(InstanceEntry * e)
+{
+    const cache_key *newkey;
+    MemObject *mem = e->p->mem_obj;
+    if (e->hash.key && EBIT_TEST(e->flags, KEY_PRIVATE))
+	return;			/* is already private */
+    if (e->hash.key) {
+//	if (e->p->swap_filen > -1)
+//	    storeDirSwapLog(e->p, SWAP_LOG_DEL);
+	instanceHashDelete(e);
+    }
+    if (mem != NULL) {
+	mem->id = getKeyCounter();
+	newkey = storeKeyPrivate(mem->url, mem->method, mem->id);
+    } else {
+	newkey = storeKeyPrivate("JUNK", METHOD_NONE, getKeyCounter());
+    }
+    assert(hash_lookup(instance_table, newkey) == NULL);
+    EBIT_SET(e->flags, KEY_PRIVATE);
+    instanceHashInsert(e, newkey);
+}
+
+void
+storeSetPublicKey(InstanceEntry * e)
 {
+    InstanceEntry *e2 = NULL;
     const cache_key *newkey;
+    int i;
     MemObject *mem = e->p->mem_obj;
+    if (e->hash.key && !EBIT_TEST(e->flags, KEY_PRIVATE))
+	return;			/* is already public */
+    assert(mem);
+    /*
+     * We can't make RELEASE_REQUEST objects public.  Depending on
+     * when RELEASE_REQUEST gets set, we might not be swapping out
+     * the object.  If we're not swapping out, then subsequent
+     * store clients won't be able to access object data which has
+     * been freed from memory.
+     *
+     * If RELEASE_REQUEST is set, then ENTRY_CACHABLE should not
+     * be set, and storeSetPublicKey() should not be called.
+     */
+    assert(!EBIT_TEST(e->flags, RELEASE_REQUEST));
+    newkey = storeKeyPublic(mem->url, mem->method);
+    if ((e2 = (InstanceEntry *) hash_lookup(instance_table, newkey))) {
+	debug(20, 3) ("storeSetPublicKey: Making old '%s' private.\n", mem->url);
+	storeSetPrivateKey(e2);
+	instanceRelease(e2);
+	newkey = storeKeyPublic(mem->url, mem->method);
+    }
+    if (e->hash.key)
+	instanceHashDelete(e);
+    EBIT_CLR(e->flags, KEY_PRIVATE);
+    if (e->p->instances->count > 0) {
+    for (i = 0; i < e->p->instances->count; ++i) {
+	if (e->p->instances->items[i] == e) break;
+    }
+    if (i == e->p->instances->count) arrayAppend(e->p->instances, e);
+    }
+    else arrayAppend(e->p->instances, e);
+    instanceHashInsert(e, newkey);
+    if (e->p->swap_filen > -1)
+	storeDirSwapLog(e->p, SWAP_LOG_ADD);
+}
+#else
+void
+storeSetPrivateKey(StoreEntry * e)
+{
+    const cache_key *newkey;
+    MemObject *mem = e->mem_obj;
     if (e->hash.key && EBIT_TEST(e->flags, KEY_PRIVATE))
 	return;			/* is already private */
     if (e->hash.key) {
+	if (e->swap_filen > -1)
+	    storeDirSwapLog(e, SWAP_LOG_DEL);
 	storeHashDelete(e);
     }
     if (mem != NULL) {
@@ -218,7 +622,7 @@
 {
     StoreEntry *e2 = NULL;
     const cache_key *newkey;
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     if (e->hash.key && !EBIT_TEST(e->flags, KEY_PRIVATE))
 	return;			/* is already public */
     assert(mem);
@@ -249,21 +653,216 @@
 	storeHashDelete(e);
     EBIT_CLR(e->flags, KEY_PRIVATE);
     storeHashInsert(e, newkey);
+    if (e->swap_filen > -1)
+	storeDirSwapLog(e, SWAP_LOG_ADD);
+}
+#endif
+
+#ifdef DSA
+/* oh well, a function that does mkdir -p in UFS. -ymc */
+static int
+storeMakeRecursiveDir(char *dir)
+{
+    char *ptr = dir;
+    char Delimiter = '/';
+
+    for (; *ptr != '\0'; ++ptr)
+    {
+	if (*ptr != Delimiter)
+	{
+	    continue;
+	}
+
+	*ptr = '\0';
+	if (strcmp(dir, "") && mkdir(dir, 0755) != 0)
+	{
+	    if (errno != EEXIST)
+	    {
+		debug(20, 0) ("Cannot create directory %s: %s\n",
+				    dir, strerror(errno));
+		*ptr = Delimiter;
+		return 0;
+	    }
+	}
+	*ptr = Delimiter;
+    }
+    return 1;
+}
+
+StoreEntry *
+storeCreateEntry()
+{
+    StoreEntry *e = NULL;
+
+    e = new_StoreEntry();
+    e->lock_count = 1;
+    storeSetMemStatus(e, NOT_IN_MEMORY);
+    e->swap_filen = -1;
+    e->swap_dirn = -1;
+    e->refcount = -1;
+    e->lastref = squid_curtime;
+    e->instances = arrayCreate();
+    e->store_status = STORE_PENDING;
+    e->hash.key = memAllocate(MEM_MD5_DIGEST);
+    EBIT_SET(e->flags, ENTRY_VALIDATED); /* xxxxx */
+    EBIT_SET(e->flags, ENTRY_CACHABLE); /* xxxxx */
+    EBIT_SET(e->flags, KEY_PRIVATE); /* xxxxx */
+    return e;
+}
+
+StoreEntry *
+new_StoreEntry()
+{
+    StoreEntry *e = NULL;
+    e = memAllocate(MEM_STOREENTRY);
+    debug(20, 3) ("new_StoreEntry: returning %p\n", e);
+    e->swap_filen = -1;
+    e->swap_dirn = -1;
+    e->swap_status = SWAPOUT_NONE;
+    MD5Init(&e->ctx);
+    return e;
+}
+
+/* adds an InstanceEntry to the array in a StoreEntry.
+ * looks like a very bug prone funcion. -ymc */
+void
+storeAddInstanceEntry(StoreEntry * p, InstanceEntry * e)
+{
+    tlv * tlv_list = NULL;
+    char * buf = NULL;
+    char metadata_path[SQUID_MAXPATHLEN];
+    int swap_hdr_sz = 0;
+    FILE * fp;
+    int i;
+    cache_key key[MD5_DIGEST_CHARS];
+  
+    /* return if key of p is NULL */
+    if (EBIT_TEST(p->flags, KEY_PRIVATE)) 
+	return;
+    /* return if the entry is already added */
+    if (EBIT_TEST(e->flags, ENTRY_CACHABLE)) 
+	return;	    
+    if (p->instances->count > 0) {
+	for (i = 0; i < p->instances->count; ++i) {
+	    if (p->instances->items[i] == e) break;
+        }
+        if (i == p->instances->count) arrayAppend(p->instances, e);
+    }
+    else 
+	arrayAppend(p->instances, e);
+    EBIT_SET(e->flags, ENTRY_CACHABLE);
+    xmemcpy(key, p->hash.key, MD5_DIGEST_CHARS);
+    snprintf(metadata_path, sizeof(metadata_path), 
+		    "%s/instances/%2.2x/%2.2x/%2.2x%2.2x"
+				"%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x"
+				"%2.2x%2.2x%2.2x%2.2x%2.2x/",
+				Config.cacheSwap.swapDirs[0].path, 
+				key[ 0] & 0xff, key[ 1] & 0xff,
+				key[ 2] & 0xff, key[ 3] & 0xff,
+				key[ 4] & 0xff, key[ 5] & 0xff,
+				key[ 6] & 0xff, key[ 7] & 0xff,
+				key[ 8] & 0xff, key[ 9] & 0xff,
+				key[10] & 0xff, key[11] & 0xff,
+				key[12] & 0xff, key[13] & 0xff,
+				key[14] & 0xff, key[15] & 0xff);
+    if (storeMakeRecursiveDir(metadata_path) == 0) return;
+    metadata_path[strlen(metadata_path)+MD5_DIGEST_CHARS*2] = '\0';
+    xmemcpy(metadata_path+strlen(metadata_path), storeKeyText(e->hash.key), MD5_DIGEST_CHARS*2);
+    tlv_list = instanceSwapMetaBuild(e);
+    buf = storeSwapMetaPack(tlv_list, &swap_hdr_sz);
+    fp = fopen(metadata_path, "w");
+    if (fp) {
+	int ret = fwrite(buf, sizeof(char), swap_hdr_sz, fp); 
+	if (ret != swap_hdr_sz) 
+	    debug(20, 0) ("Cannot write metadata file for instance %s of payload %s!", storeKeyText(e->hash.key), storeKeyText(p->hash.key));   
+	fclose(fp);
+    }
+    else
+	debug(20, 0) ("Cannot open metadata file for instance %s of payload %s!", storeKeyText(e->hash.key), storeKeyText(p->hash.key));   
+
+}
+
+void
+storeRemoveInstanceEntry(StoreEntry * p, InstanceEntry * e)
+{
+    char metadata_path[SQUID_MAXPATHLEN];
+    cache_key key[MD5_DIGEST_CHARS];
+    if (!EBIT_TEST(e->flags, ENTRY_CACHABLE)) 
+	return;
+    arrayDelete(p->instances, e);
+    /* remove corresponding metadata file in disk */
+    xmemcpy(key, p->hash.key, MD5_DIGEST_CHARS);
+    snprintf(metadata_path, sizeof(metadata_path), 
+		    "%s/instances/%2.2x/%2.2x/%2.2x%2.2x"
+				"%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x"
+				"%2.2x%2.2x%2.2x%2.2x%2.2x/",
+				Config.cacheSwap.swapDirs[0].path, 
+				key[ 0] & 0xff, key[ 1] & 0xff,
+				key[ 2] & 0xff, key[ 3] & 0xff,
+				key[ 4] & 0xff, key[ 5] & 0xff,
+				key[ 6] & 0xff, key[ 7] & 0xff,
+				key[ 8] & 0xff, key[ 9] & 0xff,
+				key[10] & 0xff, key[11] & 0xff,
+				key[12] & 0xff, key[13] & 0xff,
+				key[14] & 0xff, key[15] & 0xff);
+    metadata_path[strlen(metadata_path)+MD5_DIGEST_CHARS*2] = '\0';
+    if (EBIT_TEST(e->flags, KEY_PRIVATE)) {
+        if (e->p->mem_obj == NULL) return;
+	xmemcpy(metadata_path+strlen(metadata_path), storeKeyText(storeKeyPublic(e->p->mem_obj->url, e->p->mem_obj->method)), MD5_DIGEST_CHARS*2);
+    }	
+    else
+        xmemcpy(metadata_path+strlen(metadata_path), storeKeyText(e->hash.key), MD5_DIGEST_CHARS*2);
+    unlink(metadata_path); /* For now, doesn't matter if it fails */
 }
 
+/*
+static void
+destroy_PayloadEntry(void *data)
+{
+    PayloadEntry *p = data;
+    int i;
+    debug(20, 3) ("destroy_PayloadEntry: destroying %p\n", p);
+    if (p->mem_obj)
+	destroy_MemObject(p);
+    assert(p != NULL);
+    assert(p->instances);
+    for (i = 0; i < p->instances->count; ++i) 
+	storeRelease(p->instances->items[i]);
+    xfree(p->instances); 
+    payloadHashDelete(p);
+    assert(p->hash.key == NULL);
+    memFree(p, MEM_PAYLOADENTRY);
+}
+*/
+void
+instanceEntryReset(InstanceEntry * e)
+{
+    MemObject *mem = e->p->mem_obj;	
+    debug(20, 3) ("storeEntryReset: %s\n", storeUrl(e->p));
+    assert(mem->swapout.sio == NULL);
+    stmemFree(&mem->data_hdr);
+    mem->inmem_hi = mem->inmem_lo = 0;
+    httpReplyDestroy(mem->reply);
+    mem->reply = httpReplyCreate();
+    e->expires = e->lastmod = e->timestamp = -1;
+}
+
+#else
 StoreEntry *
-storeCreateEntry(const char * url, const char * log_url, request_flags flags, method_t method)
+storeCreateEntry(const char *url, const char *log_url, request_flags flags, method_t method)
 {
     StoreEntry *e = NULL;
+    MemObject *mem = NULL;
+    debug(20, 3) ("storeCreateEntry: '%s'\n", url);
 
     e = new_StoreEntry(STORE_ENTRY_WITH_MEMOBJ, url, log_url);
-    e->p->mem_obj->method = method;
+    e->lock_count = 1;		/* Note lock here w/o calling storeLock() */
+    mem = e->mem_obj;
+    mem->method = method;
     if (neighbors_do_private_keys || !flags.hierarchical)
 	storeSetPrivateKey(e);
     else
 	storeSetPublicKey(e);
-    if (e->p != NULL)
-	payloadAddStoreEntry(e->p, e);
     if (flags.cachable) {
 	EBIT_SET(e->flags, ENTRY_CACHABLE);
 	EBIT_CLR(e->flags, RELEASE_REQUEST);
@@ -272,20 +871,55 @@
 	storeReleaseRequest(e);
     }
     e->store_status = STORE_PENDING;
+    storeSetMemStatus(e, NOT_IN_MEMORY);
+    e->swap_status = SWAPOUT_NONE;
+    e->swap_filen = -1;
+    e->swap_dirn = -1;
+    e->refcount = 0;
+    e->lastref = squid_curtime;
     e->timestamp = -1;		/* set in storeTimestampsSet() */
     e->ping_status = PING_NONE;
     EBIT_SET(e->flags, ENTRY_VALIDATED);
     return e;
 }
+#endif
 
 /* Mark object as expired */
 void
+#ifdef DSA
+storeExpireNow(InstanceEntry * e)
+#else
 storeExpireNow(StoreEntry * e)
+#endif
 {
     debug(20, 3) ("storeExpireNow: '%s'\n", storeKeyText(e->hash.key));
     e->expires = squid_curtime;
 }
 
+/* Append incoming data from a primary server to an entry. */
+void
+storeAppend(StoreEntry * e, const char *buf, int len)
+{
+    MemObject *mem = e->mem_obj;
+    assert(mem != NULL);
+    assert(len >= 0);
+#ifndef DTD
+    assert(e->store_status == STORE_PENDING);
+#endif
+    if (len) {
+	debug(20, 5) ("storeAppend: appending %d bytes for '%s'\n",
+	    len,
+	    storeKeyText(e->hash.key));
+	storeGetMemSpace(len);
+	stmemAppend(&mem->data_hdr, buf, len);
+	mem->inmem_hi += len;
+    }
+    if (EBIT_TEST(e->flags, DELAY_SENDING))
+	return;
+    InvokeHandlers(e);
+    storeSwapOut(e);
+}
+
 void
 #if STDC_HEADERS
 storeAppendPrintf(StoreEntry * e, const char *fmt,...)
@@ -350,7 +984,7 @@
 static int
 storeCheckTooSmall(StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
 	return 0;
     if (STORE_OK == e->store_status)
@@ -380,25 +1014,33 @@
     } else if (e->store_status == STORE_OK && EBIT_TEST(e->flags, ENTRY_BAD_LENGTH)) {
 	debug(20, 2) ("storeCheckCachable: NO: wrong content-length\n");
 	store_check_cachable_hist.no.wrong_content_length++;
+#ifdef DSA
+    } else if (EBIT_TEST(e->mem_obj->e->flags, ENTRY_NEGCACHED)) {
+#else
     } else if (EBIT_TEST(e->flags, ENTRY_NEGCACHED)) {
+#endif
 	debug(20, 3) ("storeCheckCachable: NO: negative cached\n");
 	store_check_cachable_hist.no.negative_cached++;
 	return 0;		/* avoid release call below */
-    } else if ((e->p->mem_obj->reply->content_length > 0 &&
-		e->p->mem_obj->reply->content_length > Config.Store.maxObjectSize) ||
-	e->p->mem_obj->inmem_hi > Config.Store.maxObjectSize) {
+    } else if ((e->mem_obj->reply->content_length > 0 &&
+		e->mem_obj->reply->content_length > Config.Store.maxObjectSize) ||
+	e->mem_obj->inmem_hi > Config.Store.maxObjectSize) {
 	debug(20, 2) ("storeCheckCachable: NO: too big\n");
 	store_check_cachable_hist.no.too_big++;
-    } else if (e->p->mem_obj->reply->content_length > (int) Config.Store.maxObjectSize) {
+    } else if (e->mem_obj->reply->content_length > (int) Config.Store.maxObjectSize) {
 	debug(20, 2) ("storeCheckCachable: NO: too big\n");
 	store_check_cachable_hist.no.too_big++;
     } else if (storeCheckTooSmall(e)) {
 	debug(20, 2) ("storeCheckCachable: NO: too small\n");
 	store_check_cachable_hist.no.too_small++;
+#ifdef DSA
+    } else if (EBIT_TEST(e->mem_obj->e->flags, KEY_PRIVATE)) {
+#else
     } else if (EBIT_TEST(e->flags, KEY_PRIVATE)) {
+#endif
 	debug(20, 3) ("storeCheckCachable: NO: private key\n");
 	store_check_cachable_hist.no.private_key++;
-    } else if (e->p->swap_status != SWAPOUT_NONE) {
+    } else if (e->swap_status != SWAPOUT_NONE) {
 	/*
 	 * here we checked the swap_status because the remaining
 	 * cases are only relevant only if we haven't started swapping
@@ -449,23 +1091,6 @@
 	store_check_cachable_hist.yes.Default);
 }
 
-static MemObject *
-new_MemObject(const char *url, const char *log_url)
-{
-    MemObject *mem = memAllocate(MEM_MEMOBJECT);
-    mem->reply = httpReplyCreate();
-    mem->url = xstrdup(url);
-#if URL_CHECKSUM_DEBUG
-    mem->chksum = url_checksum(mem->url);
-#endif
-    mem->log_url = xstrdup(log_url);
-    mem->object_sz = -1;
-    mem->fd = -1;
-    /* XXX account log_url */
-    debug(20, 3) ("new_MemObject: returning %p\n", mem);
-    return mem;
-}
-
 /* Complete transfer into the local cache.  */
 void
 storeComplete(StoreEntry * e)
@@ -476,20 +1101,22 @@
 	 * if we're not STORE_PENDING, then probably we got aborted
 	 * and there should be NO clients on this entry
 	 */
+#ifndef DTD
 	assert(EBIT_TEST(e->flags, ENTRY_ABORTED));
-	assert(e->p->mem_obj->nclients == 0);
+	assert(e->mem_obj->nclients == 0);
+#endif
 	return;
     }
-    e->p->mem_obj->object_sz = e->p->mem_obj->inmem_hi;
+    e->mem_obj->object_sz = e->mem_obj->inmem_hi;
     e->store_status = STORE_OK;
-    assert(e->p->mem_status == NOT_IN_MEMORY);
+    assert(e->mem_status == NOT_IN_MEMORY);
     if (!storeEntryValidLength(e)) {
 	EBIT_SET(e->flags, ENTRY_BAD_LENGTH);
 	storeReleaseRequest(e);
     }
 #if USE_CACHE_DIGESTS
-    if (e->p->mem_obj->request)
-	e->p->mem_obj->request->hier.store_complete_stop = current_time;
+    if (e->mem_obj->request)
+	e->mem_obj->request->hier.store_complete_stop = current_time;
 #endif
     /*
      * We used to call InvokeHandlers, then storeSwapOut.  However,
@@ -509,15 +1136,19 @@
 void
 storeAbort(StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     assert(e->store_status == STORE_PENDING);
     assert(mem != NULL);
     debug(20, 6) ("storeAbort: %s\n", storeKeyText(e->hash.key));
-    payloadLockObject(e->p);		/* lock while aborting */
+    storeLockObject(e);
+#ifdef DSA
+    storeNegativeCache(e->mem_obj->e);
+#else
     storeNegativeCache(e);
+#endif
     storeReleaseRequest(e);
     EBIT_SET(e->flags, ENTRY_ABORTED);
-    payloadSetMemStatus(e->p, NOT_IN_MEMORY);
+    storeSetMemStatus(e, NOT_IN_MEMORY);
     e->store_status = STORE_OK;
     /*
      * We assign an object length here.  The only other place we assign
@@ -538,7 +1169,37 @@
     InvokeHandlers(e);
     /* Close any swapout file */
     storeSwapOutFileClose(e);
-    payloadUnlockObject(e->p);	/* unlock */
+    storeUnlockObject(e);	/* unlock */
+}
+
+/* Clear Memory storage to accommodate the given object len */
+static void
+storeGetMemSpace(int size)
+{
+    StoreEntry *e = NULL;
+    int released = 0;
+    static time_t last_check = 0;
+    int pages_needed;
+    RemovalPurgeWalker *walker;
+    if (squid_curtime == last_check)
+	return;
+    last_check = squid_curtime;
+    pages_needed = (size / SM_PAGE_SIZE) + 1;
+    if (memInUse(MEM_STMEM_BUF) + pages_needed < store_pages_max)
+	return;
+    debug(20, 2) ("storeGetMemSpace: Starting, need %d pages\n", pages_needed);
+    /* XXX what to set as max_scan here? */
+    walker = mem_policy->PurgeInit(mem_policy, 100000);
+    while ((e = walker->Next(walker))) {
+	storePurgeMem(e);
+	released++;
+	if (memInUse(MEM_STMEM_BUF) + pages_needed < store_pages_max)
+	    break;
+    }
+    walker->Done(walker);
+    debug(20, 3) ("storeGetMemSpace stats:\n");
+    debug(20, 3) ("  %6d HOT objects\n", hot_obj_count);
+    debug(20, 3) ("  %6d were released\n", released);
 }
 
 /* The maximum objects to scan for maintain storage space */
@@ -580,7 +1241,31 @@
     eventAdd("MaintainSwapSpace", storeMaintainSwapSpace, NULL, 1.0, 1);
 }
 
-
+#ifdef DSA
+/* release an object from a cache */
+void
+instanceRelease(InstanceEntry * e)
+{
+#ifdef DTD
+    /* just memFree bogus StoreEntry */
+    if (e->flags == 0) {
+	memFree(e, MEM_INSTANCEENTRY);
+	return;
+    }
+#endif
+    debug(20, 3) ("storeRelease: Releasing: '%s'\n", storeKeyText(e->hash.key));
+    /* If, for any reason we can't discard this object because of an
+     * outstanding request, mark it for pending release */
+    if (storeEntryLocked(e->p)) {
+	storeExpireNow(e);
+	debug(20, 3) ("storeRelease: Only setting RELEASE_REQUEST bit\n");
+	instanceReleaseRequest(e);
+	return;
+    }
+    storeRemoveInstanceEntry(e->p, e);
+    destroy_InstanceEntry(e);
+}
+#else
 /* release an object from a cache */
 void
 storeRelease(StoreEntry * e)
@@ -594,32 +1279,73 @@
 	storeReleaseRequest(e);
 	return;
     }
-    if (store_dirs_rebuilding && e->p->swap_dirn > -1) {
+    if (store_dirs_rebuilding && e->swap_filen > -1) {
 	storeSetPrivateKey(e);
-	if (e->p->swap_filen > -1) {
+	if (e->mem_obj) {
+	    storeSetMemStatus(e, NOT_IN_MEMORY);
+	    destroy_MemObject(e);
+	}
+	if (e->swap_filen > -1) {
 	    /*
 	     * Fake a call to storeLockObject().  When rebuilding is done,
 	     * we'll just call storeUnlockObject() on these.
 	     */
-	    e->p->lock_count++;
+	    e->lock_count++;
 	    EBIT_SET(e->flags, RELEASE_REQUEST);
+	    stackPush(&LateReleaseStack, e);
 	    return;
 	} else {
 	    destroy_StoreEntry(e);
 	}
     }
     storeLog(STORE_LOG_RELEASE, e);
-    payloadRemoveStoreEntry(e->p, e);
+    if (e->swap_filen > -1) {
+	storeUnlink(e);
+	if (e->swap_status == SWAPOUT_DONE)
+	    if (EBIT_TEST(e->flags, ENTRY_VALIDATED))
+		storeDirUpdateSwapSize(&Config.cacheSwap.swapDirs[e->swap_dirn], e->swap_file_sz, -1);
+	if (!EBIT_TEST(e->flags, KEY_PRIVATE))
+	    storeDirSwapLog(e, SWAP_LOG_DEL);
+#if 0
+	/* From 2.4. I think we do this in storeUnlink? */
+	storeSwapFileNumberSet(e, -1);
+#endif
+    }
+    storeSetMemStatus(e, NOT_IN_MEMORY);
     destroy_StoreEntry(e);
 }
+#endif
+
+static void
+storeLateRelease(void *unused)
+{
+    StoreEntry *e;
+    int i;
+    static int n = 0;
+    if (store_dirs_rebuilding) {
+	eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1);
+	return;
+    }
+    for (i = 0; i < 10; i++) {
+	e = stackPop(&LateReleaseStack);
+	if (e == NULL) {
+	    /* done! */
+	    debug(20, 1) ("storeLateRelease: released %d objects\n", n);
+	    return;
+	}
+	storeUnlockObject(e);
+	n++;
+    }
+    eventAdd("storeLateRelease", storeLateRelease, NULL, 0.0, 1);
+}
 
 /* return 1 if a store entry is locked */
 int
 storeEntryLocked(const StoreEntry * e)
 {
-    if (e->p->lock_count)
+    if (e->lock_count)
 	return 1;
-    if (e->p->swap_status == SWAPOUT_WRITING)
+    if (e->swap_status == SWAPOUT_WRITING)
 	return 1;
     if (e->store_status == STORE_PENDING)
 	return 1;
@@ -627,7 +1353,9 @@
      * SPECIAL, PUBLIC entries should be "locked"
      */
     if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
+#ifndef DSA
 	if (!EBIT_TEST(e->flags, KEY_PRIVATE))
+#endif
 	    return 1;
     return 0;
 }
@@ -637,8 +1365,8 @@
 {
     int diff;
     const HttpReply *reply;
-    assert(e->p->mem_obj != NULL);
-    reply = e->p->mem_obj->reply;
+    assert(e->mem_obj != NULL);
+    reply = e->mem_obj->reply;
     debug(20, 3) ("storeEntryValidLength: Checking '%s'\n", storeKeyText(e->hash.key));
     debug(20, 5) ("storeEntryValidLength:     object_len = %d\n",
 	objectLen(e));
@@ -656,7 +1384,7 @@
 	    storeKeyText(e->hash.key));
 	return 1;
     }
-    if (e->p->mem_obj->method == METHOD_HEAD) {
+    if (e->mem_obj->method == METHOD_HEAD) {
 	debug(20, 5) ("storeEntryValidLength: HEAD request: %s\n",
 	    storeKeyText(e->hash.key));
 	return 1;
@@ -700,9 +1428,15 @@
     storeInitHashValues();
     store_table = hash_create(storeKeyHashCmp,
 	store_hash_buckets, storeKeyHashHash);
-    payloadInit();
+#ifdef DSA
+    instance_table = hash_create(storeKeyHashCmp,
+	store_hash_buckets, storeKeyHashHash);
+#endif
+    mem_policy = createRemovalPolicy(Config.memPolicy);
     storeDigestInit();
     storeLogOpen();
+    stackInit(&LateReleaseStack);
+    eventAdd("storeLateRelease", storeLateRelease, NULL, 1.0, 1);
     storeDirInit();
     storeRebuildStart();
     cachemgrRegister("storedir",
@@ -726,8 +1460,23 @@
     store_pages_max = Config.memMaxSize / SM_PAGE_SIZE;
 }
 
+static int
+storeKeepInMemory(const StoreEntry * e)
+{
+    MemObject *mem = e->mem_obj;
+    if (mem == NULL)
+	return 0;
+    if (mem->data_hdr.head == NULL)
+	return 0;
+    return mem->inmem_lo == 0;
+}
+
 void
+#ifdef DSA
+storeNegativeCache(InstanceEntry * e)
+#else
 storeNegativeCache(StoreEntry * e)
+#endif
 {
     e->expires = squid_curtime + Config.negativeTtl;
     EBIT_SET(e->flags, ENTRY_NEGCACHED);
@@ -736,10 +1485,13 @@
 void
 storeFreeMemory(void)
 {
+#ifdef DSA
+    hashFreeMemory(instance_table);
+    instance_table = NULL;
+#endif
     hashFreeItems(store_table, destroy_StoreEntry);
     hashFreeMemory(store_table);
     store_table = NULL;
-    payloadFreeMemory();
 #if USE_CACHE_DIGESTS
     if (store_digest)
 	cacheDigestDestroy(store_digest);
@@ -755,23 +1507,55 @@
     return (expires > (squid_curtime + when));
 }
 
+#ifdef DTD 
+int
+storeValidToSend(StoreEntry * e)
+{
+   if (EBIT_TEST(e->flags, RELEASE_REQUEST))
+	return 0;
+   if (EBIT_TEST(e->flags, ENTRY_NEGCACHED))
+	return 0;
+   if (EBIT_TEST(e->flags, ENTRY_ABORTED))
+       return 0;
+   if (e->store_status == STORE_PENDING)
+       return 0;
+   return 1;
+}
+#endif
+
 int
+#ifdef DSA
+storeEntryValidToSend(InstanceEntry * e)
+#else
 storeEntryValidToSend(StoreEntry * e)
+#endif
 {
     if (EBIT_TEST(e->flags, RELEASE_REQUEST))
 	return 0;
     if (EBIT_TEST(e->flags, ENTRY_NEGCACHED))
 	if (e->expires <= squid_curtime)
 	    return 0;
+#ifdef DSA
+    if (EBIT_TEST(e->p->flags, ENTRY_ABORTED))
+#else
     if (EBIT_TEST(e->flags, ENTRY_ABORTED))
+#endif
 	return 0;
     return 1;
 }
 
 void
+#ifdef DSA
+storeTimestampsSet(InstanceEntry * entry)
+#else	
 storeTimestampsSet(StoreEntry * entry)
+#endif	
 {
+#ifdef DSA	
     const HttpReply *reply = entry->p->mem_obj->reply;
+#else    
+    const HttpReply *reply = entry->mem_obj->reply;
+#endif    
     time_t served_date = reply->date;
     int age = httpHeaderGetInt(&reply->header, HDR_AGE);
     /*
@@ -802,7 +1586,7 @@
 void
 storeRegisterAbort(StoreEntry * e, STABH * cb, void *data)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     assert(mem);
     assert(mem->abort.callback == NULL);
     mem->abort.callback = cb;
@@ -812,7 +1596,7 @@
 void
 storeUnregisterAbort(StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     assert(mem);
     mem->abort.callback = NULL;
 }
@@ -851,16 +1635,58 @@
 {
     debug(20, l) ("StoreEntry->key: %s\n", storeKeyText(e->hash.key));
     debug(20, l) ("StoreEntry->next: %p\n", e->hash.next);
-    debug(20, l) ("StoreEntry->mem_obj: %p\n", e->p->mem_obj);
+    debug(20, l) ("StoreEntry->mem_obj: %p\n", e->mem_obj);
+    debug(20, l) ("StoreEntry->lastref: %d\n", (int) e->lastref);
+#ifndef DSA    
     debug(20, l) ("StoreEntry->timestamp: %d\n", (int) e->timestamp);
     debug(20, l) ("StoreEntry->expires: %d\n", (int) e->expires);
     debug(20, l) ("StoreEntry->lastmod: %d\n", (int) e->lastmod);
+#endif
+    debug(20, l) ("StoreEntry->swap_file_sz: %d\n", (int) e->swap_file_sz);
+    debug(20, l) ("StoreEntry->refcount: %d\n", e->refcount);
     debug(20, l) ("StoreEntry->flags: %s\n", storeEntryFlags(e));
-    debug(20, l) ("StoreEntry->lock_count: %d\n", (int) e->p->lock_count);
-    debug(20, l) ("StoreEntry->mem_status: %d\n", (int) e->p->mem_status);
+    debug(20, l) ("StoreEntry->swap_dirn: %d\n", (int) e->swap_dirn);
+    debug(20, l) ("StoreEntry->swap_filen: %d\n", (int) e->swap_filen);
+    debug(20, l) ("StoreEntry->lock_count: %d\n", (int) e->lock_count);
+    debug(20, l) ("StoreEntry->mem_status: %d\n", (int) e->mem_status);
     debug(20, l) ("StoreEntry->ping_status: %d\n", (int) e->ping_status);
     debug(20, l) ("StoreEntry->store_status: %d\n", (int) e->store_status);
-//    debug(20, l) ("StoreEntry->swap_status: %d\n", (int) e->swap_status);
+    debug(20, l) ("StoreEntry->swap_status: %d\n", (int) e->swap_status);
+}
+
+/*
+ * NOTE, this function assumes only two mem states
+ */
+void
+storeSetMemStatus(StoreEntry * e, int new_status)
+{
+    MemObject *mem = e->mem_obj;
+    if (new_status == e->mem_status)
+	return;
+    assert(mem != NULL);
+    if (new_status == IN_MEMORY) {
+	assert(mem->inmem_lo == 0);
+	if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) {
+	    debug(20, 4) ("storeSetMemStatus: not inserting special %s into policy\n",
+		mem->url);
+	} else {
+	    mem_policy->Add(mem_policy, e, &mem->repl);
+	    debug(20, 4) ("storeSetMemStatus: inserted mem node %s\n",
+		mem->url);
+	}
+	hot_obj_count++;
+    } else {
+	if (EBIT_TEST(e->flags, ENTRY_SPECIAL)) {
+	    debug(20, 4) ("storeSetMemStatus: special entry %s\n",
+		mem->url);
+	} else {
+	    mem_policy->Remove(mem_policy, e, &mem->repl);
+	    debug(20, 4) ("storeSetMemStatus: removed mem node %s\n",
+		mem->url);
+	}
+	hot_obj_count--;
+    }
+    e->mem_status = new_status;
 }
 
 const char *
@@ -868,10 +1694,18 @@
 {
     if (e == NULL)
 	return "[null_entry]";
-    else if (e->p->mem_obj == NULL)
+    else if (e->mem_obj == NULL)
 	return "[null_mem_obj]";
     else
-	return e->p->mem_obj->url;
+	return e->mem_obj->url;
+}
+
+void
+storeCreateMemObject(StoreEntry * e, const char *url, const char *log_url)
+{
+    if (e->mem_obj)
+	return;
+    e->mem_obj = new_MemObject(url, log_url);
 }
 
 /* this just sets DELAY_SENDING */
@@ -893,16 +1727,16 @@
 int
 objectLen(const StoreEntry * e)
 {
-    assert(e->p->mem_obj != NULL);
-    return e->p->mem_obj->object_sz;
+    assert(e->mem_obj != NULL);
+    return e->mem_obj->object_sz;
 }
 
 int
 contentLen(const StoreEntry * e)
 {
-    assert(e->p->mem_obj != NULL);
-    assert(e->p->mem_obj->reply != NULL);
-    return e->p->mem_obj->object_sz - e->p->mem_obj->reply->hdr_sz;
+    assert(e->mem_obj != NULL);
+    assert(e->mem_obj->reply != NULL);
+    return e->mem_obj->object_sz - e->mem_obj->reply->hdr_sz;
 }
 
 HttpReply *
@@ -910,22 +1744,24 @@
 {
     if (NULL == e)
 	return NULL;
-    if (NULL == e->p->mem_obj)
+    if (NULL == e->mem_obj)
 	return NULL;
-    return e->p->mem_obj->reply;
+    return e->mem_obj->reply;
 }
 
 void
 storeEntryReset(StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     debug(20, 3) ("storeEntryReset: %s\n", storeUrl(e));
     assert(mem->swapout.sio == NULL);
     stmemFree(&mem->data_hdr);
     mem->inmem_hi = mem->inmem_lo = 0;
     httpReplyDestroy(mem->reply);
     mem->reply = httpReplyCreate();
+#ifndef DSA    
     e->expires = e->lastmod = e->timestamp = -1;
+#endif
 }
 
 /*
@@ -977,6 +1813,42 @@
     setup(&storefs_list[i]);
 }
 
+/*
+ * called to add another store removal policy module
+ */
+void
+storeReplAdd(char *type, REMOVALPOLICYCREATE * create)
+{
+    int i;
+    /* find the number of currently known repl types */
+    for (i = 0; storerepl_list && storerepl_list[i].typestr; i++) {
+	assert(strcmp(storerepl_list[i].typestr, type) != 0);
+    }
+    /* add the new type */
+    storerepl_list = xrealloc(storerepl_list, (i + 2) * sizeof(storerepl_entry_t));
+    memset(&storerepl_list[i + 1], 0, sizeof(storerepl_entry_t));
+    storerepl_list[i].typestr = type;
+    storerepl_list[i].create = create;
+}
+
+/*
+ * Create a removal policy instance
+ */
+RemovalPolicy *
+createRemovalPolicy(RemovalPolicySettings * settings)
+{
+    storerepl_entry_t *r;
+    for (r = storerepl_list; r && r->typestr; r++) {
+	if (strcmp(r->typestr, settings->type) == 0)
+	    return r->create(settings->args);
+    }
+    debug(20, 1) ("ERROR: Unknown policy %s\n", settings->type);
+    debug(20, 1) ("ERROR: Be sure to have set cache_replacement_policy\n");
+    debug(20, 1) ("ERROR:   and memory_replacement_policy in squid.conf!\n");
+    fatalf("ERROR: Unknown policy %s\n", settings->type);
+    return NULL;
+}
+
 #if 0
 void
 storeSwapFileNumberSet(StoreEntry * e, sfileno filn)
Index: squid/src/store_client.c
diff -u squid/src/store_client.c:1.4.4.1.6.1 squid/src/store_client.c:1.4.4.1.8.4
--- squid/src/store_client.c:1.4.4.1.6.1	Wed Aug 14 03:15:35 2002
+++ squid/src/store_client.c	Sun Dec 22 16:13:28 2002
@@ -55,7 +55,7 @@
 int
 storeClientWaiting(const StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     dlink_node *node;
     store_client *sc;
     for (node = mem->clients.head; node; node = node->next) {
@@ -84,7 +84,7 @@
 static store_client_t
 storeClientType(StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     if (mem->inmem_lo)
 	return STORE_DISK_CLIENT;
     if (EBIT_TEST(e->flags, ENTRY_ABORTED)) {
@@ -110,7 +110,7 @@
      * to the client, there is no guarantee that we will be able
      * to open it later when we really need it.
      */
-    else if (e->p->swap_status == SWAPOUT_NONE)
+    else if (e->swap_status == SWAPOUT_NONE)
 	return STORE_MEM_CLIENT;
     /*
      * otherwise, make subsequent clients read from disk so they
@@ -124,14 +124,14 @@
 store_client *
 storeClientListAdd(StoreEntry * e, void *data)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     store_client *sc;
     assert(mem);
 #if STORE_CLIENT_LIST_DEBUG
     if (storeClientListSearch(mem, data) != NULL)
 	assert(1 == 0);		/* XXX die! */
 #endif
-    e->p->refcount++;
+    e->refcount++;
     mem->nclients++;
     sc = memAllocate(MEM_STORE_CLIENT);
     cbdataAdd(sc, memFree, MEM_STORE_CLIENT);	/* sc is callback_data for file_read */
@@ -145,7 +145,7 @@
     if (sc->type == STORE_DISK_CLIENT)
 	/* assert we'll be able to get the data we want */
 	/* maybe we should open swapin_fd here */
-	assert(e->p->swap_filen > -1 || storeSwapOutAble(e));
+	assert(e->swap_filen > -1 || storeSwapOutAble(e));
     dlinkAdd(sc, &sc->node, &mem->clients);
 #if DELAY_POOLS
     sc->delay_id = 0;
@@ -187,6 +187,8 @@
     STCB * callback,
     void *data)
 {
+    if (!EBIT_TEST(e->flags, KEY_PRIVATE))
+	assert(e->hash.key);    
     assert(!EBIT_TEST(e->flags, ENTRY_ABORTED));
     debug(20, 3) ("storeClientCopy: %s, seen %d, want %d, size %d, cb %p, cbdata %p\n",
 	storeKeyText(e->hash.key),
@@ -266,7 +268,7 @@
 static void
 storeClientCopy3(StoreEntry * e, store_client * sc)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     size_t sz;
 
     if (storeClientNoMoreToSend(e, sc)) {
@@ -331,7 +333,7 @@
 static void
 storeClientFileRead(store_client * sc)
 {
-    MemObject *mem = sc->entry->p->mem_obj;
+    MemObject *mem = sc->entry->mem_obj;
     assert(sc->callback != NULL);
     assert(!sc->flags.disk_io_pending);
     sc->flags.disk_io_pending = 1;
@@ -343,7 +345,7 @@
 	    storeClientReadHeader,
 	    sc);
     } else {
-	if (sc->entry->p->swap_status == SWAPOUT_WRITING)
+	if (sc->entry->swap_status == SWAPOUT_WRITING)
 	    assert(storeOffset(mem->swapout.sio) > sc->copy_offset + mem->swap_hdr_sz);
 	storeRead(sc->swapin_sio,
 	    sc->copy_buf,
@@ -358,7 +360,7 @@
 storeClientReadBody(void *data, const char *buf, ssize_t len)
 {
     store_client *sc = data;
-    MemObject *mem = sc->entry->p->mem_obj;
+    MemObject *mem = sc->entry->mem_obj;
     assert(sc->flags.disk_io_pending);
     sc->flags.disk_io_pending = 0;
     assert(sc->callback != NULL);
@@ -374,7 +376,7 @@
     static int md5_mismatches = 0;
     store_client *sc = data;
     StoreEntry *e = sc->entry;
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     int swap_hdr_sz = 0;
     size_t body_sz;
     size_t copy_sz;
@@ -409,11 +411,11 @@
 	switch (t->type) {
 	case STORE_META_KEY:
 	    assert(t->length == MD5_DIGEST_CHARS);
-	    if (!EBIT_TEST(e->p->flags, KEY_PRIVATE) &&
-		memcmp(t->value, e->p->hash.key, MD5_DIGEST_CHARS)) {
+	    if (!EBIT_TEST(e->flags, KEY_PRIVATE) &&
+		memcmp(t->value, e->hash.key, MD5_DIGEST_CHARS)) {
 		debug(20, 2) ("storeClientReadHeader: swapin MD5 mismatch\n");
 		debug(20, 2) ("\t%s\n", storeKeyText(t->value));
-		debug(20, 2) ("\t%s\n", storeKeyText(e->p->hash.key));
+		debug(20, 2) ("\t%s\n", storeKeyText(e->hash.key));
 		if (isPowTen(++md5_mismatches))
 		    debug(20, 1) ("WARNING: %d swapin MD5 mismatches\n",
 			md5_mismatches);
@@ -445,7 +447,7 @@
 	return;
     }
     mem->swap_hdr_sz = swap_hdr_sz;
-    mem->object_sz = e->p->swap_file_sz - swap_hdr_sz;
+    mem->object_sz = e->swap_file_sz - swap_hdr_sz;
     /*
      * If our last read got some data the client wants, then give
      * it to them, otherwise schedule another read.
@@ -493,9 +495,9 @@
 int
 storeUnregister(store_client * sc, StoreEntry * e, void *data)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
 #if STORE_CLIENT_LIST_DEBUG
-    assert(sc == storeClientListSearch(e->p->mem_obj, data));
+    assert(sc == storeClientListSearch(e->mem_obj, data));
 #endif
     if (mem == NULL)
 	return 0;
@@ -513,7 +515,7 @@
     }
     dlinkDelete(&sc->node, &mem->clients);
     mem->nclients--;
-    if (e->store_status == STORE_OK && e->p->swap_status != SWAPOUT_DONE)
+    if (e->store_status == STORE_OK && e->swap_status != SWAPOUT_DONE)
 	storeSwapOut(e);
     if (sc->swapin_sio) {
 	storeClose(sc->swapin_sio);
@@ -533,7 +535,7 @@
     cbdataUnlock(sc->callback_data);	/* we're done with it now */
     /*assert(!sc->flags.disk_io_pending); */
     cbdataFree(sc);
-    assert(e->p->lock_count > 0);
+    assert(e->lock_count > 0);
     if (mem->nclients == 0)
 	CheckQuickAbort(e);
     return 1;
@@ -542,7 +544,7 @@
 off_t
 storeLowestMemReaderOffset(const StoreEntry * entry)
 {
-    const MemObject *mem = entry->p->mem_obj;
+    const MemObject *mem = entry->mem_obj;
     off_t lowest = mem->inmem_hi + 1;
     store_client *sc;
     dlink_node *nx = NULL;
@@ -569,12 +571,11 @@
 InvokeHandlers(StoreEntry * e)
 {
     int i = 0;
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     store_client *sc;
     dlink_node *nx = NULL;
     dlink_node *node;
 
-    if (mem == NULL) return;
     debug(20, 3) ("InvokeHandlers: %s\n", storeKeyText(e->hash.key));
     /* walk the entire list looking for valid callbacks */
     for (node = mem->clients.head; node; node = nx) {
@@ -594,7 +595,7 @@
 int
 storePendingNClients(const StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     int npend = NULL == mem ? 0 : mem->nclients;
     debug(20, 3) ("storePendingNClients: returning %d\n", npend);
     return npend;
@@ -607,7 +608,7 @@
     int curlen;
     int minlen;
     int expectlen;
-    MemObject *mem = entry->p->mem_obj;
+    MemObject *mem = entry->mem_obj;
     assert(mem);
     debug(20, 3) ("CheckQuickAbort2: entry=%p, mem=%p\n", entry, mem);
     if (mem->request && !mem->request->flags.cachable) {
Index: squid/src/store_dir.c
diff -u squid/src/store_dir.c:1.4.4.7.4.1 squid/src/store_dir.c:1.4.4.7
--- squid/src/store_dir.c:1.4.4.7.4.1	Wed Aug 14 03:15:36 2002
+++ squid/src/store_dir.c	Thu Mar 29 04:02:12 2001
@@ -146,7 +146,7 @@
 	if (!storeDirValidSwapDirSize(i, objsize))
 	    continue;
 	/* check for error or overload condition */
-	load = sd->checkobj(sd, e->p);
+	load = sd->checkobj(sd, e);
 	if (load < 0 || load > 1000) {
 	    continue;
 	}
@@ -183,11 +183,11 @@
     /* Calculate the object size */
     objsize = (ssize_t) objectLen(e);
     if (objsize != -1)
-	objsize += e->p->mem_obj->swap_hdr_sz;
+	objsize += e->mem_obj->swap_hdr_sz;
     for (i = 0; i < Config.cacheSwap.n_configured; i++) {
 	SD = &Config.cacheSwap.swapDirs[i];
 	SD->flags.selected = 0;
-	load = SD->checkobj(SD, e->p);
+	load = SD->checkobj(SD, e);
 	if (load < 0 || load > 1000) {
 	    continue;
 	}
@@ -239,23 +239,24 @@
  *   2.  It MUST have a valid (> -1) swap_filen.
  */
 void
-storeDirSwapLog(const PayloadEntry * p, int op)
+storeDirSwapLog(const StoreEntry * e, int op)
 {
     SwapDir *sd;
-    assert(p->swap_filen >= 0);
+    assert(!EBIT_TEST(e->flags, KEY_PRIVATE));
+    assert(e->swap_filen >= 0);
     /*
      * icons and such; don't write them to the swap log
      */
-    if (EBIT_TEST(p->flags, ENTRY_SPECIAL))
+    if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
 	return;
     assert(op > SWAP_LOG_NOP && op < SWAP_LOG_MAX);
     debug(20, 3) ("storeDirSwapLog: %s %s %d %08X\n",
 	swap_log_op_str[op],
-	storeKeyText(p->hash.key),
-	p->swap_dirn,
-	p->swap_filen);
-    sd = &Config.cacheSwap.swapDirs[p->swap_dirn];
-    sd->log.write(sd, p, op);
+	storeKeyText(e->hash.key),
+	e->swap_dirn,
+	e->swap_filen);
+    sd = &Config.cacheSwap.swapDirs[e->swap_dirn];
+    sd->log.write(sd, e, op);
 }
 
 void
@@ -363,7 +364,7 @@
 int
 storeDirWriteCleanLogs(int reopen)
 {
-    const PayloadEntry *p = NULL;
+    const StoreEntry *e = NULL;
     int n = 0;
     struct timeval start;
     double dt;
@@ -391,17 +392,23 @@
 	    sd = &Config.cacheSwap.swapDirs[dirn];
 	    if (NULL == sd->log.clean.write)
 		continue;
-	    p = sd->log.clean.nextentry(sd);
-	    if (!p)
+	    e = sd->log.clean.nextentry(sd);
+	    if (!e)
 		continue;
 	    notdone = 1;
-	    if (p->swap_filen < 0)
+	    if (e->swap_filen < 0)
 		continue;
-	    if (p->swap_file_sz <= 0)
+	    if (e->swap_status != SWAPOUT_DONE)
 		continue;
-	    if (EBIT_TEST(p->flags, ENTRY_SPECIAL))
+	    if (e->swap_file_sz <= 0)
 		continue;
-	    sd->log.clean.write(sd, p);
+	    if (EBIT_TEST(e->flags, RELEASE_REQUEST))
+		continue;
+	    if (EBIT_TEST(e->flags, KEY_PRIVATE))
+		continue;
+	    if (EBIT_TEST(e->flags, ENTRY_SPECIAL))
+		continue;
+	    sd->log.clean.write(sd, e);
 	    if ((++n & 0xFFFF) == 0) {
 		getCurrentTime();
 		debug(20, 1) ("  %7d entries written so far.\n", n);
Index: squid/src/store_io.c
diff -u squid/src/store_io.c:1.2.64.1 squid/src/store_io.c:1.2
--- squid/src/store_io.c:1.2.64.1	Wed Aug 14 03:15:36 2002
+++ squid/src/store_io.c	Sat Oct 21 08:16:13 2000
@@ -29,7 +29,7 @@
     /* This is just done for logging purposes */
     objsize = objectLen(e);
     if (objsize != -1)
-	objsize += e->p->mem_obj->swap_hdr_sz;
+	objsize += e->mem_obj->swap_hdr_sz;
 
     /*
      * Pick the swapdir
@@ -61,7 +61,7 @@
 storeOpen(StoreEntry * e, STFNCB * file_callback, STIOCB * callback,
     void *callback_data)
 {
-    SwapDir *SD = &Config.cacheSwap.swapDirs[e->p->swap_dirn];
+    SwapDir *SD = &Config.cacheSwap.swapDirs[e->swap_dirn];
     return SD->obj.open(SD, e, file_callback, callback, callback_data);
 }
 
@@ -92,7 +92,7 @@
 void
 storeUnlink(StoreEntry * e)
 {
-    SwapDir *SD = INDEXSD(e->p->swap_dirn);
+    SwapDir *SD = INDEXSD(e->swap_dirn);
     SD->obj.unlink(SD, e);
 }
 
Index: squid/src/store_key_md5.c
diff -u squid/src/store_key_md5.c:1.4.4.1 squid/src/store_key_md5.c:1.4.4.1.6.1
--- squid/src/store_key_md5.c:1.4.4.1	Mon Jan 15 14:49:20 2001
+++ squid/src/store_key_md5.c	Sun Dec 22 16:13:28 2002
@@ -153,6 +153,7 @@
 int
 storeKeyNull(const cache_key * key)
 {
+    assert(key);	
     if (memcmp(key, null_key, MD5_DIGEST_CHARS) == 0)
 	return 1;
     else
Index: squid/src/store_log.c
diff -u squid/src/store_log.c:1.4.4.1.8.1 squid/src/store_log.c:1.4.4.1
--- squid/src/store_log.c:1.4.4.1.8.1	Wed Aug 14 03:15:36 2002
+++ squid/src/store_log.c	Mon Jan 15 14:49:20 2001
@@ -49,7 +49,7 @@
 void
 storeLog(int tag, const StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     HttpReply *reply;
     if (NULL == storelog)
 	return;
@@ -71,8 +71,8 @@
 	    (int) current_time.tv_sec,
 	    (int) current_time.tv_usec / 1000,
 	    storeLogTags[tag],
-	    e->p->swap_dirn,
-	    e->p->swap_filen,
+	    e->swap_dirn,
+	    e->swap_filen,
 	    storeKeyText(e->hash.key),
 	    reply->sline.status,
 	    (int) reply->date,
@@ -89,8 +89,8 @@
 	    (int) current_time.tv_sec,
 	    (int) current_time.tv_usec / 1000,
 	    storeLogTags[tag],
-	    e->p->swap_dirn,
-	    e->p->swap_filen,
+	    e->swap_dirn,
+	    e->swap_filen,
 	    storeKeyText(e->hash.key));
     }
 }
Index: squid/src/store_rebuild.c
diff -u squid/src/store_rebuild.c:1.5.2.2.8.1 squid/src/store_rebuild.c:1.5.2.2
--- squid/src/store_rebuild.c:1.5.2.2.8.1	Wed Aug 14 03:15:37 2002
+++ squid/src/store_rebuild.c	Mon Jan 15 14:49:20 2001
@@ -51,8 +51,8 @@
 static int
 storeCleanupDoubleCheck(StoreEntry * e)
 {
-    SwapDir *SD = &Config.cacheSwap.swapDirs[e->p->swap_dirn];
-    return (SD->dblcheck(SD, e->p));
+    SwapDir *SD = &Config.cacheSwap.swapDirs[e->swap_dirn];
+    return (SD->dblcheck(SD, e));
 }
 
 static void
@@ -62,7 +62,7 @@
     static int validnum = 0;
     static int store_errors = 0;
     int validnum_start;
-    PayloadEntry *p;
+    StoreEntry *e;
     hash_link *link_ptr = NULL;
     hash_link *link_next = NULL;
     validnum_start = validnum;
@@ -79,29 +79,27 @@
 		storeDigestNoteStoreReady();
 	    return;
 	}
-	link_next = hash_get_bucket(payload_table, bucketnum);
+	link_next = hash_get_bucket(store_table, bucketnum);
 	while (NULL != (link_ptr = link_next)) {
 	    link_next = link_ptr->next;
-	    p = (PayloadEntry *) link_ptr;
-	    if (EBIT_TEST(p->flags, ENTRY_VALIDATED))
+	    e = (StoreEntry *) link_ptr;
+	    if (EBIT_TEST(e->flags, ENTRY_VALIDATED))
 		continue;
 	    /*
 	     * Calling storeRelease() has no effect because we're
 	     * still in 'store_rebuilding' state
 	     */
-	    if (p->swap_filen < 0)
+	    if (e->swap_filen < 0)
 		continue;
-	    /*
 	    if (opt_store_doublecheck)
 		if (storeCleanupDoubleCheck(e))
 		    store_errors++;
-		    */
-	    EBIT_SET(p->flags, ENTRY_VALIDATED);
+	    EBIT_SET(e->flags, ENTRY_VALIDATED);
 	    /*
 	     * Only set the file bit if we know its a valid entry
 	     * otherwise, set it in the validation procedure
 	     */
-	    storeDirUpdateSwapSize(&Config.cacheSwap.swapDirs[p->swap_dirn], p->swap_file_sz, 1);
+	    storeDirUpdateSwapSize(&Config.cacheSwap.swapDirs[e->swap_dirn], e->swap_file_sz, 1);
 	    if ((++validnum & 0x3FFFF) == 0)
 		debug(20, 1) ("  %7d Entries Validated so far.\n", validnum);
 	}
Index: squid/src/store_swapin.c
diff -u squid/src/store_swapin.c:1.4.4.1.8.1 squid/src/store_swapin.c:1.4.4.1
--- squid/src/store_swapin.c:1.4.4.1.8.1	Wed Aug 14 03:15:37 2002
+++ squid/src/store_swapin.c	Mon Jan 15 14:49:20 2001
@@ -42,25 +42,25 @@
 storeSwapInStart(store_client * sc)
 {
     StoreEntry *e = sc->entry;
-    assert(e->p->mem_status == NOT_IN_MEMORY);
-    if (!EBIT_TEST(e->p->flags, ENTRY_VALIDATED)) {
+    assert(e->mem_status == NOT_IN_MEMORY);
+    if (!EBIT_TEST(e->flags, ENTRY_VALIDATED)) {
 	/* We're still reloading and haven't validated this entry yet */
 	return;
     }
     debug(20, 3) ("storeSwapInStart: called for %d %08X %s \n",
-	e->p->swap_dirn, e->p->swap_filen, storeKeyText(e->hash.key));
-    if (e->p->swap_status != SWAPOUT_WRITING && e->p->swap_status != SWAPOUT_DONE) {
+	e->swap_dirn, e->swap_filen, storeKeyText(e->hash.key));
+    if (e->swap_status != SWAPOUT_WRITING && e->swap_status != SWAPOUT_DONE) {
 	debug(20, 1) ("storeSwapInStart: bad swap_status (%s)\n",
-	    swapStatusStr[e->p->swap_status]);
+	    swapStatusStr[e->swap_status]);
 	return;
     }
-    if (e->p->swap_filen < 0) {
+    if (e->swap_filen < 0) {
 	debug(20, 1) ("storeSwapInStart: swap_filen < 0\n");
 	return;
     }
-    assert(e->p->mem_obj != NULL);
+    assert(e->mem_obj != NULL);
     debug(20, 3) ("storeSwapInStart: Opening fileno %08X\n",
-	e->p->swap_filen);
+	e->swap_filen);
     sc->swapin_sio = storeOpen(e, storeSwapInFileNotify, storeSwapInFileClosed,
 	sc);
     cbdataLock(sc->swapin_sio);
@@ -89,8 +89,8 @@
     store_client *sc = data;
     StoreEntry *e = sc->entry;
 
-    debug(1, 3) ("storeSwapInFileNotify: changing %d/%d to %d/%d\n", e->p->swap_filen, e->p->swap_dirn, sio->swap_filen, sio->swap_dirn);
+    debug(1, 3) ("storeSwapInFileNotify: changing %d/%d to %d/%d\n", e->swap_filen, e->swap_dirn, sio->swap_filen, sio->swap_dirn);
 
-    e->p->swap_filen = sio->swap_filen;
-    e->p->swap_dirn = sio->swap_dirn;
+    e->swap_filen = sio->swap_filen;
+    e->swap_dirn = sio->swap_dirn;
 }
Index: squid/src/store_swapmeta.c
diff -u squid/src/store_swapmeta.c:1.4.4.2.4.1 squid/src/store_swapmeta.c:1.4.4.2.6.2
--- squid/src/store_swapmeta.c:1.4.4.2.4.1	Wed Aug 14 03:15:37 2002
+++ squid/src/store_swapmeta.c	Sun Nov 17 21:44:13 2002
@@ -62,32 +62,25 @@
  * Build a TLV list for a StoreEntry
  */
 tlv *
-storeInstanceSwapMetaBuild(StoreEntry * e)
+storeSwapMetaBuild(StoreEntry * e)
 {
     tlv *TLV = NULL;		/* we'll return this */
     tlv **T = &TLV;
+#ifdef DSA    
+    assert(e->mem_obj != NULL);
+    assert(e->swap_status == SWAPOUT_WRITING);
+    T = storeSwapTLVAdd(STORE_META_KEY, e->hash.key, MD5_DIGEST_CHARS, T);
+    T = storeSwapTLVAdd(STORE_META_STD, &e->lastref, STORE_HDR_METASIZE, T);
+#else    
     const char *url;
+    assert(e->mem_obj != NULL);
+    assert(e->swap_status == SWAPOUT_WRITING);
     url = storeUrl(e);
-    assert(e->p->mem_obj != NULL);
     debug(20, 3) ("storeSwapMetaBuild: %s\n", url);
     T = storeSwapTLVAdd(STORE_META_KEY, e->hash.key, MD5_DIGEST_CHARS, T);
     T = storeSwapTLVAdd(STORE_META_STD, &e->timestamp, STORE_HDR_METASIZE, T);
     T = storeSwapTLVAdd(STORE_META_URL, url, strlen(url) + 1, T);
-    return TLV;
-}
-
-tlv *
-storeSwapMetaBuild(StoreEntry * e)
-{
-    tlv *TLV = NULL;		/* we'll return this */
-    tlv **T = &TLV;
-    cache_key dummy_key[MD5_DIGEST_CHARS];
-    memset(dummy_key, '\0', MD5_DIGEST_CHARS);
-    assert(e->p->mem_obj != NULL);
-    assert(EBIT_TEST(e->p->flags, ENTRY_VALIDATED));
-    assert(e->p->swap_status == SWAPOUT_WRITING);
-    T = storeSwapTLVAdd(STORE_META_KEY, dummy_key, MD5_DIGEST_CHARS, T);
-    T = storeSwapTLVAdd(STORE_META_STD, &e->p->lastref, PAYLOAD_HDR_METASIZE, T);
+#endif    
     return TLV;
 }
 
@@ -166,3 +159,23 @@
     *hdr_len = buflen;
     return TLV;
 }
+
+#ifdef DSA
+/*
+ * Build a TLV list for a StoreEntry
+ */
+tlv *
+instanceSwapMetaBuild(InstanceEntry * e)
+{
+    tlv *TLV = NULL;		/* we'll return this */
+    tlv **T = &TLV;
+    const char *url;
+    url = storeUrl(e->p);
+    assert(e->p->mem_obj != NULL);
+    debug(20, 3) ("storeSwapMetaBuild: %s\n", url);
+    T = storeSwapTLVAdd(STORE_META_KEY, e->hash.key, MD5_DIGEST_CHARS, T);
+    T = storeSwapTLVAdd(STORE_META_STD, &e->timestamp, INSTANCE_HDR_METASIZE, T);
+    T = storeSwapTLVAdd(STORE_META_URL, url, strlen(url) + 1, T);
+    return TLV;
+}
+#endif
Index: squid/src/store_swapout.c
diff -u squid/src/store_swapout.c:1.4.4.2.2.1 squid/src/store_swapout.c:1.4.4.2.4.11.2.2
--- squid/src/store_swapout.c:1.4.4.2.2.1	Wed Aug 14 03:15:37 2002
+++ squid/src/store_swapout.c	Thu Jan  2 22:33:34 2003
@@ -45,7 +45,7 @@
 storeSwapOutStart(StoreEntry * e)
 {
     generic_cbdata *c;
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     int swap_hdr_sz = 0;
     tlv *tlv_list;
     char *buf;
@@ -54,8 +54,8 @@
      * metadata there is to store
      */
     debug(20, 5) ("storeSwapOutStart: Begin SwapOut '%s' to dirno %d, fileno %08X\n",
-	storeUrl(e), e->p->swap_dirn, e->p->swap_filen);
-    e->p->swap_status = SWAPOUT_WRITING;
+	storeUrl(e), e->swap_dirn, e->swap_filen);
+    e->swap_status = SWAPOUT_WRITING;
     tlv_list = storeSwapMetaBuild(e);
     buf = storeSwapMetaPack(tlv_list, &swap_hdr_sz);
     storeSwapTLVFree(tlv_list);
@@ -66,17 +66,17 @@
     cbdataAdd(c, memFree, MEM_GEN_CBDATA);
     mem->swapout.sio = storeCreate(e, storeSwapOutFileNotify, storeSwapOutFileClosed, c);
     if (NULL == mem->swapout.sio) {
-	e->p->swap_status = SWAPOUT_NONE;
+	e->swap_status = SWAPOUT_NONE;
 	cbdataFree(c);
 	xfree(buf);
 	storeLog(STORE_LOG_SWAPOUTFAIL, e);
 	return;
     }
-    payloadLockObject(e->p);		/* Don't lock until after create, or the replacement
+    storeLockObject(e);		/* Don't lock until after create, or the replacement
 				 * code might get confused */
     /* Pick up the file number if it was assigned immediately */
-    e->p->swap_filen = mem->swapout.sio->swap_filen;
-    e->p->swap_dirn = mem->swapout.sio->swap_dirn;
+    e->swap_filen = mem->swapout.sio->swap_filen;
+    e->swap_dirn = mem->swapout.sio->swap_dirn;
     /* write out the swap metadata */
     cbdataLock(mem->swapout.sio);
     storeWrite(mem->swapout.sio, buf, mem->swap_hdr_sz, 0, xfree);
@@ -87,19 +87,19 @@
 {
     generic_cbdata *c = data;
     StoreEntry *e = c->data;
-    MemObject *mem = e->p->mem_obj;
-    assert(e->p->swap_status == SWAPOUT_WRITING);
+    MemObject *mem = e->mem_obj;
+    assert(e->swap_status == SWAPOUT_WRITING);
     assert(mem);
     assert(mem->swapout.sio == sio);
     assert(errflag == 0);
-    e->p->swap_filen = mem->swapout.sio->swap_filen;
-    e->p->swap_dirn = mem->swapout.sio->swap_dirn;
+    e->swap_filen = mem->swapout.sio->swap_filen;
+    e->swap_dirn = mem->swapout.sio->swap_dirn;
 }
 
 void
 storeSwapOut(StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     off_t lowest_offset;
     off_t new_mem_lo;
     off_t on_disk = 0;
@@ -172,7 +172,7 @@
     }
     stmemFreeDataUpto(&mem->data_hdr, new_mem_lo);
     mem->inmem_lo = new_mem_lo;
-    if (e->p->swap_status == SWAPOUT_WRITING)
+    if (e->swap_status == SWAPOUT_WRITING)
 	assert(mem->inmem_lo <= on_disk);
     if (!storeSwapOutAble(e))
 	return;
@@ -195,7 +195,7 @@
 	    return;
     }
     /* Ok, we have stuff to swap out.  Is there a swapout.sio open? */
-    if (e->p->swap_status == SWAPOUT_NONE) {
+    if (e->swap_status == SWAPOUT_NONE) {
 	assert(mem->swapout.sio == NULL);
 	assert(mem->inmem_lo == 0);
 	if (storeCheckCachable(e))
@@ -238,7 +238,7 @@
 	mem->swapout.queue_offset += swap_buf_len;
 	storeWrite(mem->swapout.sio, mem->swapout.memnode->data, swap_buf_len, -1, NULL);
 	/* the storeWrite() call might generate an error */
-	if (e->p->swap_status != SWAPOUT_WRITING)
+	if (e->swap_status != SWAPOUT_WRITING)
 	    break;
 	swapout_size = (ssize_t) (mem->inmem_hi - mem->swapout.queue_offset);
 	if (e->store_status == STORE_PENDING)
@@ -262,7 +262,7 @@
 void
 storeSwapOutFileClose(StoreEntry * e)
 {
-    MemObject *mem = e->p->mem_obj;
+    MemObject *mem = e->mem_obj;
     assert(mem != NULL);
     debug(20, 3) ("storeSwapOutFileClose: %s\n", storeKeyText(e->hash.key));
     debug(20, 3) ("storeSwapOutFileClose: sio = %p\n", mem->swapout.sio);
@@ -276,31 +276,32 @@
 {
     generic_cbdata *c = data;
     StoreEntry *e = c->data;
-    MemObject *mem = e->p->mem_obj;
-    assert(e->p->swap_status == SWAPOUT_WRITING);
+    MemObject *mem = e->mem_obj;
+    assert(e->swap_status == SWAPOUT_WRITING);
     cbdataFree(c);
     if (errflag) {
 	debug(20, 1) ("storeSwapOutFileClosed: dirno %d, swapfile %08X, errflag=%d\n\t%s\n",
-	    e->p->swap_dirn, e->p->swap_filen, errflag, xstrerror());
+	    e->swap_dirn, e->swap_filen, errflag, xstrerror());
 	if (errflag == DISK_NO_SPACE_LEFT) {
-	    storeDirDiskFull(e->p->swap_dirn);
+	    storeDirDiskFull(e->swap_dirn);
 	    storeDirConfigure();
 	    storeConfigure();
 	}
-	if (e->p->swap_filen > 0)
+	if (e->swap_filen > 0)
 	    storeUnlink(e);
-	e->p->swap_filen = -1;
-	e->p->swap_dirn = -1;
-	e->p->swap_status = SWAPOUT_NONE;
+	e->swap_filen = -1;
+	e->swap_dirn = -1;
+	e->swap_status = SWAPOUT_NONE;
 	storeReleaseRequest(e);
     } else {
 	/* swapping complete */
 	debug(20, 3) ("storeSwapOutFileClosed: SwapOut complete: '%s' to %d, %08X\n",
-	    storeUrl(e), e->p->swap_dirn, e->p->swap_filen);
-	e->p->swap_file_sz = objectLen(e) + mem->swap_hdr_sz;
-	e->p->swap_status = SWAPOUT_DONE;
-	storeDirUpdateSwapSize(&Config.cacheSwap.swapDirs[e->p->swap_dirn], e->p->swap_file_sz, 1);
+	    storeUrl(e), e->swap_dirn, e->swap_filen);
+	e->swap_file_sz = objectLen(e) + mem->swap_hdr_sz;
+	e->swap_status = SWAPOUT_DONE;
+	storeDirUpdateSwapSize(&Config.cacheSwap.swapDirs[e->swap_dirn], e->swap_file_sz, 1);
 	if (storeCheckCachable(e)) {
+#ifdef DSA
 /* 
  * Check if the PayloadEntry is in payload_table. If yes, it means the 
  * HEAD reply contains an MD5 digest and this object is already in the
@@ -310,39 +311,42 @@
  * object. Otherwise, the object will be moved to the real cache
  * directory.
  */
-	    PayloadEntry * p;
-	    p = payloadGet(e->p->hash.key);	    
+	    StoreEntry * p;
+	    InstanceEntry * entry = instanceGetPublic(e->mem_obj->url, e->mem_obj->method);
+	    if (e->mem_obj->method == METHOD_GET) {
+	    assert(!EBIT_TEST(e->flags, KEY_PRIVATE));	
+	    p = storeGet(e->hash.key);	    
 	    if (p == NULL) { 
 	/* The object is not in hash, add it */
-		payloadHashInsert(e->p, e->p->hash.key);
+		storeHashInsert(e);
 		storeLog(STORE_LOG_SWAPOUT, e);
-		storeDirSwapLog(e->p, SWAP_LOG_ADD);
-	        payloadAddStoreEntry(e->p, e);
+		storeDirSwapLog(e, SWAP_LOG_ADD);
+	        storeAddInstanceEntry(e, entry);
 	    }
-	    else if (p == e->p) {	    
+	    else if (p == e) {
 	/* This is the case when HEAD has MD5 and we finish download */
 		storeLog(STORE_LOG_SWAPOUT, e);
-		storeDirSwapLog(e->p, SWAP_LOG_ADD);
-	        payloadAddStoreEntry(e->p, e);
+		storeDirSwapLog(e, SWAP_LOG_ADD);
+	        storeAddInstanceEntry(e, entry);
 	    }
 	    else {
-	/* The object is already in the right place, remove this one */
-		if (p->mem_obj == NULL) {
-		     p->mem_obj = e->p->mem_obj;
-		     e->p->mem_obj = NULL;
-		     payloadSetMemStatus(e->p, NOT_IN_MEMORY);
-		}     
-		payloadRemoveStoreEntry(e->p, e);   
-		payloadAddStoreEntry(p, e);   
-	    	e->p = p;
+		EBIT_SET(e->flags, KEY_PRIVATE); // set to KEY_PRIVATE, 
+						// so no SWAP_LOG_DEL
+		storeAddInstanceEntry(p, entry);   
+	        storeReleaseRequest(e);
 	    }
+	    }
+#else
+	    storeLog(STORE_LOG_SWAPOUT, e);
+	    storeDirSwapLog(e, SWAP_LOG_ADD);
+#endif
 	}
 	statCounter.swap.outs++;
     }
     debug(20, 3) ("storeSwapOutFileClosed: %s:%d\n", __FILE__, __LINE__);
     mem->swapout.sio = NULL;
     cbdataUnlock(sio);
-    payloadUnlockObject(e->p);
+    storeUnlockObject(e);
 }
 
 /*
@@ -378,15 +382,15 @@
 storeSwapOutAble(const StoreEntry * e)
 {
     dlink_node *node;
-    if (e->p->mem_obj->swapout.sio != NULL)
+    if (e->mem_obj->swapout.sio != NULL)
 	return 1;
-    if (e->p->mem_obj->inmem_lo > 0)
+    if (e->mem_obj->inmem_lo > 0)
 	return 0;
     /*
      * If there are DISK clients, we must write to disk
      * even if its not cachable
      */
-    for (node = e->p->mem_obj->clients.head; node; node = node->next) {
+    for (node = e->mem_obj->clients.head; node; node = node->next) {
 	if (((store_client *) node->data)->type == STORE_DISK_CLIENT)
 	    return 1;
     }
Index: squid/src/structs.h
diff -u squid/src/structs.h:1.6.2.10.2.2 squid/src/structs.h:1.6.2.11.2.5.2.2
--- squid/src/structs.h:1.6.2.10.2.2	Wed Aug 14 04:27:28 2002
+++ squid/src/structs.h	Wed Mar 10 22:02:58 2004
@@ -783,6 +783,9 @@
     HttpStatusLine sline;
     HttpHeader header;
     HttpBody body;		/* for small constant memory-resident text bodies only */
+#ifdef DTD
+    String content_md5; /* content MD5 value, needed for DTD */
+#endif
 };
 
 struct _http_state_flags {
@@ -792,7 +795,11 @@
 };
 
 struct _HttpStateData {
+#ifdef DSA
+    InstanceEntry * entry;
+#else    
     StoreEntry *entry;
+#endif    
     request_t *request;
     char *reply_hdr;
     size_t reply_hdr_size;
@@ -883,8 +890,13 @@
     } out;
     HttpHdrRangeIter range_iter;	/* data for iterating thru range specs */
     size_t req_sz;		/* raw request size on input, not current request size */
+#ifdef DSA
+    InstanceEntry * entry;
+    InstanceEntry * old_entry;
+#else    
     StoreEntry *entry;
     StoreEntry *old_entry;
+#endif    
     log_type log_type;
 #if USE_CACHE_DIGESTS
     const char *lookup_type;	/* temporary hack: storeGet() result: HIT/MISS/NONE */
@@ -968,8 +980,13 @@
 
 struct _DigestFetchState {
     PeerDigest *pd;
+#ifdef DSA
+    InstanceEntry * entry;
+    InstanceEntry * old_entry;
+#else    
     StoreEntry *entry;
     StoreEntry *old_entry;
+#endif    
     store_client *sc;
     store_client *old_sc;
     request_t *request;
@@ -1144,7 +1161,11 @@
 
 struct _ps_state {
     request_t *request;
+#ifdef DSA
+    InstanceEntry * entry;
+#else    
     StoreEntry *entry;
+#endif    
     int always_direct;
     int never_direct;
     int direct;
@@ -1257,10 +1278,10 @@
     char *_type;
     void *_data;
     void (*Free) (RemovalPolicy * policy);
-    void (*Add) (RemovalPolicy * policy, PayloadEntry * entry, RemovalPolicyNode * node);
-    void (*Remove) (RemovalPolicy * policy, PayloadEntry * entry, RemovalPolicyNode * node);
-    void (*Referenced) (RemovalPolicy * policy, const PayloadEntry * entry, RemovalPolicyNode * node);
-    void (*Dereferenced) (RemovalPolicy * policy, const PayloadEntry * entry, RemovalPolicyNode * node);
+    void (*Add) (RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node);
+    void (*Remove) (RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node);
+    void (*Referenced) (RemovalPolicy * policy, const StoreEntry * entry, RemovalPolicyNode * node);
+    void (*Dereferenced) (RemovalPolicy * policy, const StoreEntry * entry, RemovalPolicyNode * node);
     RemovalPolicyWalker *(*WalkInit) (RemovalPolicy * policy);
     RemovalPurgeWalker *(*PurgeInit) (RemovalPolicy * policy, int max_scan);
 };
@@ -1268,7 +1289,7 @@
 struct _RemovalPolicyWalker {
     RemovalPolicy *_policy;
     void *_data;
-    const PayloadEntry *(*Next) (RemovalPolicyWalker * walker);
+    const StoreEntry *(*Next) (RemovalPolicyWalker * walker);
     void (*Done) (RemovalPolicyWalker * walker);
 };
 
@@ -1276,7 +1297,7 @@
     RemovalPolicy *_policy;
     void *_data;
     int scanned, max_scan, locked;
-    PayloadEntry *(*Next) (RemovalPurgeWalker * walker);
+    StoreEntry *(*Next) (RemovalPurgeWalker * walker);
     void (*Done) (RemovalPurgeWalker * walker);
 };
 
@@ -1312,35 +1333,50 @@
 #if URL_CHECKSUM_DEBUG
     unsigned int chksum;
 #endif
+#ifdef DSA
+    InstanceEntry * e; /* pointer to the initial InstanceEntry */
+#endif
 };
 
-struct _StoreEntry {
-    hash_link hash;		/* must be first */
+#ifdef DSA
+struct _InstanceEntry {
+    hash_link hash;
     time_t timestamp;
     time_t expires;
     time_t lastmod;
     u_short flags;
-    store_status_t store_status:3;
-    ping_status_t ping_status:3;
-    PayloadEntry * p;
+    StoreEntry * p; /* pointer to corresponding StoreEntry */
 };
+#endif
 
-struct _PayloadEntry {
+struct _StoreEntry {
     hash_link hash;		/* must be first */
     MemObject *mem_obj;
     RemovalPolicyNode repl;
+#ifndef DSA    
+    time_t timestamp;
+#endif    
     time_t lastref;
+#ifndef DSA    
+    time_t expires;
+    time_t lastmod;
+#endif    
+    size_t swap_file_sz;
     u_short refcount;
     u_short flags;
-    size_t swap_file_sz;
     sfileno swap_filen:25;
     sdirno swap_dirn:7;
-    u_short lock_count; /* sum of all the lock_count's of the associated StoreEntry */
+    u_short lock_count;		/* Assume < 65536! */
     mem_status_t mem_status:3;
+    ping_status_t ping_status:3;
+    store_status_t store_status:3;
     swap_status_t swap_status:3;
-    MD5_CTX ctx; /* MD5 context for the hash, updated per httpReadReply */
-    Array * instances; /* array of StoreEntry's (aka instances) */
-};	
+#ifdef DSA
+    MD5_CTX ctx; /* MD5 context for the hash, updated per each read(2)
+		in httpReadReply */
+    Array * instances; /* Array of related InstanceEntry's */ 
+#endif    
+};
 
 struct _SwapDir {
     char *type;
@@ -1417,6 +1453,9 @@
 #endif
     unsigned int accelerated:1;
     unsigned int internal:1;
+#ifdef DTD
+    unsigned int was_get:1; /* to mark if this is a DTD request in the HEAD phase */
+#endif
 };
 
 struct _link_list {
@@ -1427,7 +1466,7 @@
 struct _storeIOState {
     sdirno swap_dirn;
     sfileno swap_filen;
-    PayloadEntry *p;		/* Need this so the FS layers can play god */
+    StoreEntry *e;		/* Need this so the FS layers can play god */
     mode_t mode;
     size_t st_size;		/* do stat(2) after read open */
     off_t offset;		/* current on-disk offset pointer */
@@ -1694,7 +1733,14 @@
 struct _storeSwapLogData {
     char op;
     sfileno swap_filen;
+#ifndef DSA
+    time_t timestamp;
+#endif
     time_t lastref;
+#ifndef DSA
+    time_t expires;
+    time_t lastmod;
+#endif
     size_t swap_file_sz;
     u_short refcount;
     u_short flags;
@@ -1761,7 +1807,11 @@
 
 struct _FwdState {
     int client_fd;
+#ifdef DSA
+    InstanceEntry * entry;
+#else    
     StoreEntry *entry;
+#endif    
     request_t *request;
     FwdServer *servers;
     int server_fd;
@@ -1869,8 +1919,13 @@
     int s_fd;			/* server end */
     int rcvd;			/* bytes received from client */
     int sent;			/* bytes sent to server */
+#ifdef DSA
+    InstanceEntry * request_entry;
+    InstanceEntry * reply_entry;
+#else    
     StoreEntry *request_entry;	/* the request entry */
     StoreEntry *reply_entry;	/* the reply entry */
+#endif    
     CWCB *callback;		/* what to do when we finish sending */
     void *cbdata;		/* callback data passed to callback func */
     struct {
@@ -1894,7 +1949,7 @@
  * This defines an repl type
  */
 
-struct _payloadrepl_entry {
+struct _storerepl_entry {
     char *typestr;
     REMOVALPOLICYCREATE *create;
 };
Index: squid/src/typedefs.h
diff -u squid/src/typedefs.h:1.3.4.3.4.1 squid/src/typedefs.h:1.3.4.3.6.1
--- squid/src/typedefs.h:1.3.4.3.4.1	Wed Aug 14 03:15:37 2002
+++ squid/src/typedefs.h	Fri Nov 15 01:10:37 2002
@@ -130,8 +130,10 @@
 typedef struct _mem_hdr mem_hdr;
 typedef struct _store_client store_client;
 typedef struct _MemObject MemObject;
+#ifdef DSA
+typedef struct _InstanceEntry InstanceEntry;
+#endif
 typedef struct _StoreEntry StoreEntry;
-typedef struct _PayloadEntry PayloadEntry;
 typedef struct _SwapDir SwapDir;
 typedef struct _request_flags request_flags;
 typedef struct _helper_flags helper_flags;
@@ -170,12 +172,8 @@
 typedef struct _PumpStateData PumpStateData;
 typedef struct _storefs_entry storefs_entry_t;
 typedef struct _storerepl_entry storerepl_entry_t;
-typedef struct _payloadrepl_entry payloadrepl_entry_t;
 typedef struct _diskd_queue diskd_queue;
 typedef struct _Logfile Logfile;
-typedef struct _PLRemovalPolicy PLRemovalPolicy;
-typedef struct _PLRemovalPolicyWalker PLRemovalPolicyWalker;
-typedef struct _PLRemovalPurgeWalker PLRemovalPurgeWalker;
 typedef struct _RemovalPolicy RemovalPolicy;
 typedef struct _RemovalPolicyWalker RemovalPolicyWalker;
 typedef struct _RemovalPurgeWalker RemovalPurgeWalker;
@@ -242,12 +240,12 @@
 typedef void STNEWFS(SwapDir *);
 typedef void STDUMP(StoreEntry *, const char *, SwapDir *);
 typedef void STFREE(SwapDir *);
-typedef int STDBLCHECK(SwapDir *, PayloadEntry *);
+typedef int STDBLCHECK(SwapDir *, StoreEntry *);
 typedef void STSTATFS(SwapDir *, StoreEntry *);
 typedef void STMAINTAINFS(SwapDir *);
-typedef int STCHECKOBJ(SwapDir *, const PayloadEntry *);
-typedef void STREFOBJ(SwapDir *, PayloadEntry *);
-typedef void STUNREFOBJ(SwapDir *, PayloadEntry *);
+typedef int STCHECKOBJ(SwapDir *, const StoreEntry *);
+typedef void STREFOBJ(SwapDir *, StoreEntry *);
+typedef void STUNREFOBJ(SwapDir *, StoreEntry *);
 typedef void STSETUP(storefs_entry_t *);
 typedef void STDONE(void);
 typedef int STCALLBACK(SwapDir *);
@@ -262,10 +260,10 @@
 
 typedef void STLOGOPEN(SwapDir *);
 typedef void STLOGCLOSE(SwapDir *);
-typedef void STLOGWRITE(const SwapDir *, const PayloadEntry *, int);
+typedef void STLOGWRITE(const SwapDir *, const StoreEntry *, int);
 typedef int STLOGCLEANSTART(SwapDir *);
-typedef const PayloadEntry *STLOGCLEANNEXTENTRY(SwapDir *);
-typedef void STLOGCLEANWRITE(SwapDir *, const PayloadEntry *);
+typedef const StoreEntry *STLOGCLEANNEXTENTRY(SwapDir *);
+typedef void STLOGCLEANWRITE(SwapDir *, const StoreEntry *);
 typedef void STLOGCLEANDONE(SwapDir *);
 
 /* Store dir configuration routines */
@@ -316,7 +314,6 @@
 #endif
 
 typedef RemovalPolicy *REMOVALPOLICYCREATE(wordlist * args);
-typedef PLRemovalPolicy *PLREMOVALPOLICYCREATE(wordlist * args);
 
 typedef int STDIRSELECT(const StoreEntry *);
 
Index: squid/src/urn.c
diff -u squid/src/urn.c:1.3.4.3.8.1 squid/src/urn.c:1.3.4.3.10.1
--- squid/src/urn.c:1.3.4.3.8.1	Wed Aug 14 03:15:37 2002
+++ squid/src/urn.c	Fri Nov 15 01:10:37 2002
@@ -36,9 +36,17 @@
 #include "squid.h"
 
 typedef struct {
+#ifdef DSA	
+    InstanceEntry *entry;
+#else    
     StoreEntry *entry;
+#endif    
     store_client *sc;
+#ifdef DSA    
+    InstanceEntry *urlres_e;
+#else    
     StoreEntry *urlres_e;
+#endif    
     request_t *request;
     request_t *urlres_r;
     struct {
@@ -96,21 +104,37 @@
 }
 
 void
+#ifdef DSA
+urnStart(request_t * r, InstanceEntry * e)
+#else	
 urnStart(request_t * r, StoreEntry * e)
+#endif	
 {
     LOCAL_ARRAY(char, urlres, 4096);
     request_t *urlres_r = NULL;
     const char *t;
     char *host;
     UrnState *urnState;
+#ifdef DSA    
+    InstanceEntry *urlres_e;
+#else    
     StoreEntry *urlres_e;
+#endif    
     ErrorState *err;
+#ifdef DSA    
+    debug(52, 3) ("urnStart: '%s'\n", storeUrl(e->p));
+#else    
     debug(52, 3) ("urnStart: '%s'\n", storeUrl(e));
+#endif    
     urnState = xcalloc(1, sizeof(UrnState));
     urnState->entry = e;
     urnState->request = requestLink(r);
     cbdataAdd(urnState, cbdataXfree, 0);
-    payloadLockObject(urnState->entry->p);
+#ifdef DSA    
+    storeLockObject(urnState->entry->p);
+#else    
+    storeLockObject(urnState->entry);
+#endif    
     if (strncasecmp(strBuf(r->urlpath), "menu.", 5) == 0) {
 	char *new_path = xstrdup(strBuf(r->urlpath) + 5);
 	urnState->flags.force_menu = 1;
@@ -135,17 +159,32 @@
 	return;
     }
     httpHeaderPutStr(&urlres_r->header, HDR_ACCEPT, "text/plain");
+#ifdef DSA	    
+    if ((urlres_e = instanceGetPublic(urlres, METHOD_GET)) == NULL) {
+	urlres_e = instanceCreateEntry(urlres, urlres, null_request_flags, METHOD_GET);
+	urnState->sc = storeClientListAdd(urlres_e->p, urnState);
+#else	
     if ((urlres_e = storeGetPublic(urlres, METHOD_GET)) == NULL) {
 	urlres_e = storeCreateEntry(urlres, urlres, null_request_flags, METHOD_GET);
 	urnState->sc = storeClientListAdd(urlres_e, urnState);
+#endif	
 	fwdStart(-1, urlres_e, urlres_r);
     } else {
-	payloadLockObject(urlres_e->p);
+#ifdef DSA	    
+	storeLockObject(urlres_e->p);
+	urnState->sc = storeClientListAdd(urlres_e->p, urnState);
+#else	
+	storeLockObject(urlres_e);
 	urnState->sc = storeClientListAdd(urlres_e, urnState);
+#endif	
     }
     urnState->urlres_e = urlres_e;
     urnState->urlres_r = requestLink(urlres_r);
+#ifdef DSA    
+    storeClientCopy(urnState->sc, urlres_e->p,
+#else		    
     storeClientCopy(urnState->sc, urlres_e,
+#endif	    
 	0,
 	0,
 	4096,
@@ -173,8 +212,13 @@
 urnHandleReply(void *data, char *buf, ssize_t size)
 {
     UrnState *urnState = data;
+#ifdef DSA   
+    StoreEntry *e = urnState->entry->p;
+    StoreEntry *urlres_e = urnState->urlres_e->p;
+#else    
     StoreEntry *e = urnState->entry;
     StoreEntry *urlres_e = urnState->urlres_e;
+#endif    
     char *s = NULL;
     size_t k;
     HttpReply *rep;
@@ -217,16 +261,20 @@
 	return;
     }
     s = buf + k;
-    assert(urlres_e->p->mem_obj->reply);
-    httpReplyParse(urlres_e->p->mem_obj->reply, buf, k);
+    assert(urlres_e->mem_obj->reply);
+    httpReplyParse(urlres_e->mem_obj->reply, buf, k);
     debug(52, 3) ("mem->reply exists, code=%d.\n",
-	urlres_e->p->mem_obj->reply->sline.status);
-    if (urlres_e->p->mem_obj->reply->sline.status != HTTP_OK) {
+	urlres_e->mem_obj->reply->sline.status);
+    if (urlres_e->mem_obj->reply->sline.status != HTTP_OK) {
 	debug(52, 3) ("urnHandleReply: failed.\n");
 	err = errorCon(ERR_URN_RESOLVE, HTTP_NOT_FOUND);
 	err->request = requestLink(urnState->request);
 	err->url = xstrdup(storeUrl(e));
+#ifdef DSA
+	errorAppendEntry(urnState->entry, err);
+#else
 	errorAppendEntry(e, err);
+#endif
 	return;
     }
     while (xisspace(*s))
@@ -240,7 +288,11 @@
 	err = errorCon(ERR_URN_RESOLVE, HTTP_NOT_FOUND);
 	err->request = requestLink(urnState->request);
 	err->url = xstrdup(storeUrl(e));
+#ifdef DSA
+	errorAppendEntry(urnState->entry, err);
+#else
 	errorAppendEntry(e, err);
+#endif
 	return;
     }
     min_u = urnFindMinRtt(urls, urnState->request->method, NULL);
@@ -271,7 +323,7 @@
 	"Generated by %s@%s\n"
 	"</ADDRESS>\n",
 	full_appname_string, getMyHostname());
-    rep = e->p->mem_obj->reply;
+    rep = e->mem_obj->reply;
     httpReplyReset(rep);
     httpBuildVersion(&version, 1, 0);
     httpReplySetHeaders(rep, version, HTTP_MOVED_TEMPORARILY, NULL,
@@ -292,8 +344,12 @@
     safe_free(urls);
     /* mb was absorbed in httpBodySet call, so we must not clean it */
     storeUnregister(urnState->sc, urlres_e, urnState);
-    payloadUnlockObject(urlres_e->p);
-    payloadUnlockObject(urnState->entry->p);
+    storeUnlockObject(urlres_e);
+#ifdef DSA    
+    storeUnlockObject(urnState->entry->p);
+#else    
+    storeUnlockObject(urnState->entry);
+#endif    
     requestUnlink(urnState->request);
     requestUnlink(urnState->urlres_r);
     cbdataFree(urnState);
Index: squid/src/wais.c
diff -u squid/src/wais.c:1.3.4.1.8.1 squid/src/wais.c:1.3.4.1.10.4.2.1
--- squid/src/wais.c:1.3.4.1.8.1	Wed Aug 14 03:15:37 2002
+++ squid/src/wais.c	Mon Dec 30 15:06:41 2002
@@ -37,7 +37,11 @@
 
 typedef struct {
     int fd;
+#ifdef DSA    
+    InstanceEntry *entry;
+#else    
     StoreEntry *entry;
+#endif    
     method_t method;
     const HttpHeader *request_hdr;
     char url[MAX_URL];
@@ -57,7 +61,11 @@
     WaisStateData *waisState = data;
     if (waisState == NULL)
 	return;
-    payloadUnlockObject(waisState->entry->p);
+#ifdef DSA    
+    storeUnlockObject(waisState->entry->p);
+#else    
+    storeUnlockObject(waisState->entry);
+#endif    
     requestUnlink(waisState->request);
     cbdataFree(waisState);
 }
@@ -67,10 +75,14 @@
 waisTimeout(int fd, void *data)
 {
     WaisStateData *waisState = data;
+#ifdef DSA    
+    StoreEntry *entry = waisState->entry->p;
+#else    
     StoreEntry *entry = waisState->entry;
+#endif    
     debug(24, 4) ("waisTimeout: FD %d: '%s'\n", fd, storeUrl(entry));
     if (entry->store_status == STORE_PENDING) {
-	if (entry->p->mem_obj->inmem_hi == 0) {
+	if (entry->mem_obj->inmem_hi == 0) {
 	    fwdFail(waisState->fwd,
 		errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT));
 	}
@@ -85,7 +97,11 @@
 {
     WaisStateData *waisState = data;
     LOCAL_ARRAY(char, buf, 4096);
+#ifdef DSA    
+    StoreEntry *entry = waisState->entry->p;
+#else    
     StoreEntry *entry = waisState->entry;
+#endif    
     int len;
     int clen;
     int bin;
@@ -135,19 +151,31 @@
 	    err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR);
 	    err->xerrno = errno;
 	    err->request = requestLink(waisState->request);
+#ifdef DSA
+	    errorAppendEntry(waisState->entry, err);
+#else
 	    errorAppendEntry(entry, err);
+#endif
 	    comm_close(fd);
 	}
-    } else if (len == 0 && entry->p->mem_obj->inmem_hi == 0) {
+    } else if (len == 0 && entry->mem_obj->inmem_hi == 0) {
 	ErrorState *err;
 	err = errorCon(ERR_ZERO_SIZE_OBJECT, HTTP_SERVICE_UNAVAILABLE);
 	err->xerrno = errno;
 	err->request = requestLink(waisState->request);
+#ifdef DSA
+	errorAppendEntry(waisState->entry, err);
+#else
 	errorAppendEntry(entry, err);
+#endif
 	comm_close(fd);
     } else if (len == 0) {
 	/* Connection closed; retrieval done. */
+#ifdef DSA	    
+	waisState->entry->expires = squid_curtime;
+#else	
 	entry->expires = squid_curtime;
+#endif	
 	fwdComplete(waisState->fwd);
 	comm_close(fd);
     } else {
@@ -165,7 +193,11 @@
 waisSendComplete(int fd, char *bufnotused, size_t size, int errflag, void *data)
 {
     WaisStateData *waisState = data;
+#ifdef DSA    
+    StoreEntry *entry = waisState->entry->p;
+#else   
     StoreEntry *entry = waisState->entry;
+#endif    
     debug(24, 5) ("waisSendComplete: FD %d size: %d errflag: %d\n",
 	fd, size, errflag);
     if (size > 0) {
@@ -180,7 +212,11 @@
 	err = errorCon(ERR_WRITE_ERROR, HTTP_SERVICE_UNAVAILABLE);
 	err->xerrno = errno;
 	err->request = requestLink(waisState->request);
+#ifdef DSA
+	errorAppendEntry(waisState->entry, err);
+#else
 	errorAppendEntry(entry, err);
+#endif
 	comm_close(fd);
     } else {
 	/* Schedule read reply. */
@@ -211,9 +247,15 @@
     memBufPrintf(&mb, "\r\n");
     debug(24, 6) ("waisSendRequest: buf: %s\n", mb.buf);
     comm_write_mbuf(fd, mb, waisSendComplete, waisState);
+#ifdef DSA
+    if (EBIT_TEST(waisState->entry->p->flags, ENTRY_CACHABLE))
+	storeSetPublicKey(waisState->entry);	/* Make it public */
+    EBIT_CLR(waisState->entry->p->flags, ENTRY_FWD_HDR_WAIT);
+#else
     if (EBIT_TEST(waisState->entry->flags, ENTRY_CACHABLE))
 	storeSetPublicKey(waisState->entry);	/* Make it public */
     EBIT_CLR(waisState->entry->flags, ENTRY_FWD_HDR_WAIT);
+#endif
 }
 
 void
@@ -221,7 +263,11 @@
 {
     WaisStateData *waisState = NULL;
     request_t *request = fwd->request;
+#ifdef DSA    
+    StoreEntry *entry = fwd->entry->p;
+#else    
     StoreEntry *entry = fwd->entry;
+#endif    
     int fd = fwd->server_fd;
     const char *url = storeUrl(entry);
     method_t method = request->method;
@@ -233,12 +279,16 @@
     waisState->method = method;
     waisState->request_hdr = &request->header;
     waisState->fd = fd;
+#ifdef DSA    
+    waisState->entry = fwd->entry;
+#else   
     waisState->entry = entry;
+#endif    
     xstrncpy(waisState->url, url, MAX_URL);
     waisState->request = requestLink(request);
     waisState->fwd = fwd;
     comm_add_close_handler(waisState->fd, waisStateFree, waisState);
-    payloadLockObject(entry->p);
+    storeLockObject(entry);
     commSetSelect(fd, COMM_SELECT_WRITE, waisSendRequest, waisState, 0);
     commSetTimeout(fd, Config.Timeout.read, waisTimeout, waisState);
 }
Index: squid/src/whois.c
diff -u squid/src/whois.c:1.3.4.1.8.1 squid/src/whois.c:1.3.4.1.10.1
--- squid/src/whois.c:1.3.4.1.8.1	Wed Aug 14 03:15:38 2002
+++ squid/src/whois.c	Fri Nov 15 01:10:37 2002
@@ -38,7 +38,11 @@
 #define WHOIS_PORT 43
 
 typedef struct {
+#ifdef DSA
+    InstanceEntry *entry;
+#else
     StoreEntry *entry;
+#endif 
     request_t *request;
     FwdState *fwd;
 } WhoisState;
@@ -60,7 +64,11 @@
     p->entry = fwd->entry;
     p->fwd = fwd;
     cbdataAdd(p, cbdataXfree, 0);
-    payloadLockObject(p->entry->p);
+#ifdef DSA    
+    storeLockObject(p->entry->p);
+#else    
+    storeLockObject(p->entry);
+#endif    
     comm_add_close_handler(fd, whoisClose, p);
     l = strLen(p->request->urlpath) + 3;
     buf = xmalloc(l);
@@ -76,7 +84,11 @@
 whoisTimeout(int fd, void *data)
 {
     WhoisState *p = data;
+#ifdef DSA    
+    debug(75, 1) ("whoisTimeout: %s\n", storeUrl(p->entry->p));
+#else
     debug(75, 1) ("whoisTimeout: %s\n", storeUrl(p->entry));
+#endif
     whoisClose(fd, p);
 }
 
@@ -84,9 +96,13 @@
 whoisReadReply(int fd, void *data)
 {
     WhoisState *p = data;
+#ifdef DSA    
+    StoreEntry *entry = p->entry->p;
+#else    
     StoreEntry *entry = p->entry;
+#endif    
     char *buf = memAllocate(MEM_4K_BUF);
-    MemObject *mem = entry->p->mem_obj;
+    MemObject *mem = entry->mem_obj;
     int len;
     statCounter.syscalls.sock.reads++;
     len = read(fd, buf, 4095);
@@ -128,6 +144,10 @@
 {
     WhoisState *p = data;
     debug(75, 3) ("whoisClose: FD %d\n", fd);
-    payloadUnlockObject(p->entry->p);
+#ifdef DSA    
+    storeUnlockObject(p->entry->p);
+#else    
+    storeUnlockObject(p->entry);
+#endif    
     cbdataFree(p);
 }
Index: squid/src/fs/ufs/Makefile.in
diff -u squid/src/fs/ufs/Makefile.in:1.2 squid/src/fs/ufs/Makefile.in:1.2.64.1
--- squid/src/fs/ufs/Makefile.in:1.2	Sat Oct 21 09:44:46 2000
+++ squid/src/fs/ufs/Makefile.in	Sat Nov 16 00:19:02 2002
@@ -15,6 +15,7 @@
 RANLIB		= @RANLIB@
 AC_CFLAGS	= @CFLAGS@
 SHELL		= /bin/sh
+DEFINES		= -DDSA
 
 INCLUDE		= -I../../../include -I$(top_srcdir)/include -I$(top_srcdir)/src/
 CFLAGS 		= $(AC_CFLAGS) $(INCLUDE) $(DEFINES)
Index: squid/src/fs/ufs/store_dir_ufs.c
diff -u squid/src/fs/ufs/store_dir_ufs.c:1.4.2.9.2.1 squid/src/fs/ufs/store_dir_ufs.c:1.4.2.9.4.3
--- squid/src/fs/ufs/store_dir_ufs.c:1.4.2.9.2.1	Wed Aug 14 03:15:38 2002
+++ squid/src/fs/ufs/store_dir_ufs.c	Mon Dec  2 00:11:22 2002
@@ -78,19 +78,31 @@
 static EVH storeUfsDirRebuildFromDirectory;
 static EVH storeUfsDirRebuildFromSwapLog;
 static int storeUfsDirGetNextFile(RebuildState *, int *sfileno, int *size);
-static PayloadEntry *storeUfsDirAddDiskRestore(SwapDir * SD, const cache_key * key,
+static StoreEntry *storeUfsDirAddDiskRestore(SwapDir * SD, const cache_key * key,
     int file_number,
     size_t swap_file_sz,
+#ifndef DSA
+    time_t expires,
+    time_t timestamp,
+#endif
     time_t lastref,
+#ifndef DSA
+    time_t lastmod,
+#endif
     u_num32 refcount,
     u_short flags,
+#ifdef DSA
     Array * instances,
+#endif
     int clean);
-static StoreEntry *storeUfsDirAddInstanceRestore(const cache_key * key,
+#ifdef DSA
+static InstanceEntry * storeUfsDirAddInstanceRestore(const cache_key * key,
     time_t timestamp,
     time_t expires,
     time_t lastmod,
     u_short flags);
+static Array * storeUfsDirAddInstances(const cache_key *);
+#endif
 static void storeUfsDirRebuild(SwapDir * sd);
 static void storeUfsDirCloseTmpSwapLog(SwapDir * sd);
 static FILE *storeUfsDirOpenTmpSwapLog(SwapDir *, int *, int *);
@@ -114,11 +126,10 @@
 static EVH storeUfsDirCleanEvent;
 static int storeUfsDirIs(SwapDir * sd);
 static int storeUfsFilenoBelongsHere(int fn, int F0, int F1, int F2);
-static int storeUfsCleanupDoubleCheck(SwapDir *, PayloadEntry *);
+static int storeUfsCleanupDoubleCheck(SwapDir *, StoreEntry *);
 static void storeUfsDirStats(SwapDir *, StoreEntry *);
 static void storeUfsDirInitBitmap(SwapDir *);
 static int storeUfsDirValidFileno(SwapDir *, sfileno, int);
-static Array * storeUfsDirAddInstances(const cache_key *);
 
 /*
  * These functions were ripped straight out of the heart of store_dir.c.
@@ -377,8 +388,8 @@
     RebuildState *rb = data;
     SwapDir *SD = rb->sd;
     LOCAL_ARRAY(char, hdr_buf, SM_PAGE_SIZE);
-    PayloadEntry *p = NULL;
-    PayloadEntry tmpp;
+    StoreEntry *e = NULL;
+    StoreEntry tmpe;
     cache_key key[MD5_DIGEST_CHARS];
     int sfileno = 0;
     int count;
@@ -386,9 +397,11 @@
     struct stat sb;
     int swap_hdr_len;
     int fd = -1;
-    int i;
     tlv *tlv_list;
     tlv *t;
+#ifdef DSA
+    int i;
+#endif
     assert(rb != NULL);
     debug(20, 3) ("storeUfsDirRebuildFromDirectory: DIR #%d\n", rb->sd->index);
     for (count = 0; count < rb->speed; count++) {
@@ -445,7 +458,7 @@
 	}
 	debug(20, 3) ("storeUfsDirRebuildFromDirectory: successful swap meta unpacking\n");
 	memset(key, '\0', MD5_DIGEST_CHARS);
-	memset(&tmpp, '\0', sizeof(PayloadEntry));
+	memset(&tmpe, '\0', sizeof(StoreEntry));
 	for (t = tlv_list; t; t = t->next) {
 	    switch (t->type) {
 	    case STORE_META_KEY:
@@ -453,8 +466,12 @@
 		xmemcpy(key, t->value, MD5_DIGEST_CHARS);
 		break;
 	    case STORE_META_STD:
-		assert(t->length == PAYLOAD_HDR_METASIZE);
-		xmemcpy(&tmpp.lastref, t->value, PAYLOAD_HDR_METASIZE);
+		assert(t->length == STORE_HDR_METASIZE);
+#ifdef DSA
+		xmemcpy(&tmpe.lastref, t->value, STORE_HDR_METASIZE);
+#else
+		xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE);
+#endif
 		break;
 	    default:
 		break;
@@ -467,57 +484,72 @@
 	    storeUfsDirUnlinkFile(SD, sfileno);
 	    continue;
 	}
-	tmpp.hash.key = key;
+	tmpe.hash.key = key;
 	/* check sizes */
-	if (tmpp.swap_file_sz == 0) {
-	    tmpp.swap_file_sz = sb.st_size;
-	} else if (tmpp.swap_file_sz == sb.st_size - swap_hdr_len) {
-	    tmpp.swap_file_sz = sb.st_size;
-	} else if (tmpp.swap_file_sz != sb.st_size) {
+	if (tmpe.swap_file_sz == 0) {
+	    tmpe.swap_file_sz = sb.st_size;
+	} else if (tmpe.swap_file_sz == sb.st_size - swap_hdr_len) {
+	    tmpe.swap_file_sz = sb.st_size;
+	} else if (tmpe.swap_file_sz != sb.st_size) {
 	    debug(20, 1) ("storeUfsDirRebuildFromDirectory: SIZE MISMATCH %d!=%d\n",
-		tmpp.swap_file_sz, (int) sb.st_size);
+		tmpe.swap_file_sz, (int) sb.st_size);
 	    storeUfsDirUnlinkFile(SD, sfileno);
 	    continue;
 	}
-	/*
+#ifdef DSA
+	EBIT_CLR(tmpe.flags, KEY_PRIVATE);
+#else
 	if (EBIT_TEST(tmpe.flags, KEY_PRIVATE)) {
 	    storeUfsDirUnlinkFile(SD, sfileno);
 	    rb->counts.badflags++;
 	    continue;
 	}
-	*/
-	p = payloadGet(key);
-	if (p && p->lastref >= tmpp.lastref) {
+#endif
+	e = storeGet(key);
+	if (e && e->lastref >= tmpe.lastref) {
 	    /* key already exists, current entry is newer */
 	    /* keep old, ignore new */
 	    rb->counts.dupcount++;
 	    continue;
-	} else if (NULL != p) {
+	} else if (NULL != e) {
 	    /* URL already exists, this swapfile not being used */
 	    /* junk old, load new */
-	    payloadRelease(p);	/* release old entry */
+	    storeRelease(e);	/* release old entry */
 	    rb->counts.dupcount++;
 	}
 	rb->counts.objcount++;
-	tmpp.instances = storeUfsDirAddInstances(key);
-	if (tmpp.instances == NULL || tmpp.instances->count <= 0) {
-	    if (tmpp.instances)
-		    arrayDestroy(tmpp.instances);
+#ifdef DSA
+	tmpe.instances = storeUfsDirAddInstances(key);
+	if (tmpe.instances == NULL || tmpe.instances->count <= 0) {
+	    if (tmpe.instances)
+		arrayDestroy(tmpe.instances);
 	    rb->counts.dupcount++;
 	    continue;
-	}    	    
-	payloadEntryDump(&tmpp, 5);
-	p = storeUfsDirAddDiskRestore(SD, key,
+	}
+#endif	
+	storeEntryDump(&tmpe, 5);
+	e = storeUfsDirAddDiskRestore(SD, key,
 	    sfileno,
-	    tmpp.swap_file_sz,
-	    tmpp.lastref,       /* lastref */
-	    tmpp.refcount,	/* refcount */
-	    tmpp.flags,		/* flags */
-	    tmpp.instances,     /* instances */
+	    tmpe.swap_file_sz,
+#ifndef DSA
+	    tmpe.expires,
+	    tmpe.timestamp,
+#endif
+	    tmpe.lastref,
+#ifndef DSA
+	    tmpe.lastmod,
+#endif
+	    tmpe.refcount,	/* refcount */
+	    tmpe.flags,		/* flags */
+#ifdef DSA
+	    tmpe.instances,
+#endif
 	    (int) rb->flags.clean);
-	for (i = 0; i < tmpp.instances->count; ++i) 
-	    ((StoreEntry *) tmpp.instances->items[i])->p = p;
-	storeDirSwapLog(p, SWAP_LOG_ADD);
+#ifdef DSA
+	for (i = 0; i < tmpe.instances->count; ++i)
+	    ((InstanceEntry *) tmpe.instances->items[i])->p = e;
+#endif
+	storeDirSwapLog(e, SWAP_LOG_ADD);
     }
     eventAdd("storeRebuild", storeUfsDirRebuildFromDirectory, rb, 0.0, 1);
 }
@@ -527,15 +559,17 @@
 {
     RebuildState *rb = data;
     SwapDir *SD = rb->sd;
-    PayloadEntry *p = NULL;
+    StoreEntry *e = NULL;
     storeSwapLogData s;
     size_t ss = sizeof(storeSwapLogData);
     int count;
-    int i;
     int used;			/* is swapfile already in use? */
     int disk_entry_newer;	/* is the log entry newer than current entry? */
     double x;
+#ifdef DSA
+    int i;
     Array * instances;
+#endif
     assert(rb != NULL);
     /* load a number of objects per invocation */
     for (count = 0; count < rb->speed; count++) {
@@ -571,7 +605,7 @@
 	if (s.op == SWAP_LOG_ADD) {
 	    (void) 0;
 	} else if (s.op == SWAP_LOG_DEL) {
-	    if ((p = payloadGet(s.key)) != NULL) {
+	    if ((e = storeGet(s.key)) != NULL) {
 		/*
 		 * Make sure we don't unlink the file, it might be
 		 * in use by a subsequent entry.  Also note that
@@ -579,13 +613,20 @@
 		 * because adding to store_swap_size happens in
 		 * the cleanup procedure.
 		 */
-		if (p->swap_filen > -1) {
-		    storeUfsDirReplRemove(p);
-		    storeUfsDirMapBitReset(SD, p->swap_filen);
-		    p->swap_filen = -1;
-		    p->swap_dirn = -1;
+#ifdef DSA
+		assert(e->instances->count > 0);    
+		storeExpireNow(e->instances->items[0]);
+#else
+		storeExpireNow(e);
+#endif
+		storeReleaseRequest(e);
+		if (e->swap_filen > -1) {
+		    storeUfsDirReplRemove(e);
+		    storeUfsDirMapBitReset(SD, e->swap_filen);
+		    e->swap_filen = -1;
+		    e->swap_dirn = -1;
 		}
-		payloadRelease(p);
+		storeRelease(e);
 		rb->counts.objcount--;
 		rb->counts.cancelcount++;
 	    }
@@ -608,28 +649,36 @@
 	    rb->counts.invalid++;
 	    continue;
 	}
-	/* ymc: No concept of PRIVATE for payloads
 	if (EBIT_TEST(s.flags, KEY_PRIVATE)) {
 	    rb->counts.badflags++;
 	    continue;
 	}
-	*/
-	p = payloadGet(s.key);
+	e = storeGet(s.key);
 	used = storeUfsDirMapBitTest(SD, s.swap_filen);
 	/* If this URL already exists in the cache, does the swap log
 	 * appear to have a newer entry?  Compare 'lastref' from the
 	 * swap log to e->lastref. */
-	disk_entry_newer = p ? (s.lastref > p->lastref ? 1 : 0) : 0;
+	disk_entry_newer = e ? (s.lastref > e->lastref ? 1 : 0) : 0;
 	if (used && !disk_entry_newer) {
 	    /* log entry is old, ignore it */
 	    rb->counts.clashcount++;
 	    continue;
-	} else if (used && p && p->swap_filen == s.swap_filen && p->swap_dirn == SD->index) {
+	} else if (used && e && e->swap_filen == s.swap_filen && e->swap_dirn == SD->index) {
 	    /* swapfile taken, same URL, newer, update meta */
-		p->lastref = s.lastref;
-		p->flags = s.flags;
-		p->refcount = s.refcount;
-		storeUfsDirUnrefObj(SD, p);
+	    if (e->store_status == STORE_OK) {
+		e->lastref = s.lastref;
+#ifndef DSA
+		e->timestamp = s.timestamp;
+		e->expires = s.expires;
+		e->lastmod = s.lastmod;
+#endif
+		e->flags = s.flags;
+		e->refcount += s.refcount;
+		storeUfsDirUnrefObj(SD, e);
+	    } else {
+		debug_trap("storeUfsDirRebuildFromSwapLog: bad condition");
+		debug(20, 1) ("\tSee %s:%d\n", __FILE__, __LINE__);
+	    }
 	    continue;
 	} else if (used) {
 	    /* swapfile in use, not by this URL, log entry is newer */
@@ -651,22 +700,29 @@
 	    assert(rb->flags.need_to_validate);
 	    rb->counts.clashcount++;
 	    continue;
-	} else if (p && !disk_entry_newer) {
+	} else if (e && !disk_entry_newer) {
 	    /* key already exists, current entry is newer */
 	    /* keep old, ignore new */
 	    rb->counts.dupcount++;
 	    continue;
-	} else if (p) {
+	} else if (e) {
 	    /* key already exists, this swapfile not being used */
 	    /* junk old, load new */
-	    if (p->swap_filen > -1) {
-		storeUfsDirReplRemove(p);
+#ifdef DSA
+	    assert(e->instances->count > 0);
+	    storeExpireNow(e->instances->items[0]);
+#else
+	    storeExpireNow(e);
+#endif
+	    storeReleaseRequest(e);
+	    if (e->swap_filen > -1) {
+		storeUfsDirReplRemove(e);
 		/* Make sure we don't actually unlink the file */
-		storeUfsDirMapBitReset(SD, p->swap_filen);
-		p->swap_filen = -1;
-		p->swap_dirn = -1;
+		storeUfsDirMapBitReset(SD, e->swap_filen);
+		e->swap_filen = -1;
+		e->swap_dirn = -1;
 	    }
-	    payloadRelease(p);
+	    storeRelease(e);
 	    rb->counts.dupcount++;
 	} else {
 	    /* URL doesnt exist, swapfile not in use */
@@ -675,24 +731,37 @@
 	}
 	/* update store_swap_size */
 	rb->counts.objcount++;
+#ifdef DSA
 	instances = storeUfsDirAddInstances(s.key);
 	if (instances == NULL || instances->count <= 0) {
 	    if (instances)
-		    arrayDestroy(instances);
+		arrayDestroy(instances);
 	    rb->counts.dupcount++;
 	    continue;
-	}    	    
-	p = storeUfsDirAddDiskRestore(SD, s.key,
+	}
+#endif
+	e = storeUfsDirAddDiskRestore(SD, s.key,
 	    s.swap_filen,
 	    s.swap_file_sz,
+#ifndef DSA
+	    s.expires,
+	    s.timestamp,
+#endif
 	    s.lastref,
+#ifndef DSA
+	    s.lastmod,
+#endif
 	    s.refcount,
 	    s.flags,
+#ifdef DSA
 	    instances,
+#endif
 	    (int) rb->flags.clean);
-	for (i = 0; i < instances->count; ++i) 
-	    ((StoreEntry *) instances->items[i])->p = p;
-	storeDirSwapLog(p, SWAP_LOG_ADD);
+#ifdef DSA
+	for (i = 0; i < instances->count; ++i)
+	    ((InstanceEntry *) instances->items[i])->p = e;
+#endif
+	storeDirSwapLog(e, SWAP_LOG_ADD);
     }
     eventAdd("storeRebuild", storeUfsDirRebuildFromSwapLog, rb, 0.0, 1);
 }
@@ -786,43 +855,65 @@
 
 /* Add a new object to the cache with empty memory copy and pointer to disk
  * use to rebuild store from disk. */
-static PayloadEntry *
+static StoreEntry *
 storeUfsDirAddDiskRestore(SwapDir * SD, const cache_key * key,
     int file_number,
     size_t swap_file_sz,
+#ifndef DSA
+    time_t expires,
+    time_t timestamp,
+#endif
     time_t lastref,
+#ifndef DSA
+    time_t lastmod,
+#endif
     u_num32 refcount,
     u_short flags,
+#ifdef DSA
     Array * instances,
+#endif
     int clean)
 {
-    PayloadEntry *p = NULL;
+    StoreEntry *e = NULL;
     debug(20, 5) ("storeUfsAddDiskRestore: %s, fileno=%08X\n", storeKeyText(key), file_number);
     /* if you call this you'd better be sure file_number is not 
      * already in use! */
-    p = new_PayloadEntry(STORE_ENTRY_WITHOUT_MEMOBJ, NULL, NULL);
-    payloadSetMemStatus(p, NOT_IN_MEMORY);
-    p->swap_filen = file_number;
-    p->swap_dirn = SD->index;
-    p->swap_file_sz = swap_file_sz;
-    p->swap_status = SWAPOUT_DONE;
-    p->lock_count = 0;
-    p->lastref = lastref;
-    p->refcount = refcount;
-    p->flags = flags;
-    p->instances = instances;
-    EBIT_SET(p->flags, ENTRY_CACHABLE);
-    EBIT_CLR(p->flags, RELEASE_REQUEST);
-    EBIT_CLR(p->flags, KEY_PRIVATE);
-    EBIT_CLR(p->flags, ENTRY_VALIDATED);
-    storeUfsDirMapBitSet(SD, p->swap_filen);
-    payloadHashInsert(p, key);	/* do it after we clear KEY_PRIVATE */
-    storeUfsDirReplAdd(SD, p);
-    return p;
+    e = new_StoreEntry(STORE_ENTRY_WITHOUT_MEMOBJ, NULL, NULL);
+    e->store_status = STORE_OK;
+    storeSetMemStatus(e, NOT_IN_MEMORY);
+    e->swap_status = SWAPOUT_DONE;
+    e->swap_filen = file_number;
+    e->swap_dirn = SD->index;
+    e->swap_file_sz = swap_file_sz;
+    e->lock_count = 0;
+    e->lastref = lastref;
+#ifndef DSA
+    e->timestamp = timestamp;
+    e->expires = expires;
+    e->lastmod = lastmod;
+#endif
+    e->refcount = refcount;
+    e->flags = flags;
+    EBIT_SET(e->flags, ENTRY_CACHABLE);
+    EBIT_CLR(e->flags, RELEASE_REQUEST);
+    EBIT_CLR(e->flags, KEY_PRIVATE);
+    e->ping_status = PING_NONE;
+    EBIT_CLR(e->flags, ENTRY_VALIDATED);
+    storeUfsDirMapBitSet(SD, e->swap_filen);
+#ifdef DSA
+    e->instances = instances;
+    e->hash.key = storeKeyDup(key);
+    storeHashInsert(e);	/* do it after we clear KEY_PRIVATE */
+#else
+    storeHashInsert(e, key);	/* do it after we clear KEY_PRIVATE */
+#endif
+    storeUfsDirReplAdd(SD, e);
+    return e;
 }
 
+#ifdef DSA
 static Array *
-storeUfsDirAddInstances(const cache_key * key) 
+storeUfsDirAddInstances(const cache_key * key)
 {
     char fullpath[SQUID_MAXPATHLEN];	
     char fullfilename[SQUID_MAXPATHLEN];	
@@ -830,8 +921,8 @@
     DIR * dp;
     char hdr_buf[SM_PAGE_SIZE];
     struct dirent * de;
-    StoreEntry * e = NULL;
-    StoreEntry tmpe;
+    InstanceEntry * e = NULL;
+    InstanceEntry tmpe;
     int fd;
     struct stat sb;
     tlv * tlv_list;
@@ -905,7 +996,7 @@
 	}
 	debug(20, 3) ("storeUfsDirAddInstances: successful swap meta unpacking\n");
 	memset(skey, '\0', MD5_DIGEST_CHARS);
-	memset(&tmpe, '\0', sizeof(StoreEntry));
+	memset(&tmpe, '\0', sizeof(InstanceEntry));
 	for (t = tlv_list; t; t = t->next) {
 	    switch (t->type) {
 	    case STORE_META_KEY:
@@ -913,8 +1004,8 @@
 		xmemcpy(skey, t->value, MD5_DIGEST_CHARS);
 		break;
 	    case STORE_META_STD:
-		assert(t->length == STORE_HDR_METASIZE);
-		xmemcpy(&tmpe.timestamp, t->value, STORE_HDR_METASIZE);
+		assert(t->length == INSTANCE_HDR_METASIZE);
+		xmemcpy(&tmpe.timestamp, t->value, INSTANCE_HDR_METASIZE);
 		break;
 	    default:
 		break;
@@ -946,7 +1037,7 @@
 	    continue;
 	}
 	
-	e = storeGet(skey);
+	e = instanceGet(skey);
 	if (e && e->timestamp >= tmpe.timestamp) {
 	    /* key already exists, current entry is newer */
 	    /* keep old, ignore new */
@@ -954,9 +1045,15 @@
 	} else if (NULL != e) {
 	    /* URL already exists, this swapfile not being used */
 	    /* junk old, load new */
+#ifdef DSA
+	    instanceRelease(e);	/* release old entry */
+#else
 	    storeRelease(e);	/* release old entry */
+#endif
 	}
+#ifndef DSA
 	storeEntryDump(&tmpe, 5);
+#endif
 	e = storeUfsDirAddInstanceRestore(skey,
 	    tmpe.timestamp,     /* timestamp */
 	    tmpe.expires,       /* expires */
@@ -966,37 +1063,36 @@
     }
     closedir(dp);
     if (ar->count <= 0) {
-	    arrayDestroy(ar);
-	    return 0;
+	arrayDestroy(ar);
+	return 0;
     }
     return ar;
 }
 
-static StoreEntry *
+static InstanceEntry *
 storeUfsDirAddInstanceRestore(const cache_key * key,
     time_t timestamp,
     time_t expires,
     time_t lastmod,
     u_short flags)
 {
-    StoreEntry *e = NULL;
+    InstanceEntry *e = NULL;
     debug(20, 5) ("storeUfsAddInstanceRestore: %s\n", storeKeyText(key));
     /* if you call this you'd better be sure file_number is not 
      * already in use! */
-    e = new_StoreEntry(STORE_ENTRY_WITHOUT_MEMOBJ, NULL, NULL);
+    e = new_InstanceEntry(STORE_ENTRY_WITHOUT_MEMOBJ, NULL, NULL);
     e->timestamp = timestamp;
     e->expires = expires;
-    e->store_status = STORE_OK;
     e->lastmod = lastmod;
     e->flags = flags;
     EBIT_SET(e->flags, ENTRY_CACHABLE);
     EBIT_CLR(e->flags, RELEASE_REQUEST);
     EBIT_CLR(e->flags, KEY_PRIVATE);
-    e->ping_status = PING_NONE;
     EBIT_CLR(e->flags, ENTRY_VALIDATED);
-    storeHashInsert(e, key);	/* do it after we clear KEY_PRIVATE */
+    instanceHashInsert(e, key);	/* do it after we clear KEY_PRIVATE */
     return e;
 }
+#endif
 
 static void
 storeUfsDirRebuild(SwapDir * sd)
@@ -1018,7 +1114,7 @@
     if (fp == NULL || zero) {
 	if (fp != NULL)
 	    fclose(fp);
-func = storeUfsDirRebuildFromDirectory;
+	func = storeUfsDirRebuildFromDirectory;
     } else {
 	func = storeUfsDirRebuildFromSwapLog;
 	rb->log = fp;
@@ -1163,10 +1259,10 @@
 /*
  * Get the next entry that is a candidate for clean log writing
  */
-const PayloadEntry *
+const StoreEntry *
 storeUfsDirCleanLogNextEntry(SwapDir * sd)
 {
-    const PayloadEntry *entry = NULL;
+    const StoreEntry *entry = NULL;
     struct _clean_state *state = sd->log.clean.state;
     if (state->walker)
 	entry = state->walker->Next(state->walker);
@@ -1177,19 +1273,26 @@
  * "write" an entry to the clean log file.
  */
 static void
-storeUfsDirWriteCleanEntry(SwapDir * sd, const PayloadEntry * p)
+storeUfsDirWriteCleanEntry(SwapDir * sd, const StoreEntry * e)
 {
     storeSwapLogData s;
     static size_t ss = sizeof(storeSwapLogData);
     struct _clean_state *state = sd->log.clean.state;
     memset(&s, '\0', ss);
     s.op = (char) SWAP_LOG_ADD;
-    s.swap_filen = p->swap_filen;
-    s.lastref = p->lastref;
-    s.swap_file_sz = p->swap_file_sz;
-    s.refcount = p->refcount;
-    s.flags = p->flags;
-    xmemcpy(&s.key, p->hash.key, MD5_DIGEST_CHARS);
+    s.swap_filen = e->swap_filen;
+#ifndef DSA
+    s.timestamp = e->timestamp;
+#endif
+    s.lastref = e->lastref;
+#ifndef DSA
+    s.expires = e->expires;
+    s.lastmod = e->lastmod;
+#endif
+    s.swap_file_sz = e->swap_file_sz;
+    s.refcount = e->refcount;
+    s.flags = e->flags;
+    xmemcpy(&s.key, e->hash.key, MD5_DIGEST_CHARS);
     xmemcpy(state->outbuf + state->outbuf_offset, &s, ss);
     state->outbuf_offset += ss;
     /* buffered write */
@@ -1273,17 +1376,24 @@
 }
 
 static void
-storeUfsDirSwapLog(const SwapDir * sd, const PayloadEntry * p, int op)
+storeUfsDirSwapLog(const SwapDir * sd, const StoreEntry * e, int op)
 {
     ufsinfo_t *ufsinfo = (ufsinfo_t *) sd->fsdata;
     storeSwapLogData *s = memAllocate(MEM_SWAP_LOG_DATA);
     s->op = (char) op;
-    s->swap_filen = p->swap_filen;
-    s->lastref = p->lastref;
-    s->swap_file_sz = p->swap_file_sz;
-    s->refcount = p->refcount;
-    s->flags = p->flags;
-    xmemcpy(s->key, p->hash.key, MD5_DIGEST_CHARS);
+    s->swap_filen = e->swap_filen;
+#ifndef DSA
+    s->timestamp = e->timestamp;
+#endif
+    s->lastref = e->lastref;
+#ifndef DSA
+    s->expires = e->expires;
+    s->lastmod = e->lastmod;
+#endif
+    s->swap_file_sz = e->swap_file_sz;
+    s->refcount = e->refcount;
+    s->flags = e->flags;
+    xmemcpy(s->key, e->hash.key, MD5_DIGEST_CHARS);
     file_write(ufsinfo->swaplog_fd,
 	-1,
 	s,
@@ -1296,12 +1406,16 @@
 static void
 storeUfsDirNewfs(SwapDir * sd)
 {
+#ifdef DSA
     char instances_dir[SQUID_MAXPATHLEN];
+#endif
     debug(47, 3) ("Creating swap space in %s\n", sd->path);
     storeUfsDirCreateDirectory(sd->path, 0);
+#ifdef DSA
     strcpy(instances_dir, sd->path);
     strcat(instances_dir, "/instances");
     storeUfsDirCreateDirectory(instances_dir, 0);
+#endif
     storeUfsDirCreateSwapSubDirs(sd);
 }
 
@@ -1484,7 +1598,7 @@
 void
 storeUfsDirMaintain(SwapDir * SD)
 {
-    PayloadEntry *p = NULL;
+    StoreEntry *e = NULL;
     int removed = 0;
     int max_scan;
     int max_remove;
@@ -1509,11 +1623,11 @@
 	    break;
 	if (removed >= max_remove)
 	    break;
-	p = walker->Next(walker);
-	if (!p)
+	e = walker->Next(walker);
+	if (!e)
 	    break;		/* no more objects */
 	removed++;
-	payloadRelease(p);
+	storeRelease(e);
     }
     walker->Done(walker);
     debug(20, (removed ? 2 : 3)) ("storeUfsDirMaintain: %s removed %d/%d f=%.03f max_scan=%d\n",
@@ -1528,7 +1642,7 @@
  * happily store anything as long as the LRU time isn't too small.
  */
 int
-storeUfsDirCheckObj(SwapDir * SD, const PayloadEntry * p)
+storeUfsDirCheckObj(SwapDir * SD, const StoreEntry * e)
 {
     /* Return 999 (99.9%) constant load */
     return 999;
@@ -1541,12 +1655,12 @@
  * maintain replacement information within the storage fs.
  */
 void
-storeUfsDirRefObj(SwapDir * SD, PayloadEntry * p)
+storeUfsDirRefObj(SwapDir * SD, StoreEntry * e)
 {
-    debug(1, 3) ("storeUfsDirRefObj: referencing %p %d/%d\n", p, p->swap_dirn,
-	p->swap_filen);
+    debug(1, 3) ("storeUfsDirRefObj: referencing %p %d/%d\n", e, e->swap_dirn,
+	e->swap_filen);
     if (SD->repl->Referenced)
-	SD->repl->Referenced(SD->repl, p, &p->repl);
+	SD->repl->Referenced(SD->repl, e, &e->repl);
 }
 
 /*
@@ -1555,12 +1669,12 @@
  * removed, to maintain replacement information within the storage fs.
  */
 void
-storeUfsDirUnrefObj(SwapDir * SD, PayloadEntry * p)
+storeUfsDirUnrefObj(SwapDir * SD, StoreEntry * e)
 {
-    debug(1, 3) ("storeUfsDirUnrefObj: referencing %p %d/%d\n", p, p->swap_dirn,
-	p->swap_filen);
+    debug(1, 3) ("storeUfsDirUnrefObj: referencing %p %d/%d\n", e, e->swap_dirn,
+	e->swap_filen);
     if (SD->repl->Dereferenced)
-	SD->repl->Dereferenced(SD->repl, p, &p->repl);
+	SD->repl->Dereferenced(SD->repl, e, &e->repl);
 }
 
 /*
@@ -1590,21 +1704,21 @@
  */
 
 void
-storeUfsDirReplAdd(SwapDir * SD, PayloadEntry * p)
+storeUfsDirReplAdd(SwapDir * SD, StoreEntry * e)
 {
-    debug(20, 4) ("storeUfsDirReplAdd: added node %p to dir %d\n", p,
+    debug(20, 4) ("storeUfsDirReplAdd: added node %p to dir %d\n", e,
 	SD->index);
-    SD->repl->Add(SD->repl, p, &p->repl);
+    SD->repl->Add(SD->repl, e, &e->repl);
 }
 
 
 void
-storeUfsDirReplRemove(PayloadEntry * p)
+storeUfsDirReplRemove(StoreEntry * e)
 {
-    SwapDir *SD = INDEXSD(p->swap_dirn);
-    debug(20, 4) ("storeUfsDirReplRemove: remove node %p from dir %d\n", p,
+    SwapDir *SD = INDEXSD(e->swap_dirn);
+    debug(20, 4) ("storeUfsDirReplRemove: remove node %p from dir %d\n", e,
 	SD->index);
-    SD->repl->Remove(SD->repl, p, &p->repl);
+    SD->repl->Remove(SD->repl, e, &e->repl);
 }
 
 
@@ -1749,26 +1863,26 @@
  * This is called by storeCleanup() if -S was given on the command line.
  */
 static int
-storeUfsCleanupDoubleCheck(SwapDir * sd, PayloadEntry * p)
+storeUfsCleanupDoubleCheck(SwapDir * sd, StoreEntry * e)
 {
     struct stat sb;
 
-    if (stat(storeUfsDirFullPath(sd, p->swap_filen, NULL), &sb) < 0) {
+    if (stat(storeUfsDirFullPath(sd, e->swap_filen, NULL), &sb) < 0) {
 	debug(20, 0) ("storeUfsCleanupDoubleCheck: MISSING SWAP FILE\n");
-	debug(20, 0) ("storeUfsCleanupDoubleCheck: FILENO %08X\n", p->swap_filen);
+	debug(20, 0) ("storeUfsCleanupDoubleCheck: FILENO %08X\n", e->swap_filen);
 	debug(20, 0) ("storeUfsCleanupDoubleCheck: PATH %s\n",
-	    storeUfsDirFullPath(sd, p->swap_filen, NULL));
-	payloadEntryDump(p, 0);
+	    storeUfsDirFullPath(sd, e->swap_filen, NULL));
+	storeEntryDump(e, 0);
 	return -1;
     }
-    if (p->swap_file_sz != sb.st_size) {
+    if (e->swap_file_sz != sb.st_size) {
 	debug(20, 0) ("storeUfsCleanupDoubleCheck: SIZE MISMATCH\n");
-	debug(20, 0) ("storeUfsCleanupDoubleCheck: FILENO %08X\n", p->swap_filen);
+	debug(20, 0) ("storeUfsCleanupDoubleCheck: FILENO %08X\n", e->swap_filen);
 	debug(20, 0) ("storeUfsCleanupDoubleCheck: PATH %s\n",
-	    storeUfsDirFullPath(sd, p->swap_filen, NULL));
+	    storeUfsDirFullPath(sd, e->swap_filen, NULL));
 	debug(20, 0) ("storeUfsCleanupDoubleCheck: ENTRY SIZE: %d, FILE SIZE: %d\n",
-	    p->swap_file_sz, (int) sb.st_size);
-	payloadEntryDump(p, 0);
+	    e->swap_file_sz, (int) sb.st_size);
+	storeEntryDump(e, 0);
 	return -1;
     }
     return 0;
Index: squid/src/fs/ufs/store_io_ufs.c
diff -u squid/src/fs/ufs/store_io_ufs.c:1.2.6.2.8.1 squid/src/fs/ufs/store_io_ufs.c:1.2.6.2
--- squid/src/fs/ufs/store_io_ufs.c:1.2.6.2.8.1	Wed Aug 14 03:15:38 2002
+++ squid/src/fs/ufs/store_io_ufs.c	Mon Jan 15 14:49:22 2001
@@ -48,7 +48,7 @@
 storeUfsOpen(SwapDir * SD, StoreEntry * e, STFNCB * file_callback,
     STIOCB * callback, void *callback_data)
 {
-    sfileno f = e->p->swap_filen;
+    sfileno f = e->swap_filen;
     char *path = storeUfsDirFullPath(SD, f, NULL);
     storeIOState *sio;
     struct stat sb;
@@ -70,7 +70,7 @@
     sio->callback = callback;
     sio->callback_data = callback_data;
     cbdataLock(callback_data);
-    sio->p = e->p;
+    sio->e = e;
     ((ufsstate_t *) (sio->fsstate))->fd = fd;
     ((ufsstate_t *) (sio->fsstate))->flags.writing = 0;
     ((ufsstate_t *) (sio->fsstate))->flags.reading = 0;
@@ -118,7 +118,7 @@
     sio->callback = callback;
     sio->callback_data = callback_data;
     cbdataLock(callback_data);
-    sio->p = (PayloadEntry *) e->p;
+    sio->e = (StoreEntry *) e;
     ((ufsstate_t *) (sio->fsstate))->fd = fd;
     ((ufsstate_t *) (sio->fsstate))->flags.writing = 0;
     ((ufsstate_t *) (sio->fsstate))->flags.reading = 0;
@@ -126,7 +126,7 @@
     store_open_disk_fd++;
 
     /* now insert into the replacement policy */
-    storeUfsDirReplAdd(SD, e->p);
+    storeUfsDirReplAdd(SD, e);
     return sio;
 }
 
@@ -184,10 +184,10 @@
 void
 storeUfsUnlink(SwapDir * SD, StoreEntry * e)
 {
-    debug(79, 3) ("storeUfsUnlink: fileno %08X\n", e->p->swap_filen);
-    storeUfsDirReplRemove(e->p);
-    storeUfsDirMapBitReset(SD, e->p->swap_filen);
-    storeUfsDirUnlinkFile(SD, e->p->swap_filen);
+    debug(79, 3) ("storeUfsUnlink: fileno %08X\n", e->swap_filen);
+    storeUfsDirReplRemove(e);
+    storeUfsDirMapBitReset(SD, e->swap_filen);
+    storeUfsDirUnlinkFile(SD, e->swap_filen);
 }
 
 /*  === STATIC =========================================================== */
Index: squid/src/fs/ufs/store_ufs.h
diff -u squid/src/fs/ufs/store_ufs.h:1.2.126.1 squid/src/fs/ufs/store_ufs.h:1.2
--- squid/src/fs/ufs/store_ufs.h:1.2.126.1	Wed Aug 14 03:15:38 2002
+++ squid/src/fs/ufs/store_ufs.h	Sat Oct 21 09:44:46 2000
@@ -34,8 +34,8 @@
 extern int storeUfsDirMapBitAllocate(SwapDir *);
 extern char *storeUfsDirFullPath(SwapDir * SD, sfileno filn, char *fullpath);
 extern void storeUfsDirUnlinkFile(SwapDir *, sfileno);
-extern void storeUfsDirReplAdd(SwapDir * SD, PayloadEntry *);
-extern void storeUfsDirReplRemove(PayloadEntry *);
+extern void storeUfsDirReplAdd(SwapDir * SD, StoreEntry *);
+extern void storeUfsDirReplRemove(StoreEntry *);
 
 /*
  * Store IO stuff
Index: squid/src/repl/heap/store_heap_replacement.c
diff -u squid/src/repl/heap/store_heap_replacement.c:1.3.4.1.8.1 squid/src/repl/heap/store_heap_replacement.c:1.3.4.1
--- squid/src/repl/heap/store_heap_replacement.c:1.3.4.1.8.1	Wed Aug 14 03:15:38 2002
+++ squid/src/repl/heap/store_heap_replacement.c	Mon Jan 15 14:49:22 2001
@@ -65,9 +65,9 @@
  * turnarounds)
  */
 heap_key 
-HeapKeyGen_PayloadEntry_LFUDA(void *entry, double age)
+HeapKeyGen_StoreEntry_LFUDA(void *entry, double age)
 {
-    PayloadEntry *e = entry;
+    StoreEntry *e = entry;
     heap_key key;
     double tie;
     if (e->lastref <= 0)
@@ -77,8 +77,11 @@
     else
 	tie = 1.0 - exp((double) (e->lastref - squid_curtime) / 86400.0);
     key = age + (double) e->refcount - tie;
-    debug(81, 3) ("HeapKeyGen_PayloadEntry_LFUDA: %s refcnt=%ld lastref=%ld age=%f tie=%f -> %f\n",
+    debug(81, 3) ("HeapKeyGen_StoreEntry_LFUDA: %s refcnt=%ld lastref=%ld age=%f tie=%f -> %f\n",
 	storeKeyText(e->hash.key), e->refcount, e->lastref, age, tie, key);
+    if (e->mem_obj && e->mem_obj->url)
+	debug(81, 3) ("HeapKeyGen_StoreEntry_LFUDA: url=%s\n",
+	    e->mem_obj->url);
     return (double) key;
 }
 
@@ -103,15 +106,18 @@
  * turnarounds)
  */
 heap_key 
-HeapKeyGen_PayloadEntry_GDSF(void *entry, double age)
+HeapKeyGen_StoreEntry_GDSF(void *entry, double age)
 {
-    PayloadEntry *e = entry;
+    StoreEntry *e = entry;
     heap_key key;
     double size = e->swap_file_sz ? (double) e->swap_file_sz : 1.0;
     double tie = (e->lastref > 1) ? (1.0 / e->lastref) : 1.0;
     key = age + ((double) e->refcount / size) - tie;
-    debug(81, 3) ("HeapKeyGen_PayloadEntry_GDSF: %s size=%f refcnt=%ld lastref=%ld age=%f tie=%f -> %f\n",
+    debug(81, 3) ("HeapKeyGen_StoreEntry_GDSF: %s size=%f refcnt=%ld lastref=%ld age=%f tie=%f -> %f\n",
 	storeKeyText(e->hash.key), size, e->refcount, e->lastref, age, tie, key);
+    if (e->mem_obj && e->mem_obj->url)
+	debug(81, 3) ("HeapKeyGen_StoreEntry_GDSF: url=%s\n",
+	    e->mem_obj->url);
     return key;
 }
 
@@ -123,10 +129,13 @@
  * heap-based replacement policies...
  */
 heap_key 
-HeapKeyGen_PayloadEntry_LRU(void *entry, double age)
+HeapKeyGen_StoreEntry_LRU(void *entry, double age)
 {
-    PayloadEntry *e = entry;
-    debug(81, 3) ("HeapKeyGen_PayloadEntry_LRU: %s age=%f lastref=%f\n",
+    StoreEntry *e = entry;
+    debug(81, 3) ("HeapKeyGen_StoreEntry_LRU: %s age=%f lastref=%f\n",
 	storeKeyText(e->hash.key), age, (double) e->lastref);
+    if (e->mem_obj && e->mem_obj->url)
+	debug(81, 3) ("HeapKeyGen_StoreEntry_LRU: url=%s\n",
+	    e->mem_obj->url);
     return (heap_key) e->lastref;
 }
Index: squid/src/repl/heap/store_heap_replacement.h
diff -u squid/src/repl/heap/store_heap_replacement.h:1.2.124.1 squid/src/repl/heap/store_heap_replacement.h:1.2
--- squid/src/repl/heap/store_heap_replacement.h:1.2.124.1	Wed Aug 14 03:15:38 2002
+++ squid/src/repl/heap/store_heap_replacement.h	Sat Oct 21 09:44:46 2000
@@ -1,3 +1,3 @@
-extern heap_key HeapKeyGen_PayloadEntry_LFUDA(void *entry, double age);
-extern heap_key HeapKeyGen_PayloadEntry_GDSF(void *entry, double age);
-extern heap_key HeapKeyGen_PayloadEntry_LRU(void *entry, double age);
+extern heap_key HeapKeyGen_StoreEntry_LFUDA(void *entry, double age);
+extern heap_key HeapKeyGen_StoreEntry_GDSF(void *entry, double age);
+extern heap_key HeapKeyGen_StoreEntry_LRU(void *entry, double age);
Index: squid/src/repl/heap/store_repl_heap.c
diff -u squid/src/repl/heap/store_repl_heap.c:1.3.4.1.8.1 squid/src/repl/heap/store_repl_heap.c:1.3.4.1
--- squid/src/repl/heap/store_repl_heap.c:1.3.4.1.8.1	Wed Aug 14 03:15:38 2002
+++ squid/src/repl/heap/store_repl_heap.c	Mon Jan 15 14:49:22 2001
@@ -48,21 +48,48 @@
     heap_key_func *keyfunc;
     int count;
     int nwalkers;
+    enum heap_entry_type {
+	TYPE_UNKNOWN = 0, TYPE_STORE_ENTRY, TYPE_STORE_MEM
+    } type;
 };
 
+/* Hack to avoid having to remember the RemovalPolicyNode location.
+ * Needed by the purge walker.
+ */
+static enum heap_entry_type
+heap_guessType(StoreEntry * entry, RemovalPolicyNode * node)
+{
+    if (node == &entry->repl)
+	return TYPE_STORE_ENTRY;
+    if (entry->mem_obj && node == &entry->mem_obj->repl)
+	return TYPE_STORE_MEM;
+    fatal("Heap Replacement: Unknown StoreEntry node type");
+    return TYPE_UNKNOWN;
+}
+#define SET_POLICY_NODE(entry,value) \
+    switch(heap->type) { \
+    case TYPE_STORE_ENTRY: entry->repl.data = value; break ; \
+    case TYPE_STORE_MEM: entry->mem_obj->repl.data = value ; break ; \
+    default: break; \
+    }
+
 static void
-heap_add(RemovalPolicy * policy, PayloadEntry * entry, RemovalPolicyNode * node)
+heap_add(RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node)
 {
     HeapPolicyData *heap = policy->_data;
     assert(!node->data);
+    if (EBIT_TEST(entry->flags, ENTRY_SPECIAL))
+	return;			/* We won't manage these.. they messes things up */
     node->data = heap_insert(heap->heap, entry);
     heap->count += 1;
+    if (!heap->type)
+	heap->type = heap_guessType(entry, node);
     /* Add a little more variance to the aging factor */
     heap->heap->age += heap->heap->age / 100000000;
 }
 
 static void
-heap_remove(RemovalPolicy * policy, PayloadEntry * entry,
+heap_remove(RemovalPolicy * policy, StoreEntry * entry,
     RemovalPolicyNode * node)
 {
     HeapPolicyData *heap = policy->_data;
@@ -75,14 +102,14 @@
 }
 
 static void
-heap_referenced(RemovalPolicy * policy, const PayloadEntry * entry,
+heap_referenced(RemovalPolicy * policy, const StoreEntry * entry,
     RemovalPolicyNode * node)
 {
     HeapPolicyData *heap = policy->_data;
     heap_node *hnode = node->data;
     if (!hnode)
 	return;
-    heap_update(heap->heap, hnode, (PayloadEntry *) entry);
+    heap_update(heap->heap, hnode, (StoreEntry *) entry);
 }
 
 /** RemovalPolicyWalker **/
@@ -92,16 +119,16 @@
     int current;
 };
 
-const PayloadEntry *
+const StoreEntry *
 heap_walkNext(RemovalPolicyWalker * walker)
 {
     HeapWalkData *heap_walk = walker->_data;
     RemovalPolicy *policy = walker->_policy;
     HeapPolicyData *heap = policy->_data;
-    PayloadEntry *entry;
+    StoreEntry *entry;
     if (heap_walk->current >= heap_nodes(heap->heap))
 	return NULL;		/* done */
-    entry = (PayloadEntry *) heap_peep(heap->heap, heap_walk->current++);
+    entry = (StoreEntry *) heap_peep(heap->heap, heap_walk->current++);
     return entry;
 }
 
@@ -143,25 +170,25 @@
     heap_key min_age;
 };
 
-static PayloadEntry *
+static StoreEntry *
 heap_purgeNext(RemovalPurgeWalker * walker)
 {
     HeapPurgeData *heap_walker = walker->_data;
     RemovalPolicy *policy = walker->_policy;
     HeapPolicyData *heap = policy->_data;
-    PayloadEntry *entry;
+    StoreEntry *entry;
     heap_key age;
   try_again:
     if (!heap_nodes(heap->heap) > 0)
 	return NULL;		/* done */
     age = heap_peepminkey(heap->heap);
     entry = heap_extractmin(heap->heap);
-    if (payloadEntryLocked(entry)) {
+    if (storeEntryLocked(entry)) {
 	linklistPush(&heap_walker->locked_entries, entry);
 	goto try_again;
     }
     heap_walker->min_age = age;
-    entry->repl.data = NULL;
+    SET_POLICY_NODE(entry, NULL);
     return entry;
 }
 
@@ -171,7 +198,7 @@
     HeapPurgeData *heap_walker = walker->_data;
     RemovalPolicy *policy = walker->_policy;
     HeapPolicyData *heap = policy->_data;
-    PayloadEntry *entry;
+    StoreEntry *entry;
     assert(strcmp(policy->_type, "heap") == 0);
     assert(heap->nwalkers > 0);
     heap->nwalkers -= 1;
@@ -185,7 +212,7 @@
      */
     while ((entry = linklistShift(&heap_walker->locked_entries))) {
 	heap_node *node = heap_insert(heap->heap, entry);
-	entry->repl.data = node;
+	SET_POLICY_NODE(entry, node);
     }
     safe_free(walker->_data);
     cbdataFree(walker);
@@ -251,15 +278,15 @@
 	keytype = "LRU";
     }
     if (!strcmp(keytype, "GDSF"))
-	heap_data->keyfunc = HeapKeyGen_PayloadEntry_GDSF;
+	heap_data->keyfunc = HeapKeyGen_StoreEntry_GDSF;
     else if (!strcmp(keytype, "LFUDA"))
-	heap_data->keyfunc = HeapKeyGen_PayloadEntry_LFUDA;
+	heap_data->keyfunc = HeapKeyGen_StoreEntry_LFUDA;
     else if (!strcmp(keytype, "LRU"))
-	heap_data->keyfunc = HeapKeyGen_PayloadEntry_LRU;
+	heap_data->keyfunc = HeapKeyGen_StoreEntry_LRU;
     else {
 	debug(81, 0) ("createRemovalPolicy_heap: Unknown key type \"%s\". Using LRU\n",
 	    keytype);
-	heap_data->keyfunc = HeapKeyGen_PayloadEntry_LRU;
+	heap_data->keyfunc = HeapKeyGen_StoreEntry_LRU;
     }
     /* No additional arguments expected */
     assert(!args);
Index: squid/src/repl/lru/store_repl_lru.c
diff -u squid/src/repl/lru/store_repl_lru.c:1.2.6.1.8.1 squid/src/repl/lru/store_repl_lru.c:1.2.6.1
--- squid/src/repl/lru/store_repl_lru.c:1.2.6.1.8.1	Wed Aug 14 03:15:39 2002
+++ squid/src/repl/lru/store_repl_lru.c	Mon Jan 15 14:49:22 2001
@@ -52,13 +52,13 @@
  * Needed by the purge walker to clear the policy information
  */
 static enum heap_entry_type
-repl_guessType(PayloadEntry * entry, RemovalPolicyNode * node)
+repl_guessType(StoreEntry * entry, RemovalPolicyNode * node)
 {
     if (node == &entry->repl)
 	return TYPE_STORE_ENTRY;
     if (entry->mem_obj && node == &entry->mem_obj->repl)
 	return TYPE_STORE_MEM;
-    fatal("Heap Replacement: Unknown PayloadEntry node type");
+    fatal("Heap Replacement: Unknown StoreEntry node type");
     return TYPE_UNKNOWN;
 }
 #define SET_POLICY_NODE(entry,value) \
@@ -80,7 +80,7 @@
 static int nr_lru_policies = 0;
 
 static void
-lru_add(RemovalPolicy * policy, PayloadEntry * entry, RemovalPolicyNode * node)
+lru_add(RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node)
 {
     LruPolicyData *lru = policy->_data;
     LruNode *lru_node;
@@ -93,7 +93,7 @@
 }
 
 static void
-lru_remove(RemovalPolicy * policy, PayloadEntry * entry, RemovalPolicyNode * node)
+lru_remove(RemovalPolicy * policy, StoreEntry * entry, RemovalPolicyNode * node)
 {
     LruPolicyData *lru = policy->_data;
     LruNode *lru_node = node->data;
@@ -114,7 +114,7 @@
 }
 
 static void
-lru_referenced(RemovalPolicy * policy, const PayloadEntry * entry,
+lru_referenced(RemovalPolicy * policy, const StoreEntry * entry,
     RemovalPolicyNode * node)
 {
     LruPolicyData *lru = policy->_data;
@@ -132,7 +132,7 @@
     LruNode *current;
 };
 
-const PayloadEntry *
+const StoreEntry *
 lru_walkNext(RemovalPolicyWalker * walker)
 {
     LruWalkData *lru_walk = walker->_data;
@@ -140,7 +140,7 @@
     if (!lru_node)
 	return NULL;
     lru_walk->current = (LruNode *) lru_node->node.next;
-    return (PayloadEntry *) lru_node->node.data;
+    return (StoreEntry *) lru_node->node.data;
 }
 
 static void
@@ -181,14 +181,14 @@
     LruNode *start;
 };
 
-static PayloadEntry *
+static StoreEntry *
 lru_purgeNext(RemovalPurgeWalker * walker)
 {
     LruPurgeData *lru_walker = walker->_data;
     RemovalPolicy *policy = walker->_policy;
     LruPolicyData *lru = policy->_data;
     LruNode *lru_node;
-    PayloadEntry *entry;
+    StoreEntry *entry;
   try_again:
     lru_node = lru_walker->current;
     if (!lru_node || walker->scanned >= walker->max_scan)
@@ -199,9 +199,9 @@
 	/* Last node found */
 	lru_walker->current = NULL;
     }
-    entry = (PayloadEntry *) lru_node->node.data;
+    entry = (StoreEntry *) lru_node->node.data;
     dlinkDelete(&lru_node->node, &lru->list);
-    if (payloadEntryLocked(entry)) {
+    if (storeEntryLocked(entry)) {
 	/* Shit, it is locked. we can't return this one */
 	walker->locked++;
 	dlinkAddTail(entry, &lru_node->node, &lru->list);
