]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Copy data back into memory as it's being read from disk
authorHenrik Nordstrom <henrik@henriknordstrom.net>
Mon, 27 Jul 2009 11:34:04 +0000 (13:34 +0200)
committerHenrik Nordstrom <henrik@henriknordstrom.net>
Mon, 27 Jul 2009 11:34:04 +0000 (13:34 +0200)
src/StoreClient.h
src/store_client.cc

index e211cd042c0cc9e08cfba2009e4634e8e64d4eda..4d6429dfbb103e2f979c0df9e9f1910bb49d2962 100644 (file)
@@ -70,6 +70,7 @@ public:
     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;
 
index 4b24ae651f5c405d4904195fbcc5d8153a320a40..0595ac608071b359ad2f910e8c6bbb7c46b0ff3c 100644 (file)
@@ -472,24 +472,50 @@ store_client::fileRead()
 }
 
 static void
-storeClientReadBody(void *data, const char *buf, ssize_t len, StoreIOState::Pointer self)
+storeClientMemWriteComplete(void *data, StoreIOBuffer wroteBuffer)
 {
-    store_client *sc = (store_client *)data;
-    assert(sc->flags.disk_io_pending);
-    sc->flags.disk_io_pending = 0;
-    assert(sc->_callback.pending());
+       // 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");
-        }
+        } else {
+           parsed_header = 1;
+       }
     }
 
-    sc->callback(len);
+    const HttpReply *rep = entry->getReply();
+    if (len > 0 && rep && entry->mem_obj->inmem_lo == 0 && entry->objectLen() <= (int64_t)Config.Store.maxInMemObjSize) {
+       /* 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() + rep->hdr_sz;
+       if ((copyInto.offset == mem_offset) || (parsed_header && mem_offset == rep->hdr_sz)) {
+           StoreIOBuffer tmp = copyInto;
+           tmp.offset -= rep->hdr_sz;
+           entry->mem_obj->write(tmp, storeClientMemWriteComplete, this);
+       }
+    }
+
+    callback(len);
 }
 
 void
@@ -514,6 +540,13 @@ storeClientReadHeader(void *data, const char *buf, ssize_t len, StoreIOState::Po
     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 +622,8 @@ store_client::readHeader(char const *buf, ssize_t len)
         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!");
-            }
-        }
+       readBody(copyInto.data, copy_sz);
 
-        callback(copy_sz);
         return;
     }