# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: henrik@henriknordstrom.net-20090813102809-\
#   muiiiqhlgun9yi1w
# target_branch: http://www.squid-cache.org/bzr/squid3/trunk/
# testament_sha1: 47dcab3b4b0ded59b21ed8081584dd84100689c0
# timestamp: 2009-08-13 12:29:04 +0200
# base_revision_id: squid3@treenet.co.nz-20090807124451-\
#   6bgmp2f2t00gopvn
# 
# Begin patch
=== modified file 'src/Store.h'
--- src/Store.h	2009-07-27 21:50:59 +0000
+++ src/Store.h	2009-07-27 21:51:36 +0000
@@ -377,6 +377,9 @@
  */
 SQUIDCEXTERN void packerToStoreInit(Packer * p, StoreEntry * e);
 
+/// \ingroup StoreAPI
+SQUIDCEXTERN void storeGetMemSpace(int size);
+
 #ifdef _USE_INLINE_
 #include "Store.cci"
 #endif

=== modified file 'src/StoreClient.h'
--- src/StoreClient.h	2009-01-21 03:47:47 +0000
+++ src/StoreClient.h	2009-07-27 11:34:04 +0000
@@ -70,6 +70,7 @@
     void callback(ssize_t len, bool error = false);
     void doCopy (StoreEntry *e);
     void readHeader(const char *buf, ssize_t len);
+    void readBody(const char *buf, ssize_t len);
     void copy(StoreEntry *, StoreIOBuffer, STCB *, void *);
     void dumpStats(MemBuf * output, int clientNumber) const;
 

=== modified file 'src/store.cc'
--- src/store.cc	2009-02-12 10:46:08 +0000
+++ src/store.cc	2009-08-01 21:20:37 +0000
@@ -99,7 +99,6 @@
 /*
  * local function prototypes
  */
-static void storeGetMemSpace(int);
 static int getKeyCounter(void);
 static OBJH storeCheckCachableStats;
 static EVH storeLateRelease;
@@ -314,11 +313,18 @@
     if (store_status == STORE_OK) {
         /* the object has completed. */
 
-        if (mem_obj->inmem_lo == 0 && !isEmpty())
-            /* hot object */
-            return STORE_MEM_CLIENT;
-        else
-            return STORE_DISK_CLIENT;
+        if (mem_obj->inmem_lo == 0 && !isEmpty()) {
+            if (swap_status == SWAPOUT_DONE) {
+        	if (mem_obj->endOffset() == mem_obj->object_sz) {
+        	    /* hot object fully swapped in */
+        	    return STORE_MEM_CLIENT;
+        	}
+            } else {
+        	/* Memory-only, or currently being swapped out */
+        	return STORE_MEM_CLIENT;
+            }
+        }
+        return STORE_DISK_CLIENT;
     }
 
     /* here and past, entry is STORE_PENDING */
@@ -1112,8 +1118,10 @@
     unlock();       /* unlock */
 }
 
-/* Clear Memory storage to accommodate the given object len */
-static void
+/**
+ * Clear Memory storage to accommodate the given object len
+ */
+void
 storeGetMemSpace(int size)
 {
     PROF_start(storeGetMemSpace);

=== modified file 'src/store_client.cc'
--- src/store_client.cc	2009-07-26 21:21:51 +0000
+++ src/store_client.cc	2009-07-27 21:48:18 +0000
@@ -472,24 +472,52 @@
 }
 
 static void
-storeClientReadBody(void *data, const char *buf, ssize_t len, StoreIOState::Pointer self)
-{
-    store_client *sc = (store_client *)data;
-    assert(sc->flags.disk_io_pending);
-    sc->flags.disk_io_pending = 0;
-    assert(sc->_callback.pending());
+storeClientMemWriteComplete(void *data, StoreIOBuffer wroteBuffer)
+{
+        // Nothin to do here but callback is needed
+}
+
+void
+store_client::readBody(const char *buf, ssize_t len)
+{
+    int parsed_header = 0;
+
+    // Don't assert disk_io_pending here.. may be called by read_header
+    flags.disk_io_pending = 0;
+    assert(_callback.pending());
     debugs(90, 3, "storeClientReadBody: len " << len << "");
 
-    if (sc->copyInto.offset == 0 && len > 0 && sc->entry->getReply()->sline.status == 0) {
+    if (copyInto.offset == 0 && len > 0 && entry->getReply()->sline.status == 0) {
         /* Our structure ! */
-        HttpReply *rep = (HttpReply *) sc->entry->getReply(); // bypass const
+        HttpReply *rep = (HttpReply *) entry->getReply(); // bypass const
 
-        if (!rep->parseCharBuf(sc->copyInto.data, headersEnd(sc->copyInto.data, len))) {
+        if (!rep->parseCharBuf(copyInto.data, headersEnd(copyInto.data, len))) {
             debugs(90, 0, "Could not parse headers from on disk object");
-        }
-    }
-
-    sc->callback(len);
+        } else {
+            parsed_header = 1;
+        }
+    }
+
+    const HttpReply *rep = entry->getReply();
+    if (len > 0 && rep && entry->mem_obj->inmem_lo == 0 && entry->objectLen() <= (int64_t)Config.Store.maxInMemObjSize) {
+        storeGetMemSpace(len);
+        // The above may start to free our object so we need to check again
+        if (entry->mem_obj->inmem_lo == 0) {
+            /* Copy read data back into memory.
+             * but first we need to adjust offset.. some parts of the code
+             * counts offset including headers, some parts count offset as
+             * withing the body.. copyInto is including headers, but the mem
+             * cache expects offset without headers (using negative for headers)
+             * eventually not storing packed headers in memory at all.
+             */
+            int64_t mem_offset = entry->mem_obj->endOffset();
+            if ((copyInto.offset == mem_offset) || (parsed_header && mem_offset == rep->hdr_sz)) {
+                entry->mem_obj->write(StoreIOBuffer(len, copyInto.offset - rep->hdr_sz, copyInto.data), storeClientMemWriteComplete, this);
+            }
+        }
+    }
+
+    callback(len);
 }
 
 void
@@ -514,6 +542,13 @@
     sc->readHeader(buf, len);
 }
 
+static void
+storeClientReadBody(void *data, const char *buf, ssize_t len, StoreIOState::Pointer self)
+{
+    store_client *sc = (store_client *)data;
+    sc->readBody(buf, len);
+}
+
 void
 store_client::unpackHeader(char const *buf, ssize_t len)
 {
@@ -589,16 +624,8 @@
         debugs(90, 3, "storeClientReadHeader: copying " << copy_sz << " bytes of body");
         xmemmove(copyInto.data, copyInto.data + mem->swap_hdr_sz, copy_sz);
 
-        if (copyInto.offset == 0 && len > 0 && entry->getReply()->sline.status == 0) {
-            /* Our structure ! */
-            HttpReply *rep = (HttpReply *) entry->getReply(); // bypass const
-
-            if (!rep->parseCharBuf(copyInto.data, headersEnd(copyInto.data, copy_sz))) {
-                debugs(90, 0, "could not parse headers from on disk structure!");
-            }
-        }
-
-        callback(copy_sz);
+        readBody(copyInto.data, copy_sz);
+
         return;
     }
 

# Begin bundle
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

