]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Spread MemBuf.h among .h monsters.
authorrousskov <>
Thu, 26 Feb 1998 14:06:14 +0000 (14:06 +0000)
committerrousskov <>
Thu, 26 Feb 1998 14:06:14 +0000 (14:06 +0000)
src/MemBuf.cc
src/protos.h
src/structs.h
src/typedefs.h

index fe0f27aa2a650ec558fdbee11000945ebf6baa8c..d1c72e86f81328b1e86093b8f45d3b88944a1f1d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: MemBuf.cc,v 1.3 1998/02/21 18:46:34 rousskov Exp $
+ * $Id: MemBuf.cc,v 1.4 1998/02/26 07:06:14 rousskov Exp $
  *
  * DEBUG: section 59    auto-growing Memory Buffer with printf
  * AUTHOR: Alex Rousskov
  *  
  */
 
-/* see MemBuf.h for documentation */
-
 /*
  * To-Do: uses memory pools for .buf recycling @?@
  */
 
+/*
+    Rationale:
+    ----------
+
+    Here is how one would comm_write an object without MemBuffer:
+
+    {
+       -- allocate:
+       buf = malloc(big_enough);
+
+        -- "pack":
+       snprintf object(s) piece-by-piece constantly checking for overflows
+           and maintaining (buf+offset);
+       ...
+
+       -- write
+       comm_write(buf, free, ...);
+    }
+
+    The whole "packing" idea is quite messy: We are given a buffer of fixed
+    size and we have to check all the time that we still fit. Sounds logical.
+    However, what happens if we have more data? If we are lucky to be careful
+    to stop before we overrun any buffers, we still may have garbage (e.g.
+    half of ETag) in the buffer.
+
+    MemBuffer:
+    ----------
+
+    MemBuffer is a memory-resident buffer with printf()-like interface. It
+    hides all offest handling and overflow checking. Moreover, it has a
+    build-in control that no partial data has been written.
+
+    MemBuffer is designed to handle relatively small data. It starts with a
+    small buffer of configurable size to avoid allocating huge buffers all the
+    time.  MemBuffer doubles the buffer when needed. It assert()s that it will
+    not grow larger than a configurable limit. MemBuffer has virtually no
+    overhead (and can even reduce memory consumption) compared to old
+    "packing" approach.
+
+    MemBuffer eliminates both "packing" mess and truncated data:
+
+    {
+       -- setup
+       MemBuf buf;
+
+       -- required init with optional size tuning (see #defines for defaults)
+        memBufInit(&buf, initial-size, absolute-maximum);
+
+       -- "pack" (no need to handle offsets or check for overflows)
+       memBufPrintf(&buf, ...);
+       ...
+
+       -- write
+       comm_write(buf.buf, memBufFreeFunc(&buf), ...);
+
+       -- *iff* you did not give the buffer away, free it yourself
+       -- memBufFree(&buf);
+    }
+*/
+
 
 #include "squid.h"
 
+/* local constants */
+
+/* default values for buffer sizes, used by memBufDefInit */
+#define MEM_BUF_INIT_SIZE   (2*1024)
+#define MEM_BUF_MAX_SIZE   (32*1024)
+
+
 /* local routines */
 static void memBufGrow(MemBuf *mb, mb_size_t min_cap);
 
 
+/* init with defaults */
+void
+memBufDefInit(MemBuf *mb)
+{
+    memBufInit(mb, MEM_BUF_INIT_SIZE, MEM_BUF_MAX_SIZE);
+}
+
 
+/* init with specific sizes */
 void
 memBufInit(MemBuf *mb, mb_size_t szInit, mb_size_t szMax)
 {
@@ -57,6 +130,10 @@ memBufInit(MemBuf *mb, mb_size_t szInit, mb_size_t szMax)
     memBufGrow(mb, szInit);
 }
 
+/*
+ * cleans the mb; last function to call if you do not give .buf away with
+ * memBufFreeFunc
+ */
 void
 memBufClean(MemBuf *mb)
 {
@@ -69,6 +146,7 @@ memBufClean(MemBuf *mb)
    mb->size = mb->capacity = 0;
 }
 
+/* calls memcpy, appends exactly size bytes, extends buffer if needed */
 void
 memBufAppend(MemBuf *mb, const char *buf, mb_size_t sz)
 {
@@ -85,6 +163,7 @@ memBufAppend(MemBuf *mb, const char *buf, mb_size_t sz)
     }
 }
 
+/* calls snprintf, extends buffer if needed */
 #ifdef __STDC__
 void
 memBufPrintf(MemBuf *mb, const char *fmt, ...)
@@ -109,6 +188,7 @@ memBufPrintf(va_alist)
 }
 
 
+/* vprintf for other printf()'s to use */
 void
 memBufVPrintf(MemBuf *mb, const char *fmt, va_list vargs)
 {
@@ -131,6 +211,13 @@ memBufVPrintf(MemBuf *mb, const char *fmt, va_list vargs)
     mb->size += sz-1; /* note that we cut 0-terminator as store does @?@ @?@ */
 }
 
+/*
+ * returns free() function to be used.
+ * Important:
+ *   calling this function "freezes" mb,
+ *   do not _update_ mb after that in any way
+ *   (you still can read-access .buf and .size)
+ */
 FREE *
 memBufFreeFunc(MemBuf *mb)
 {
@@ -178,6 +265,10 @@ memBufGrow(MemBuf *mb, mb_size_t min_cap)
     mb->capacity = new_cap;
 }
 
+
+/* Reports */
+
+/* puts report on MemBuf _module_ usage into mb */
 void
 memBufReport(MemBuf *mb)
 {
index b13ac7158b966015195ca9a70f8b4e8089d26a76..df13188d784c0d486846d6ea6f1de33d0d9fea07 100644 (file)
@@ -306,6 +306,28 @@ extern ipcache_addrs *ipcacheCheckNumeric(const char *name);
 extern void ipcache_restart(void);
 extern int ipcacheUnregister(const char *name, void *data);
 
+/* MemBuf */
+/* init with specific sizes */
+extern void memBufInit(MemBuf *mb, mb_size_t szInit, mb_size_t szMax);
+/* init with defaults */
+extern void memBufDefInit(MemBuf *mb);
+/* cleans the mb; last function to call if you do not give .buf away */
+extern void memBufClean(MemBuf *mb);
+/* calls memcpy, appends exactly size bytes, extends buffer if needed */
+extern void memBufAppend(MemBuf *mb, const char *buf, mb_size_t size);
+/* calls snprintf, extends buffer if needed */
+#ifdef __STDC__
+extern void memBufPrintf(MemBuf *mb, const char *fmt, ...);
+#else
+extern void memBufPrintf();
+#endif
+/* vprintf for other printf()'s to use */
+extern void memBufVPrintf(MemBuf *mb, const char *fmt, va_list ap);
+/* returns free() function to be used, _freezes_ the object! */
+extern FREE *memBufFreeFunc(MemBuf *mb);
+/* puts report on MemBuf _module_ usage into mb */
+extern void memBufReport(MemBuf *mb);
+
 extern char *mime_get_header(const char *mime, const char *header);
 extern char *mime_headers_end(const char *mime);
 extern int mk_mime_hdr(char *result, const char *type, int size, time_t ttl, time_t lmt);
index 916f49831f3b1744214ce76968fb520fc12e5657..01203a455b220665d417f92856a356f1c79d6289 100644 (file)
@@ -444,9 +444,6 @@ struct _hash_table {
     hash_link *current_ptr;
 };
 
-#include "MemBuf.h"
-#include "Packer.h"
-
 /* server cache control */
 struct _HttpScc {
     int mask;
@@ -800,6 +797,19 @@ struct _iostats {
     } Http, Ftp, Gopher, Wais;
 };
 
+/* auto-growing memory-resident buffer with printf interface */
+struct _MemBuf {
+    /* public, read-only */
+    char *buf;
+    mb_size_t size;  /* used space, does not count 0-terminator */
+
+    /* private, stay away; use interface function instead */
+    mb_size_t max_capacity; /* when grows: assert(new_capacity <= max_capacity) */
+    mb_size_t capacity;     /* allocated space */
+    FREE *freefunc;  /* what to use to free the buffer, NULL after memBufFreeFunc() is called */
+};
+
+
 struct _mem_node {
     char *data;
     int len;
@@ -827,6 +837,8 @@ struct _store_client {
     struct _store_client *next;
 };
 
+#include "Packer.h"
+
 /* This structure can be freed while object is purged out from memory */
 struct _MemObject {
     method_t method;
@@ -842,11 +854,7 @@ struct _MemObject {
        int fd;
        void *ctrl;
     } swapout;
-#if 0
-    struct _http_reply *reply;
-#else
     HttpReply *reply;
-#endif
     request_t *request;
     struct timeval start_ping;
     IRCB *icp_reply_callback;
index 95eab48ad128b5234bb4e2fd867482b34501fba8..d8a8b94e9668a75c7295e96cf0be5f655e2c1dcb 100644 (file)
@@ -72,6 +72,7 @@ typedef struct _pingerReplyData pingerReplyData;
 typedef struct _icp_common_t icp_common_t;
 typedef struct _Meta_data Meta_data;
 typedef struct _iostats iostats;
+typedef struct _MemBuf MemBuf;
 typedef struct _mem_node mem_node;
 typedef struct _mem_hdr mem_hdr;
 typedef struct _store_client store_client;
@@ -129,3 +130,6 @@ typedef unsigned char cache_key;
 
 /* context-based debugging, the actual type is subject to change */
 typedef int Ctx;
+
+/* in case we want to change it later */
+typedef size_t mb_size_t;