Index: squid/include/Array.h
diff -u squid/include/Array.h:1.2.4.3 squid/include/Array.h:1.2.4.2
--- squid/include/Array.h:1.2.4.3	Mon Nov 11 01:10:04 2002
+++ squid/include/Array.h	Mon Nov 11 00:25:30 2002
@@ -49,6 +49,7 @@
 extern void arrayDestroy(Array *s);
 extern void arrayAppend(Array *s, void *obj);
 extern void arrayPreAppend(Array * s, int app_count);
+extern void arrayDelete(Array * s, void *obj);
 
 
 #endif /* ndef _ARRAY_H_ */
Index: squid/lib/Array.c
diff -u squid/lib/Array.c:1.3.4.3 squid/lib/Array.c:1.3.4.2
--- squid/lib/Array.c:1.3.4.3	Mon Nov 11 01:10:06 2002
+++ squid/lib/Array.c	Mon Nov 11 00:25:30 2002
@@ -102,6 +102,20 @@
 	arrayGrow(a, a->count + app_count);
 }
 
+void 
+arrayDelete(Array * a, void * obj)
+{
+    int i,j;
+    assert(a);
+    assert(a->count > 0);
+    for (i = 0; i < a->count; ++i) 
+	if (a->items[i] == obj) 
+	    break;
+    --a->count;
+    for (j = i; j < a->count; ++j)
+	    a->items[j] = a->items[j+1];
+}
+
 /* grows internal buffer to satisfy required minimal capacity */
 static void
 arrayGrow(Array * a, int min_capacity)
Index: squid/src/Makefile.in
diff -u squid/src/Makefile.in:1.3.4.6 squid/src/Makefile.in:1.3.4.5
--- squid/src/Makefile.in:1.3.4.6	Mon Nov 11 01:10:06 2002
+++ squid/src/Makefile.in	Mon Nov 11 00:25:31 2002
@@ -76,6 +76,7 @@
 SHELL		= /bin/sh
 
 INCLUDE		= -I. -I../include -I$(top_srcdir)/include
+DEFINES		= -DDSA
 CFLAGS 		= $(AC_CFLAGS) $(INCLUDE) $(DEFINES)
 SQUID_LIBS	= -L../lib $(CRYPTLIB) $(REGEXLIB) @SQUID_PTHREAD_LIB@ \
 		  $(SNMPLIB) $(MALLOCLIB) -lmiscutil $(XTRA_LIBS)
Index: squid/src/asn.c
diff -u squid/src/asn.c:1.4.2.5 squid/src/asn.c:1.4.2.4
--- squid/src/asn.c:1.4.2.5	Mon Nov 11 01:10:08 2002
+++ squid/src/asn.c	Mon Nov 11 00:25: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 {
+#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);
@@ -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,
@@ -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);
     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.5 squid/src/cache_manager.c:1.3.4.4
--- squid/src/cache_manager.c:1.3.4.5	Mon Nov 11 01:10:08 2002
+++ squid/src/cache_manager.c	Mon Nov 11 00:25:31 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);
+#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;
+#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 */
-	httpReplyAbsorb(entry->mem_obj->reply, rep);
+#ifdef DSA	
+	httpReplyAbsorb(entry->p->mem_obj->reply, rep);
 	/* store the reply */
-	httpReplySwapOut(entry->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.11 squid/src/client_side.c:1.5.2.10
--- squid/src/client_side.c:1.5.2.11	Mon Nov 11 01:10:09 2002
+++ squid/src/client_side.c	Mon Nov 11 00:25:31 2002
@@ -94,7 +94,11 @@
 static void clientCheckNoCache(clientHttpRequest *);
 static void clientCheckNoCacheDone(int answer, void *data);
 static STCB clientHandleIMSReply;
+#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;
@@ -191,6 +195,27 @@
 	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
+    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)
 {
@@ -210,6 +235,7 @@
 	memAllocate(MEM_CLIENT_SOCK_BUF), clientSendMoreData, h);
     return e;
 }
+#endif
 
 void
 clientAccessCheckDone(int answer, void *data)
@@ -344,7 +370,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);
     /*
@@ -365,12 +395,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->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));
@@ -383,7 +422,11 @@
     /* Register with storage manager to receive updates when data comes in. */
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED))
 	debug(33, 0) ("clientProcessExpired: found ENTRY_ABORTED object\n");
+#ifdef DSA
+    storeClientCopy(http->sc, entry->p,
+#else
     storeClientCopy(http->sc, entry,
+#endif
 	http->out.offset,
 	http->out.offset,
 	CLIENT_SOCK_SZ,
@@ -393,9 +436,15 @@
 }
 
 static int
+#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;
@@ -434,11 +483,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);
@@ -450,31 +507,52 @@
 	memFree(buf, MEM_CLIENT_SOCK_BUF);
 	return;
     }
+#ifdef DSA
+    mem = entry->p->mem_obj;
+#else
     mem = entry->mem_obj;
+#endif
     status = mem->reply->sline.status;
     if (EBIT_TEST(entry->flags, ENTRY_ABORTED)) {
 	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);
 	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);
 	    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,
@@ -489,29 +567,56 @@
 	 * 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;
 	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;
+	}
+	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);
@@ -519,13 +624,18 @@
 	}
 	storeUnregister(http->old_sc, http->old_entry, http);
 	storeUnlockObject(http->old_entry);
+#endif
 	recopy = 0;
     }
     http->old_entry = NULL;	/* done with old_entry */
     http->old_sc = NULL;
     assert(!EBIT_TEST(entry->flags, ENTRY_ABORTED));
     if (recopy) {
+#ifdef DSA
+	storeClientCopy(http->sc, entry->p,
+#else
 	storeClientCopy(http->sc, entry,
+#endif
 	    http->out.offset,
 	    http->out.offset,
 	    CLIENT_SOCK_SZ,
@@ -538,12 +648,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);
@@ -552,7 +674,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;
@@ -574,7 +700,11 @@
 void
 clientPurgeRequest(clientHttpRequest * http)
 {
+#ifdef DSA
+    InstanceEntry *entry;
+#else
     StoreEntry *entry;
+#endif
     ErrorState *err = NULL;
     HttpReply *r;
     http_status status;
@@ -592,26 +722,55 @@
     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) {
+#else
     if ((entry = storeGetPublic(http->uri, METHOD_GET)) == NULL) {
+#endif
 	status = HTTP_NOT_FOUND;
     } else {
 	storeRelease(entry);
 	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)
 {
@@ -623,6 +782,7 @@
 	return 0;
     return 1;
 }
+#endif
 
 void
 clientUpdateCounters(clientHttpRequest * http)
@@ -694,10 +854,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
 	/*
@@ -711,12 +879,21 @@
 	    storeUnlockObject(e);
 	}
 #endif
+#ifdef DSA
+	if (http->entry && http->entry->p && http->entry->p->ping_status == PING_WAITING)
+#else
 	if (http->entry && http->entry->ping_status == PING_WAITING)
+#endif
 	    storeReleaseRequest(http->entry);
     }
     assert(http->log_type < LOG_TYPE_MAX);
+#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;
@@ -762,17 +939,29 @@
     stringClean(&http->range_iter.boundary);
     if ((e = http->entry)) {
 	http->entry = NULL;
+#ifdef DSA
+	storeUnregister(http->sc, e->p, http);
+	http->sc = NULL;
+	storeUnlockObject(e->p);
+#else
 	storeUnregister(http->sc, e, http);
 	http->sc = NULL;
 	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;
 	storeUnlockObject(e);
+#endif
     }
     requestUnlink(http->request);
     assert(http != http->next);
@@ -1093,14 +1282,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;
 
@@ -1137,7 +1334,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";
@@ -1337,7 +1538,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);
@@ -1350,24 +1555,40 @@
 	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;
 	    storeUnlockObject(e);
+#endif
 	}
 	clientProcessMiss(http);
 	return;
     }
     assert(size > 0);
+#ifdef DSA
+    mem = e->p->mem_obj;
+#else
     mem = e->mem_obj;
+#endif
     assert(!EBIT_TEST(e->flags, ENTRY_ABORTED));
     if (mem->reply->sline.status == 0) {
 	/*
 	 * we don't have full reply headers yet; either wait for more or
 	 * punt to clientProcessMiss.
 	 */
+#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) {
@@ -1375,7 +1596,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,
@@ -1398,7 +1623,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) {
@@ -1459,12 +1688,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;
 	    storeUnlockObject(e);
+#endif
 	    e = clientCreateStoreEntry(http, http->request->method, null_request_flags);
 	    /*
 	     * Copy timestamp from the original entry so the 304
@@ -1472,16 +1710,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;
@@ -1550,9 +1799,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
@@ -1684,7 +1939,11 @@
 clientSendMoreData(void *data, char *buf, ssize_t size)
 {
     clientHttpRequest *http = data;
+#ifdef DSA
+    StoreEntry *entry = http->entry->p;
+#else
     StoreEntry *entry = http->entry;
+#endif
     ConnStateData *conn = http->conn;
     int fd = conn->fd;
     HttpReply *rep = NULL;
@@ -1733,9 +1992,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;
 	    storeUnlockObject(http->entry);
+#endif
 	    http->entry = clientCreateStoreEntry(http, http->request->method,
 		null_request_flags);
 	    errorAppendEntry(http->entry, err);
@@ -1869,7 +2134,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.
@@ -1896,7 +2165,11 @@
 clientWriteComplete(int fd, char *bufnotused, size_t size, int errflag, void *data)
 {
     clientHttpRequest *http = data;
+#ifdef DSA
+    StoreEntry *entry = http->entry->p;
+#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",
@@ -1968,10 +2241,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;
 	storeUnlockObject(http->entry);
+#endif
     }
     http->entry = clientCreateStoreEntry(http, r->method, null_request_flags);
     errorAppendEntry(http->entry, err);
@@ -2017,11 +2297,19 @@
 clientProcessRequest2(clientHttpRequest * http)
 {
     request_t *r = http->request;
+#ifdef DSA
+    InstanceEntry *e;
+    e = http->entry = instanceGetPublic(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 = 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)
@@ -2060,10 +2348,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;
 	}
@@ -2087,7 +2382,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;
@@ -2119,15 +2418,26 @@
 	if (r->max_forwards == 0) {
 	    http->entry = clientCreateStoreEntry(http, r->method, null_request_flags);
 	    storeReleaseRequest(http->entry);
+#ifdef DSA
+	    storeBuffer(http->entry->p);
+#else
 	    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 */
@@ -2146,15 +2456,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) {
-	storeLockObject(http->entry);
+	storeLockObject(http->entry->p);
 	storeCreateMemObject(http->entry, http->uri, http->log_uri);
 	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,
@@ -2186,11 +2508,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;
 	storeUnlockObject(http->entry);
+#endif
 	http->entry = NULL;
     }
     if (clientOnlyIfCached(http)) {
@@ -2218,9 +2548,15 @@
 #endif
 	storeReleaseRequest(http->entry);
 	httpRedirectReply(rep, http->redirect.status, http->redirect.location);
+#ifdef DSA
+	httpReplySwapOut(rep, http->entry->p);
+	httpReplyDestroy(rep);
+	storeComplete(http->entry->p);
+#else
 	httpReplySwapOut(rep, http->entry);
 	httpReplyDestroy(rep);
 	storeComplete(http->entry);
+#endif
 	return;
     }
     if (http->flags.internal)
@@ -2929,7 +3265,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;
@@ -2995,8 +3335,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/enums.h
diff -u squid/src/enums.h:1.5.2.5 squid/src/enums.h:1.5.2.4
--- squid/src/enums.h:1.5.2.5	Mon Nov 11 01:10:11 2002
+++ squid/src/enums.h	Mon Nov 11 00:25:32 2002
@@ -594,6 +594,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.5 squid/src/errorpage.c:1.4.2.4
--- squid/src/errorpage.c:1.4.2.5	Mon Nov 11 01:10:13 2002
+++ squid/src/errorpage.c	Mon Nov 11 00:25:32 2002
@@ -258,8 +258,14 @@
  *            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->mem_obj;
     assert(mem != NULL);
@@ -301,8 +307,13 @@
     EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
     storeBufferFlush(entry);
     storeComplete(entry);
+#ifdef DSA
+    storeNegativeCache(e);
+    storeReleaseRequest(e);
+#else
     storeNegativeCache(entry);
     storeReleaseRequest(entry);
+#endif
     storeUnlockObject(entry);
     errorStateFree(err);
 }
Index: squid/src/forward.c
diff -u squid/src/forward.c:1.4.4.3 squid/src/forward.c:1.4.4.2
--- squid/src/forward.c:1.4.4.3	Mon Nov 11 01:10:13 2002
+++ squid/src/forward.c	Mon Nov 11 00:25:32 2002
@@ -69,7 +69,11 @@
 static void
 fwdStateFree(FwdState * fwdState)
 {
+#ifdef DSA	
+    StoreEntry *e = fwdState->entry->p;
+#else    
     StoreEntry *e = fwdState->entry;
+#endif    
     int sfd;
     debug(17, 3) ("fwdStateFree: %p\n", fwdState);
     assert(e->mem_obj);
@@ -82,12 +86,20 @@
     if (e->store_status == STORE_PENDING) {
 	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);
 	    storeComplete(e);
+#ifdef DSA
+	    storeReleaseRequest(fwdState->entry);
+#else
 	    storeReleaseRequest(e);
+#endif
 	}
     }
     if (storePendingNClients(e) > 0)
@@ -113,9 +125,15 @@
 static int
 fwdCheckRetry(FwdState * fwdState)
 {
+#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 +151,11 @@
 fwdServerClosed(int fd, void *data)
 {
     FwdState *fwdState = data;
+#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 +228,22 @@
 	    peerConnectFailed(fs->peer);
 	comm_close(server_fd);
     } else {
+#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);
 	else if (Config.onoff.log_ip_on_direct)
 	    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,7 +256,11 @@
 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));
     assert(fd == fwdState->server_fd);
@@ -249,7 +283,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;
@@ -314,7 +352,11 @@
 fwdStartComplete(FwdServer * servers, void *data)
 {
     FwdState *fwdState = data;
+#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 +369,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 +386,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,
@@ -409,7 +459,11 @@
 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);
@@ -452,7 +506,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;
@@ -481,9 +539,15 @@
 	    return;
 	}
     }
+#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->mem_obj->chksum == url_checksum(e->mem_obj->url));
 #endif
@@ -517,9 +581,15 @@
     fwdState->server_fd = -1;
     fwdState->request = requestLink(r);
     fwdState->start = squid_curtime;
+#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);
 }
 
@@ -564,7 +634,11 @@
     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 +651,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 +665,11 @@
 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,7 +685,11 @@
 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->mem_obj->reply->sline.status);
Index: squid/src/ftp.c
diff -u squid/src/ftp.c:1.4.2.9 squid/src/ftp.c:1.4.2.8
--- squid/src/ftp.c:1.4.2.9	Mon Nov 11 01:10:13 2002
+++ squid/src/ftp.c	Mon Nov 11 00:25:32 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);
     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,7 +907,11 @@
     int len;
     int j;
     int bin;
+#ifdef DSA    
+    StoreEntry *entry = ftpState->entry->p;
+#else    
     StoreEntry *entry = ftpState->entry;
+#endif    
     MemObject *mem = entry->mem_obj;
     size_t read_sz;
 #if DELAY_POOLS
@@ -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++;
     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;
@@ -1093,7 +1133,11 @@
 	}
 	/* eject any old cached object */
 	key = storeKeyPublic(entry->mem_obj->url, entry->mem_obj->method);
+#ifdef DSA	
+	if ((pe = instanceGet(key)) != NULL)
+#else		
 	if ((pe = storeGet(key)) != NULL)
+#endif		
 	    storeRelease(pe);
 	/* create reply */
 	reply = entry->mem_obj->reply;
@@ -1253,7 +1297,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)) {
@@ -1706,7 +1754,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 +1903,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");
@@ -2354,7 +2410,11 @@
 static void
 ftpFailed(FtpStateData * ftpState, err_type error)
 {
+#ifdef DSA	
+    StoreEntry *entry = ftpState->entry->p;
+#else    
     StoreEntry *entry = ftpState->entry;
+#endif    
     if (entry->mem_obj->inmem_hi == 0)
 	ftpFailedErrorMessage(ftpState, error);
     if (ftpState->data.fd > -1) {
@@ -2470,7 +2530,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 +2560,11 @@
     else
 	err->ftp.reply = xstrdup("");
     errorAppendEntry(ftpState->entry, err);
+#ifdef DSA    
+    storeBufferFlush(ftpState->entry->p);
+#else    
     storeBufferFlush(ftpState->entry);
+#endif    
     ftpSendQuit(ftpState);
 }
 
@@ -2508,8 +2576,13 @@
     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;
+#endif    
     http_reply *reply = e->mem_obj->reply;
     http_version_t version;
     if (ftpState->flags.http_header_sent)
@@ -2559,20 +2632,37 @@
     httpReplySwapOut(reply, e);
     storeBufferFlush(e);
     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
 	 */
+#ifdef DSA	
+	pe = instanceGetPublic(e->mem_obj->url, e->mem_obj->method);
+	if (pe)
+	    storeRelease(pe);
+	storeRelease(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 {
+	storeRelease(ftpState->entry);
+#else	
 	storeSetPublicKey(e);
     } else {
 	storeRelease(e);
+#endif	
     }
 }
 
Index: squid/src/globals.h
diff -u squid/src/globals.h:1.4.2.4 squid/src/globals.h:1.4.2.3
--- squid/src/globals.h:1.4.2.4	Mon Nov 11 01:10:15 2002
+++ squid/src/globals.h	Mon Nov 11 00:25:32 2002
@@ -125,6 +125,9 @@
 extern double current_dtime;
 extern int store_hash_buckets;	/* 0 */
 extern hash_table *store_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 */
Index: squid/src/gopher.c
diff -u squid/src/gopher.c:1.4.2.5 squid/src/gopher.c:1.4.2.4
--- squid/src/gopher.c:1.4.2.5	Mon Nov 11 01:10:15 2002
+++ squid/src/gopher.c	Mon Nov 11 00:25:33 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) {
 	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,7 +595,11 @@
 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->mem_obj->inmem_hi == 0) {
@@ -593,7 +616,11 @@
 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;
@@ -640,7 +667,11 @@
 	    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);
@@ -650,14 +681,22 @@
 	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. */
@@ -774,10 +821,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();
     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.6 squid/src/http.c:1.4.4.5
--- squid/src/http.c:1.4.4.6	Mon Nov 11 01:10:15 2002
+++ squid/src/http.c	Mon Nov 11 00:25:33 2002
@@ -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;
+#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,7 +103,11 @@
 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->mem_obj->inmem_hi == 0) {
@@ -104,15 +120,25 @@
 
 /* This object can be cached for a long time */
 static void
+#ifdef DSA
+httpMakePublic(InstanceEntry * entry)
+{
+    if (EBIT_TEST(entry->p->flags, ENTRY_CACHABLE))
+#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)
+#else
 httpMakePrivate(StoreEntry * entry)
+#endif	
 {
     storeExpireNow(entry);
     storeReleaseRequest(entry);	/* delete object when not used */
@@ -121,19 +147,34 @@
 
 /* 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,8 +208,13 @@
     }
     if (!remove && !forbidden)
 	return;
+#ifdef DSA    
+    assert(e->p->mem_obj);
+    if ((pe = instanceGetPublic(e->p->mem_obj->url, e->p->mem_obj->method)) != NULL) {
+#else	    
     assert(e->mem_obj);
     if ((pe = storeGetPublic(e->mem_obj->url, e->mem_obj->method)) != NULL) {
+#endif	    
 	assert(e != pe);
 	storeRelease(pe);
     }
@@ -176,13 +222,21 @@
      * Also remove any cached HEAD response in case the object has
      * changed.
      */
+#ifdef DSA   
+    if ((pe = instanceGetPublic(e->p->mem_obj->url, METHOD_HEAD)) != NULL) {
+#else	    
     if ((pe = storeGetPublic(e->mem_obj->url, METHOD_HEAD)) != NULL) {
+#endif	    
 	assert(e != pe);
 	storeRelease(pe);
     }
     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,7 +248,11 @@
 	 * Remove any cached GET object if it is beleived that the
 	 * object may have changed as a result of other methods
 	 */
+#ifdef DSA	    
+	if ((pe = instanceGetPublic(e->p->mem_obj->url, METHOD_GET)) != NULL) {
+#else		
 	if ((pe = storeGetPublic(e->mem_obj->url, METHOD_GET)) != NULL) {
+#endif		
 	    assert(e != pe);
 	    storeRelease(pe);
 	}
@@ -205,7 +263,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 +309,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,7 +385,11 @@
 httpProcessReplyHeader(HttpStateData * httpState, const char *buf, int size)
 {
     char *t = NULL;
+#ifdef DSA 
+    StoreEntry *entry = httpState->entry->p;
+#else 
     StoreEntry *entry = httpState->entry;
+#endif 
     int room;
     size_t hdr_len;
     HttpReply *reply = entry->mem_obj->reply;
@@ -359,13 +429,30 @@
     /* Parse headers into reply structure */
     /* what happens if we fail to parse here? */
     httpReplyParse(reply, httpState->reply_hdr, hdr_len);
+#ifdef DSA
+    storeTimestampsSet(httpState->entry);
+#else
     storeTimestampsSet(entry);
+#endif
     /* Check if object is cacheable or not based on reply code */
     debug(11, 3) ("httpProcessReplyHeader: HTTP CODE: %d\n", reply->sline.status);
     if (neighbors_do_private_keys)
+#ifdef DSA
+	httpMaybeRemovePublic(httpState->entry, reply->sline.status);
+#else
 	httpMaybeRemovePublic(entry, reply->sline.status);
+#endif
     switch (httpCachableReply(httpState)) {
     case 1:
+#ifdef DSA
+	httpMakePublic(httpState->entry);
+	break;
+    case 0:
+	httpMakePrivate(httpState->entry);
+	break;
+    case -1:
+	httpCacheNegatively(httpState->entry);
+#else
 	httpMakePublic(entry);
 	break;
     case 0:
@@ -373,6 +460,7 @@
 	break;
     case -1:
 	httpCacheNegatively(entry);
+#endif
 	break;
     default:
 	assert(0);
@@ -406,7 +494,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 +549,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;
@@ -595,7 +691,11 @@
 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);
@@ -613,7 +713,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 {
@@ -850,7 +954,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;
@@ -906,9 +1014,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);
+#ifdef DSA
+    storeLockObject(fwd->entry->p);
+#else
     storeLockObject(fwd->entry);
+#endif
     httpState->fwd = fwd;
     httpState->entry = fwd->entry;
     httpState->fd = fd;
@@ -916,7 +1032,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;
@@ -930,7 +1050,11 @@
 	 * for example, the request to this neighbor fails.
 	 */
 	if (httpState->peer->options.proxy_only)
+#ifdef DSA
+	    storeReleaseRequest(httpState->entry);
+#else
 	    storeReleaseRequest(httpState->entry);
+#endif
 #if DELAY_POOLS
 	assert(delayIsNoDelay(fd) == 0);
 	if (httpState->peer->options.no_delay)
@@ -958,7 +1082,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);
@@ -973,7 +1101,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;
     }
@@ -988,7 +1120,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.3 squid/src/icp_v2.c:1.3.4.2
--- squid/src/icp_v2.c:1.3.4.3	Mon Nov 11 01:10:16 2002
+++ squid/src/icp_v2.c	Mon Nov 11 00:25:33 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.5 squid/src/internal.c:1.3.4.4
--- squid/src/internal.c:1.3.4.5	Mon Nov 11 01:10:17 2002
+++ squid/src/internal.c	Mon Nov 11 00:25:33 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;
@@ -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.3 squid/src/mem.c:1.3.4.2
--- squid/src/mem.c:1.3.4.3	Mon Nov 11 01:10:17 2002
+++ squid/src/mem.c	Mon Nov 11 00:25:33 2002
@@ -277,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.5 squid/src/mime.c:1.3.4.4
--- squid/src/mime.c:1.3.4.5	Mon Nov 11 01:10:18 2002
+++ squid/src/mime.c	Mon Nov 11 00:25:34 2002
@@ -391,7 +391,11 @@
     int n;
     request_flags flags;
     struct stat sb;
+#ifdef DSA
+    InstanceEntry *e;
+#else
     StoreEntry *e;
+#endif
     LOCAL_ARRAY(char, path, MAXPATHLEN);
     LOCAL_ARRAY(char, url, MAX_URL);
     char *buf;
@@ -416,33 +420,60 @@
     }
     flags = null_request_flags;
     flags.cachable = 1;
+#ifdef DSA
+    e = instanceCreateEntry(url,
+#else
     e = storeCreateEntry(url,
+#endif
 	url,
 	flags,
 	METHOD_GET);
     assert(e != NULL);
     storeSetPublicKey(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);
+#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);
     while ((n = read(fd, buf, 4096)) > 0)
+#ifdef DSA
+	storeAppend(e->p, buf, n);
+#else
 	storeAppend(e, buf, n);
+#endif
     file_close(fd);
     EBIT_SET(e->flags, ENTRY_SPECIAL);
+#ifdef DSA
+    storeBufferFlush(e->p);
+    storeComplete(e->p);
+    storeTimestampsSet(e);
+    debug(25, 3) ("Loaded icon %s\n", url);
+    storeUnlockObject(e->p);
+#else
     storeBufferFlush(e);
     storeComplete(e);
     storeTimestampsSet(e);
     debug(25, 3) ("Loaded icon %s\n", url);
     storeUnlockObject(e);
+#endif
     memFree(buf, MEM_4K_BUF);
 }
Index: squid/src/neighbors.c
diff -u squid/src/neighbors.c:1.5.2.6 squid/src/neighbors.c:1.5.2.5
--- squid/src/neighbors.c:1.5.2.6	Mon Nov 11 01:10:18 2002
+++ squid/src/neighbors.c	Mon Nov 11 00:25:34 2002
@@ -1116,7 +1116,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 +1128,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 +1157,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 +1175,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,
@@ -1174,7 +1194,11 @@
     EBIT_SET(fake->flags, ENTRY_ABORTED);
     requestUnlink(fake->mem_obj->request);
     fake->mem_obj->request = NULL;
+#ifdef DSA
+    storeReleaseRequest(psstate->entry);
+#else
     storeReleaseRequest(fake);
+#endif
     storeUnlockObject(fake);
     requestUnlink(psstate->request);
     cbdataFree(psstate);
@@ -1184,7 +1208,11 @@
 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;
+#endif    
     MemObject *mem = fake->mem_obj;
     int rtt = tvSubMsec(mem->start_ping, current_time);
     assert(proto == PROTO_ICP);
Index: squid/src/peer_select.c
diff -u squid/src/peer_select.c:1.3.4.4 squid/src/peer_select.c:1.3.4.3
--- squid/src/peer_select.c:1.3.4.4	Mon Nov 11 01:10:19 2002
+++ squid/src/peer_select.c	Mon Nov 11 00:25:34 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);
 	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)
 	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.11 squid/src/protos.h:1.4.4.10
--- squid/src/protos.h:1.4.4.11	Mon Nov 11 01:10:19 2002
+++ squid/src/protos.h	Mon Nov 11 00:25:34 2002
@@ -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);
 
@@ -807,31 +836,60 @@
 /*
  * store.c
  */
-extern StoreEntry *new_StoreEntry(int, const char *, const char *);
 extern StoreEntry *storeGet(const cache_key *);
 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 *);
+extern void storeAbort(InstanceEntry *);
+extern void payloadRelease(StoreEntry *);
+extern void payloadReleaseRequest(StoreEntry *);
+#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 *);
+extern void storeAbort(StoreEntry *);
+#endif
 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 storeRelease(InstanceEntry *);
+extern void storeReleaseRequest(InstanceEntry *);
+#else
 extern void storeRelease(StoreEntry *);
+extern void storeReleaseRequest(StoreEntry *);
+#endif
 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 DSA
+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);
@@ -850,7 +908,11 @@
 #endif
 extern void storeAppendVPrintf(StoreEntry *, const char *, va_list ap);
 extern int storeCheckCachable(StoreEntry * e);
+#ifdef DSA
+extern void storeSetPrivateKey(InstanceEntry *);
+#else
 extern void storeSetPrivateKey(StoreEntry *);
+#endif
 extern int objectLen(const StoreEntry * e);
 extern int contentLen(const StoreEntry * e);
 extern HttpReply *storeEntryReply(StoreEntry *);
@@ -1060,7 +1122,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);
@@ -1142,7 +1208,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.3 squid/src/pump.c:1.4.4.2
--- squid/src/pump.c:1.4.4.3	Mon Nov 11 01:10:22 2002
+++ squid/src/pump.c	Mon Nov 11 00:25:34 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);
+#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);
     }
@@ -192,7 +217,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 +236,11 @@
     if (cbdataValid(p->cbdata))
 	p->callback(sfd, NULL, p->sent, 0, p->cbdata);
     cbdataUnlock(p->cbdata);
+#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 +255,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;
@@ -298,8 +335,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);
@@ -344,8 +386,13 @@
 	pump_head = p->next;
     assert(fd == p->c_fd);
     p->c_fd = -1;
+#ifdef DSA    
+    req = p->request_entry->p;
+    rep = p->reply_entry->p;
+#else    
     req = p->request_entry;
     rep = p->reply_entry;
+#endif    
     if (req != NULL) {
 	storeUnregister(p->sc, req, p);
 	storeUnlockObject(req);
@@ -410,7 +457,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.4 squid/src/refresh.c:1.5.2.3
--- squid/src/refresh.c:1.5.2.4	Mon Nov 11 01:10:22 2002
+++ squid/src/refresh.c	Mon Nov 11 00:25:34 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,7 +336,11 @@
 }
 
 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.
@@ -336,6 +357,15 @@
     if (entry->lastmod < 0)
 	/* Last modified is needed to do a refresh */
 	return 0;
+#ifdef DSA    
+    if (entry->p->mem_obj == NULL)
+	/* 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;
@@ -343,6 +373,7 @@
 	/* 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++;
Index: squid/src/stat.c
diff -u squid/src/stat.c:1.4.4.4 squid/src/stat.c:1.4.4.3
--- squid/src/stat.c:1.4.4.4	Mon Nov 11 01:10:23 2002
+++ squid/src/stat.c	Mon Nov 11 00:25:35 2002
@@ -244,11 +244,13 @@
 describeTimestamps(const StoreEntry * entry)
 {
     LOCAL_ARRAY(char, buf, 256);
+#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;
 }
 
@@ -1424,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.7 squid/src/store.c:1.4.4.6
--- squid/src/store.c:1.4.4.7	Mon Nov 11 01:10:24 2002
+++ squid/src/store.c	Mon Nov 11 00:25:35 2002
@@ -73,6 +73,9 @@
 
 extern OBJH storeIOStats;
 
+#ifdef DSA
+static void instanceHashDelete(InstanceEntry *);
+#endif
 /*
  * local function prototypes
  */
@@ -127,6 +130,128 @@
     return mem;
 }
 
+#ifdef DSA
+void
+payloadReleaseRequest(StoreEntry * e)
+{
+    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);
+}
+
+/* release an object from a cache */
+void
+payloadRelease(StoreEntry * p)
+{
+//    assert(p->instances);
+    debug(20, 3) ("storeRelease: Releasing: '%s'\n", storeKeyText(p->hash.key));
+    /* If, for any reason we can't discard this object because of an
+     * outstanding request, mark it for pending release */
+    if (storeEntryLocked(p)) {
+	debug(20, 3) ("payloadRelease: Only setting RELEASE_REQUEST bit\n");
+	payloadReleaseRequest(p);
+	return;
+    }
+    if (store_dirs_rebuilding && p->swap_filen > -1) {
+	if (p->swap_filen > -1) {
+	    /*
+	     * Fake a call to storeLockObject().  When rebuilding is done,
+	     * we'll just call storeUnlockObject() on these.
+	     */
+	    p->lock_count++;
+	    EBIT_SET(p->flags, RELEASE_REQUEST);
+	    stackPush(&LateReleaseStack, p);
+	    return;
+	} else {
+	    destroy_StoreEntry(p);
+	}
+    }
+    if (p->swap_filen > -1) {
+	storeUnlink(p);
+	if (p->swap_status == SWAPOUT_DONE)
+	    if (EBIT_TEST(p->flags, ENTRY_VALIDATED))
+		storeDirUpdateSwapSize(&Config.cacheSwap.swapDirs[p->swap_dirn], p->swap_file_sz, -1);
+	    storeDirSwapLog(p, SWAP_LOG_DEL);
+    }
+    destroy_StoreEntry(p);
+}
+
+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);
+    }
+    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->flags, KEY_PRIVATE))
+	storeAddInstanceEntry(e->p, e);
+    if (flags.cachable) {
+	EBIT_SET(e->p->flags, ENTRY_CACHABLE);
+	EBIT_CLR(e->flags, RELEASE_REQUEST);
+    } else {
+	EBIT_CLR(e->p->flags, ENTRY_CACHABLE);
+	storeReleaseRequest(e);
+    }
+    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)
 {
@@ -140,6 +265,7 @@
     e->swap_dirn = -1;
     return e;
 }
+#endif
 
 static void
 destroy_MemObject(StoreEntry * e)
@@ -216,7 +342,11 @@
     storeSetMemStatus(e, NOT_IN_MEMORY);
     destroy_MemObject(e);
     if (e->swap_status != SWAPOUT_DONE)
+#ifdef DSA
+	payloadRelease(e);
+#else
 	storeRelease(e);
+#endif
 }
 
 static void
@@ -266,7 +396,11 @@
 }
 
 void
+#ifdef DSA
+storeReleaseRequest(InstanceEntry * e)
+#else
 storeReleaseRequest(StoreEntry * e)
+#endif
 {
     if (EBIT_TEST(e->flags, RELEASE_REQUEST))
 	return;
@@ -295,7 +429,11 @@
 	EBIT_SET(e->flags, RELEASE_REQUEST);
     assert(storePendingNClients(e) == 0);
     if (EBIT_TEST(e->flags, RELEASE_REQUEST))
+#ifdef DSA
+	payloadRelease(e);
+#else
 	storeRelease(e);
+#endif
     else if (storeKeepInMemory(e)) {
 	storeEntryDereferenced(e);
 	storeSetMemStatus(e, IN_MEMORY);
@@ -334,6 +472,66 @@
     return key_counter;
 }
 
+#ifdef DSA
+void
+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);
+	storeHashDelete(e->p);
+	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;
+    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);
+	storeRelease(e2);
+	newkey = storeKeyPublic(mem->url, mem->method);
+    }
+    if (e->hash.key)
+	instanceHashDelete(e);
+    EBIT_CLR(e->flags, KEY_PRIVATE);
+    instanceHashInsert(e, newkey);
+    if (e->p->swap_filen > -1)
+	storeDirSwapLog(e->p, SWAP_LOG_ADD);
+}
+#else
 void
 storeSetPrivateKey(StoreEntry * e)
 {
@@ -396,7 +594,191 @@
     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;
+    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;	    
+    arrayAppend(p->instances, e);
+    EBIT_SET(e->flags, ENTRY_CACHABLE);
+    e->p = p;
+    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)
 {
@@ -431,10 +813,15 @@
     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;
@@ -591,7 +978,12 @@
 	store_check_cachable_hist.yes.Default++;
 	return 1;
     }
+#ifdef DSA
+    assert(e->instances->count == 1);
+    storeReleaseRequest(e->instances->items[0]);
+#else
     storeReleaseRequest(e);
+#endif
     EBIT_CLR(e->flags, ENTRY_CACHABLE);
     return 0;
 }
@@ -644,7 +1036,12 @@
     assert(e->mem_status == NOT_IN_MEMORY);
     if (!storeEntryValidLength(e)) {
 	EBIT_SET(e->flags, ENTRY_BAD_LENGTH);
+#ifdef DSA
+	assert(e->instances->count == 1);
+	storeReleaseRequest(e->instances->items[0]);
+#else
 	storeReleaseRequest(e);
+#endif
     }
 #if USE_CACHE_DIGESTS
     if (e->mem_obj->request)
@@ -666,18 +1063,34 @@
  * entry for releasing
  */
 void
+#ifdef DSA
+storeAbort(InstanceEntry * e)
+{
+    MemObject *mem = e->p->mem_obj;
+    assert(e->p->store_status == STORE_PENDING);
+#else
 storeAbort(StoreEntry * e)
 {
     MemObject *mem = e->mem_obj;
     assert(e->store_status == STORE_PENDING);
+#endif
     assert(mem != NULL);
     debug(20, 6) ("storeAbort: %s\n", storeKeyText(e->hash.key));
-    storeLockObject(e);		/* lock while aborting */
+#ifdef DSA
+    storeLockObject(e->p);		/* lock while aborting */
+#else
+    storeLockObject(e);
+#endif
     storeNegativeCache(e);
     storeReleaseRequest(e);
     EBIT_SET(e->flags, ENTRY_ABORTED);
+#ifdef DSA
+    storeSetMemStatus(e->p, NOT_IN_MEMORY);
+    e->p->store_status = STORE_OK;
+#else
     storeSetMemStatus(e, NOT_IN_MEMORY);
     e->store_status = STORE_OK;
+#endif
     /*
      * We assign an object length here.  The only other place we assign
      * the object length is in storeComplete()
@@ -694,10 +1107,17 @@
 	mem->abort.data = NULL;
     }
     /* Notify the client side */
+#ifdef DSA
+    InvokeHandlers(e->p);
+    /* Close any swapout file */
+    storeSwapOutFileClose(e->p);
+    storeUnlockObject(e->p);	/* unlock */
+#else
     InvokeHandlers(e);
     /* Close any swapout file */
     storeSwapOutFileClose(e);
     storeUnlockObject(e);	/* unlock */
+#endif
 }
 
 /* Clear Memory storage to accommodate the given object len */
@@ -769,7 +1189,39 @@
     eventAdd("MaintainSwapSpace", storeMaintainSwapSpace, NULL, 1.0, 1);
 }
 
-
+#ifdef DSA
+/* release an object from a cache */
+void
+storeRelease(InstanceEntry * e)
+{
+    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");
+	storeReleaseRequest(e);
+	return;
+    }
+    if (store_dirs_rebuilding && e->p->swap_dirn > -1) {
+	storeSetPrivateKey(e);
+	if (e->p->swap_filen > -1) {
+	    /*
+	     * Fake a call to storeLockObject().  When rebuilding is done,
+	     * we'll just call storeUnlockObject() on these.
+	     */
+	    e->p->lock_count++;
+	    EBIT_SET(e->flags, RELEASE_REQUEST);
+	    return;
+	} else {
+	    destroy_StoreEntry(e);
+	}
+    }
+    storeLog(STORE_LOG_RELEASE, e->p);
+    storeRemoveInstanceEntry(e->p, e);
+    destroy_StoreEntry(e);
+}
+#else
 /* release an object from a cache */
 void
 storeRelease(StoreEntry * e)
@@ -818,6 +1270,7 @@
     storeSetMemStatus(e, NOT_IN_MEMORY);
     destroy_StoreEntry(e);
 }
+#endif
 
 static void
 storeLateRelease(void *unused)
@@ -969,7 +1422,11 @@
 }
 
 void
+#ifdef DSA
+storeNegativeCache(InstanceEntry * e)
+#else
 storeNegativeCache(StoreEntry * e)
+#endif
 {
     e->expires = squid_curtime + Config.negativeTtl;
     EBIT_SET(e->flags, ENTRY_NEGCACHED);
@@ -997,7 +1454,11 @@
 }
 
 int
+#ifdef DSA
+storeEntryValidToSend(InstanceEntry * e)
+#else
 storeEntryValidToSend(StoreEntry * e)
+#endif
 {
     if (EBIT_TEST(e->flags, RELEASE_REQUEST))
 	return 0;
@@ -1010,9 +1471,17 @@
 }
 
 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);
     /*
@@ -1093,10 +1562,12 @@
     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->mem_obj);
-    debug(20, l) ("StoreEntry->timestamp: %d\n", (int) e->timestamp);
     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));
@@ -1214,7 +1685,9 @@
     mem->inmem_hi = mem->inmem_lo = 0;
     httpReplyDestroy(mem->reply);
     mem->reply = httpReplyCreate();
+#ifndef DSA    
     e->expires = e->lastmod = e->timestamp = -1;
+#endif
 }
 
 /*
Index: squid/src/store_client.c
diff -u squid/src/store_client.c:1.4.4.3 squid/src/store_client.c:1.4.4.2
--- squid/src/store_client.c:1.4.4.3	Mon Nov 11 01:10:25 2002
+++ squid/src/store_client.c	Mon Nov 11 00:25:35 2002
@@ -662,5 +662,10 @@
     if (CheckQuickAbort2(entry) == 0)
 	return;
     statCounter.aborted_requests++;
+#ifdef DSA
+    assert(entry->instances->count == 1);
+    storeAbort(entry->instances->items[0]);
+#else
     storeAbort(entry);
+#endif
 }
Index: squid/src/store_swapmeta.c
diff -u squid/src/store_swapmeta.c:1.4.4.4 squid/src/store_swapmeta.c:1.4.4.3
--- squid/src/store_swapmeta.c:1.4.4.4	Mon Nov 11 01:10:25 2002
+++ squid/src/store_swapmeta.c	Mon Nov 11 00:25:36 2002
@@ -72,7 +72,11 @@
     url = storeUrl(e);
     debug(20, 3) ("storeSwapMetaBuild: %s\n", url);
     T = storeSwapTLVAdd(STORE_META_KEY, e->hash.key, MD5_DIGEST_CHARS, T);
+#ifdef DSA    
+    T = storeSwapTLVAdd(STORE_META_STD, &e->lastref, STORE_HDR_METASIZE, T);
+#else    
     T = storeSwapTLVAdd(STORE_META_STD, &e->timestamp, STORE_HDR_METASIZE, T);
+#endif    
     T = storeSwapTLVAdd(STORE_META_URL, url, strlen(url) + 1, T);
     return TLV;
 }
@@ -152,3 +156,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, STORE_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.4 squid/src/store_swapout.c:1.4.4.3
--- squid/src/store_swapout.c:1.4.4.4	Mon Nov 11 01:10:26 2002
+++ squid/src/store_swapout.c	Mon Nov 11 00:25:36 2002
@@ -168,7 +168,12 @@
 	 * so we must make it PRIVATE.  This is tricky/ugly because
 	 * for the most part, we treat swapable == cachable here.
 	 */
+#ifdef DSA
+	assert(e->instances->count == 1);
+	storeReleaseRequest((InstanceEntry *) e->instances->items[0]);
+#else
 	storeReleaseRequest(e);
+#endif
     }
     stmemFreeDataUpto(&mem->data_hdr, new_mem_lo);
     mem->inmem_lo = new_mem_lo;
@@ -292,7 +297,12 @@
 	e->swap_filen = -1;
 	e->swap_dirn = -1;
 	e->swap_status = SWAPOUT_NONE;
+#ifdef DSA
+	assert(e->instances->count == 1);
+	storeReleaseRequest((InstanceEntry *) e->instances->items[0]);
+#else
 	storeReleaseRequest(e);
+#endif
     } else {
 	/* swapping complete */
 	debug(20, 3) ("storeSwapOutFileClosed: SwapOut complete: '%s' to %d, %08X\n",
Index: squid/src/structs.h
diff -u squid/src/structs.h:1.6.2.13 squid/src/structs.h:1.6.2.12
--- squid/src/structs.h:1.6.2.13	Mon Nov 11 01:10:27 2002
+++ squid/src/structs.h	Mon Nov 11 00:25:36 2002
@@ -792,7 +792,11 @@
 };
 
 struct _HttpStateData {
+#ifdef DSA
+    InstanceEntry * entry;
+#else    
     StoreEntry *entry;
+#endif    
     request_t *request;
     char *reply_hdr;
     size_t reply_hdr_size;
@@ -883,8 +887,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 +977,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 +1158,11 @@
 
 struct _ps_state {
     request_t *request;
+#ifdef DSA
+    InstanceEntry * entry;
+#else    
     StoreEntry *entry;
+#endif    
     int always_direct;
     int never_direct;
     int direct;
@@ -1314,14 +1332,29 @@
 #endif
 };
 
+#ifdef DSA
+struct _InstanceEntry {
+    hash_link hash;
+    time_t expires;
+    time_t lastmod;
+    time_t timestamp;
+    u_short flags;
+    StoreEntry * p; /* pointer to corresponding StoreEntry */
+};
+#endif
+
 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;
@@ -1332,6 +1365,11 @@
     ping_status_t ping_status:3;
     store_status_t store_status:3;
     swap_status_t swap_status:3;
+#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 {
@@ -1756,7 +1794,11 @@
 
 struct _FwdState {
     int client_fd;
+#ifdef DSA
+    InstanceEntry * entry;
+#else    
     StoreEntry *entry;
+#endif    
     request_t *request;
     FwdServer *servers;
     int server_fd;
@@ -1864,8 +1906,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 {
Index: squid/src/typedefs.h
diff -u squid/src/typedefs.h:1.3.4.5 squid/src/typedefs.h:1.3.4.4
--- squid/src/typedefs.h:1.3.4.5	Mon Nov 11 01:10:32 2002
+++ squid/src/typedefs.h	Mon Nov 11 00:25:36 2002
@@ -130,6 +130,9 @@
 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 _SwapDir SwapDir;
 typedef struct _request_flags request_flags;
Index: squid/src/urn.c
diff -u squid/src/urn.c:1.3.4.5 squid/src/urn.c:1.3.4.4
--- squid/src/urn.c:1.3.4.5	Mon Nov 11 01:10:33 2002
+++ squid/src/urn.c	Mon Nov 11 00:25:36 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);
+#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 {
+#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;
@@ -226,7 +270,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;
     }
     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);
@@ -293,7 +345,11 @@
     /* mb was absorbed in httpBodySet call, so we must not clean it */
     storeUnregister(urnState->sc, urlres_e, urnState);
     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.3 squid/src/wais.c:1.3.4.2
--- squid/src/wais.c:1.3.4.3	Mon Nov 11 01:10:33 2002
+++ squid/src/wais.c	Mon Nov 11 00:25:36 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;
+#ifdef DSA    
+    storeUnlockObject(waisState->entry->p);
+#else    
     storeUnlockObject(waisState->entry);
+#endif    
     requestUnlink(waisState->request);
     cbdataFree(waisState);
 }
@@ -67,7 +75,11 @@
 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->mem_obj->inmem_hi == 0) {
@@ -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;
@@ -131,11 +147,19 @@
 	} else {
 	    ErrorState *err;
 	    EBIT_CLR(entry->flags, ENTRY_CACHABLE);
+#ifdef DSA
+	    storeReleaseRequest(waisState->entry);
+#else
 	    storeReleaseRequest(entry);
+#endif
 	    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->mem_obj->inmem_hi == 0) {
@@ -143,11 +167,19 @@
 	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 +197,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 +216,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. */
@@ -221,7 +261,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,7 +277,11 @@
     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;
Index: squid/src/whois.c
diff -u squid/src/whois.c:1.3.4.3 squid/src/whois.c:1.3.4.2
--- squid/src/whois.c:1.3.4.3	Mon Nov 11 01:10:34 2002
+++ squid/src/whois.c	Mon Nov 11 00:25:36 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);
+#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,7 +96,11 @@
 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->mem_obj;
     int len;
@@ -128,6 +144,10 @@
 {
     WhoisState *p = data;
     debug(75, 3) ("whoisClose: FD %d\n", fd);
+#ifdef DSA    
+    storeUnlockObject(p->entry->p);
+#else    
     storeUnlockObject(p->entry);
+#endif    
     cbdataFree(p);
 }
