# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: henrik@henriknordstrom.net-20100528215644-\
#   wyillk99j8xh6gsz
# target_branch: http://www.squid-cache.org/bzr/squid3/trunk/
# testament_sha1: 2620126df44429193c1456740f28dc63960ed438
# timestamp: 2010-05-28 23:58:31 +0200
# base_revision_id: henrik@henriknordstrom.net-20100528215627-\
#   agkq7l8rn7lertwg
# 
# Begin patch
=== modified file 'include/MemPool.h'
--- include/MemPool.h	2010-03-21 03:08:26 +0000
+++ include/MemPool.h	2010-05-28 21:53:06 +0000
@@ -1,5 +1,5 @@
-#ifndef _MEM_POOLS_H_
-#define _MEM_POOLS_H_
+#ifndef _MEM_POOL_H_
+#define _MEM_POOL_H_
 
 /**
  \defgroup MemPoolsAPI  Memory Management (Memory Pool Allocator)
@@ -63,7 +63,6 @@
 #define MEM_MAX_FREE  65535	/* ushort is max number of items per chunk */
 
 class MemImplementingAllocator;
-class MemChunk;
 class MemPoolStats;
 
 /// \ingroup MemPoolsAPI
@@ -130,13 +129,6 @@
     MemImplementingAllocator * create(const char *label, size_t obj_size);
 
     /**
-     \param label	Name for the pool. Displayed in stats.
-     \param obj_size	Size of elements in MemPool.
-     \param chunked	??
-     */
-    MemImplementingAllocator * create(const char *label, size_t obj_size, bool const chunked);
-
-    /**
      * Sets upper limit in bytes to amount of free ram kept in pools. This is
      * not strict upper limit, but a hint. When MemPools are over this limit,
      * totally free chunks are immediately considered for release. Otherwise
@@ -197,7 +189,7 @@
      \param stats	Object to be filled with statistical data about pool.
      \retval		Number of objects in use, ie. allocated.
      */
-    virtual int getStats(MemPoolStats * stats) = 0;
+    virtual int getStats(MemPoolStats * stats, int accumulate = 0) = 0;
 
     virtual MemPoolMeter const &getMeter() const = 0;
 
@@ -342,15 +334,13 @@
 
     virtual bool idleTrigger(int shift) const = 0;
     virtual void clean(time_t maxage) = 0;
-    /** Hint to the allocator - may be ignored */
-    virtual void setChunkSize(size_t chunksize) {}
     virtual size_t objectSize() const;
     virtual int getInUseCount() = 0;
 protected:
     virtual void *allocate() = 0;
     virtual void deallocate(void *) = 0;
-private:
     MemPoolMeter meter;
+    int memPID;
 public:
     MemImplementingAllocator *next;
 public:
@@ -360,93 +350,6 @@
 };
 
 /// \ingroup MemPoolsAPI
-class MemPool : public MemImplementingAllocator
-{
-public:
-    friend class MemChunk;
-    MemPool(const char *label, size_t obj_size);
-    ~MemPool();
-    void convertFreeCacheToChunkFreeCache();
-    virtual void clean(time_t maxage);
-
-    /**
-     \param stats	Object to be filled with statistical data about pool.
-     \retval		Number of objects in use, ie. allocated.
-     */
-    virtual int getStats(MemPoolStats * stats);
-
-    void createChunk();
-    void *get();
-    void push(void *obj);
-    virtual int getInUseCount();
-protected:
-    virtual void *allocate();
-    virtual void deallocate(void *);
-public:
-    /**
-     * Allows you tune chunk size of pooling. Objects are allocated in chunks
-     * instead of individually. This conserves memory, reduces fragmentation.
-     * Because of that memory can be freed also only in chunks. Therefore
-     * there is tradeoff between memory conservation due to chunking and free
-     * memory fragmentation.
-     *
-     \note  As a general guideline, increase chunk size only for pools that keep
-     *      very many items for relatively long time.
-     */
-    virtual void setChunkSize(size_t chunksize);
-
-    virtual bool idleTrigger(int shift) const;
-
-    size_t chunk_size;
-    int chunk_capacity;
-    int memPID;
-    int chunkCount;
-    size_t inuse;
-    size_t idle;
-    void *freeCache;
-    MemChunk *nextFreeChunk;
-    MemChunk *Chunks;
-    Splay<MemChunk *> allChunks;
-};
-
-/// \ingroup MemPoolsAPI
-class MemMalloc : public MemImplementingAllocator
-{
-public:
-    MemMalloc(char const *label, size_t aSize);
-    virtual bool idleTrigger(int shift) const;
-    virtual void clean(time_t maxage);
-
-    /**
-     \param stats	Object to be filled with statistical data about pool.
-     \retval		Number of objects in use, ie. allocated.
-     */
-    virtual int getStats(MemPoolStats * stats);
-
-    virtual int getInUseCount();
-protected:
-    virtual void *allocate();
-    virtual void deallocate(void *);
-private:
-    int inuse;
-};
-
-/// \ingroup MemPoolsAPI
-class MemChunk
-{
-public:
-    MemChunk(MemPool *pool);
-    ~MemChunk();
-    void *freeList;
-    void *objCache;
-    int inuse_count;
-    MemChunk *nextFreeChunk;
-    MemChunk *next;
-    time_t lastref;
-    MemPool *pool;
-};
-
-/// \ingroup MemPoolsAPI
 class MemPoolStats
 {
 public:
@@ -536,4 +439,4 @@
 }
 
 
-#endif /* _MEM_POOLS_H_ */
+#endif /* _MEM_POOL_H_ */

=== added file 'include/MemPoolChunked.h'
--- include/MemPoolChunked.h	1970-01-01 00:00:00 +0000
+++ include/MemPoolChunked.h	2010-05-28 21:53:06 +0000
@@ -0,0 +1,82 @@
+#ifndef _MEM_POOL_CHUNKED_H_
+#define _MEM_POOL_CHUNKED_H_
+
+#include "MemPool.h"
+
+/// \ingroup MemPoolsAPI
+#define MEM_PAGE_SIZE 4096
+/// \ingroup MemPoolsAPI
+#define MEM_CHUNK_SIZE 4096 * 4
+/// \ingroup MemPoolsAPI
+#define MEM_CHUNK_MAX_SIZE  256 * 1024	/* 2MB */
+/// \ingroup MemPoolsAPI
+#define MEM_MIN_FREE  32
+/// \ingroup MemPoolsAPI
+#define MEM_MAX_FREE  65535	/* ushort is max number of items per chunk */
+
+class MemChunk;
+
+/// \ingroup MemPoolsAPI
+class MemPoolChunked : public MemImplementingAllocator
+{
+public:
+    friend class MemChunk;
+    MemPoolChunked(const char *label, size_t obj_size);
+    ~MemPoolChunked();
+    void convertFreeCacheToChunkFreeCache();
+    virtual void clean(time_t maxage);
+
+    /**
+     \param stats	Object to be filled with statistical data about pool.
+     \retval		Number of objects in use, ie. allocated.
+     */
+    virtual int getStats(MemPoolStats * stats, int accumulate);
+
+    void createChunk();
+    void *get();
+    void push(void *obj);
+    virtual int getInUseCount();
+protected:
+    virtual void *allocate();
+    virtual void deallocate(void *);
+public:
+    /**
+     * Allows you tune chunk size of pooling. Objects are allocated in chunks
+     * instead of individually. This conserves memory, reduces fragmentation.
+     * Because of that memory can be freed also only in chunks. Therefore
+     * there is tradeoff between memory conservation due to chunking and free
+     * memory fragmentation.
+     *
+     \note  As a general guideline, increase chunk size only for pools that keep
+     *      very many items for relatively long time.
+     */
+    virtual void setChunkSize(size_t chunksize);
+
+    virtual bool idleTrigger(int shift) const;
+
+    size_t chunk_size;
+    int chunk_capacity;
+    int memPID;
+    int chunkCount;
+    void *freeCache;
+    MemChunk *nextFreeChunk;
+    MemChunk *Chunks;
+    Splay<MemChunk *> allChunks;
+};
+
+/// \ingroup MemPoolsAPI
+class MemChunk
+{
+public:
+    MemChunk(MemPoolChunked *pool);
+    ~MemChunk();
+    void *freeList;
+    void *objCache;
+    int inuse_count;
+    MemChunk *nextFreeChunk;
+    MemChunk *next;
+    time_t lastref;
+    MemPoolChunked *pool;
+};
+
+#endif /* _MEM_POOL_CHUNKED_H_ */

=== added file 'include/MemPoolMalloc.h'
--- include/MemPoolMalloc.h	1970-01-01 00:00:00 +0000
+++ include/MemPoolMalloc.h	2010-05-28 21:53:06 +0000
@@ -0,0 +1,47 @@
+#ifndef _MEM_POOL_MALLOC_H_
+#define _MEM_POOL_MALLOC_H_
+
+/**
+ \defgroup MemPoolsAPI  Memory Management (Memory Pool Allocator)
+ \ingroup Components
+ *
+ *\par
+ *  MemPools are a pooled memory allocator running on top of malloc(). It's
+ *  purpose is to reduce memory fragmentation and provide detailed statistics
+ *  on memory consumption.
+ *
+ \par
+ *  Preferably all memory allocations in Squid should be done using MemPools
+ *  or one of the types built on top of it (i.e. cbdata).
+ *
+ \note Usually it is better to use cbdata types as these gives you additional
+ *     safeguards in references and typechecking. However, for high usage pools where
+ *     the cbdata functionality of cbdata is not required directly using a MemPool
+ *     might be the way to go.
+ */
+
+#include "MemPool.h"
+
+/// \ingroup MemPoolsAPI
+class MemPoolMalloc : public MemImplementingAllocator
+{
+public:
+    MemPoolMalloc(char const *label, size_t aSize);
+    virtual bool idleTrigger(int shift) const;
+    virtual void clean(time_t maxage);
+
+    /**
+     \param stats	Object to be filled with statistical data about pool.
+     \retval		Number of objects in use, ie. allocated.
+     */
+    virtual int getStats(MemPoolStats * stats, int accumulate);
+
+    virtual int getInUseCount();
+protected:
+    virtual void *allocate();
+    virtual void deallocate(void *);
+private:
+};
+
+
+#endif /* _MEM_POOL_MALLOC_H_ */

=== modified file 'lib/Makefile.am'
--- lib/Makefile.am	2009-12-19 11:56:02 +0000
+++ lib/Makefile.am	2010-05-28 21:53:06 +0000
@@ -49,6 +49,8 @@
 	win32lib.c
 libmiscutil_a_SOURCES = \
 	MemPool.cc \
+	MemPoolChunked.cc \
+	MemPoolMalloc.cc \
 	base64.c \
 	charset.c \
 	getfullhostname.c \

=== modified file 'lib/MemPool.cc'
--- lib/MemPool.cc	2010-04-14 21:04:28 +0000
+++ lib/MemPool.cc	2010-05-28 21:53:06 +0000
@@ -87,6 +87,8 @@
 #endif
 
 #include "MemPool.h"
+#include "MemPoolChunked.h"
+#include "MemPoolMalloc.h"
 
 #define FLUSH_LIMIT 1000	/* Flush memPool counters to memMeters after flush limit calls */
 #define MEM_MAX_MMAP_CHUNKS 2048
@@ -107,10 +109,6 @@
 
 static int Pool_id_counter = 0;
 
-/* local prototypes */
-static int memCompChunks(MemChunk * const &, MemChunk * const &);
-static int memCompObjChunks(void * const &, MemChunk * const &);
-
 MemPools &
 MemPools::GetInstance()
 {
@@ -165,195 +163,6 @@
     return mem_idle_limit;
 }
 
-/* Compare chunks */
-static int
-memCompChunks(MemChunk * const &chunkA, MemChunk * const &chunkB)
-{
-    if (chunkA->objCache > chunkB->objCache)
-        return 1;
-    else if (chunkA->objCache < chunkB->objCache)
-        return -1;
-    else
-        return 0;
-}
-
-/* Compare object to chunk */
-static int
-memCompObjChunks(void *const &obj, MemChunk * const &chunk)
-{
-    /* object is lower in memory than the chunks arena */
-    if (obj < chunk->objCache)
-        return -1;
-    /* object is within the pool */
-    if (obj < (void *) ((char *) chunk->objCache + chunk->pool->chunk_size))
-        return 0;
-    /* object is above the pool */
-    return 1;
-}
-
-MemChunk::MemChunk(MemPool *aPool)
-{
-    /* should have a pool for this too -
-     * note that this requres:
-     * allocate one chunk for the pool of chunks's first chunk
-     * allocate a chunk from that pool
-     * move the contents of one chunk into the other
-     * free the first chunk.
-     */
-    inuse_count = 0;
-    next = NULL;
-    pool = aPool;
-
-    objCache = xcalloc(1, pool->chunk_size);
-    freeList = objCache;
-    void **Free = (void **)freeList;
-
-    for (int i = 1; i < pool->chunk_capacity; i++) {
-        *Free = (void *) ((char *) Free + pool->obj_size);
-        void **nextFree = (void **)*Free;
-        (void) VALGRIND_MAKE_MEM_NOACCESS(Free, pool->obj_size);
-        Free = nextFree;
-    }
-    nextFreeChunk = pool->nextFreeChunk;
-    pool->nextFreeChunk = this;
-
-    memMeterAdd(pool->getMeter().alloc, pool->chunk_capacity);
-    memMeterAdd(pool->getMeter().idle, pool->chunk_capacity);
-    pool->idle += pool->chunk_capacity;
-    pool->chunkCount++;
-    lastref = squid_curtime;
-    pool->allChunks.insert(this, memCompChunks);
-}
-
-MemPool::MemPool(const char *aLabel, size_t aSize) : MemImplementingAllocator(aLabel, aSize)
-{
-    chunk_size = 0;
-    chunk_capacity = 0;
-    memPID = 0;
-    chunkCount = 0;
-    inuse = 0;
-    idle = 0;
-    freeCache = 0;
-    nextFreeChunk = 0;
-    Chunks = 0;
-    next = 0;
-    MemImplementingAllocator *last_pool;
-
-    assert(aLabel != NULL && aSize);
-
-    setChunkSize(MEM_CHUNK_SIZE);
-
-    /* Append as Last */
-    for (last_pool = MemPools::GetInstance().pools; last_pool && last_pool->next;)
-        last_pool = last_pool->next;
-    if (last_pool)
-        last_pool->next = this;
-    else
-        MemPools::GetInstance().pools = this;
-
-    memPID = ++Pool_id_counter;
-}
-
-MemChunk::~MemChunk()
-{
-    memMeterDel(pool->getMeter().alloc, pool->chunk_capacity);
-    memMeterDel(pool->getMeter().idle, pool->chunk_capacity);
-    pool->idle -= pool->chunk_capacity;
-    pool->chunkCount--;
-    pool->allChunks.remove(this, memCompChunks);
-    xfree(objCache);
-}
-
-void
-MemPool::push(void *obj)
-{
-    void **Free;
-    /* XXX We should figure out a sane way of avoiding having to clear
-     * all buffers. For example data buffers such as used by MemBuf do
-     * not really need to be cleared.. There was a condition based on
-     * the object size here, but such condition is not safe.
-     */
-    if (doZeroOnPush)
-        memset(obj, 0, obj_size);
-    Free = (void **)obj;
-    *Free = freeCache;
-    freeCache = obj;
-    (void) VALGRIND_MAKE_MEM_NOACCESS(obj, obj_size);
-}
-
-/*
- * Find a chunk with a free item.
- * Create new chunk on demand if no chunk with frees found.
- * Insert new chunk in front of lowest ram chunk, making it preferred in future,
- * and resulting slow compaction towards lowest ram area.
- */
-void *
-MemPool::get()
-{
-    void **Free;
-
-    /* first, try cache */
-    if (freeCache) {
-        Free = (void **)freeCache;
-        (void) VALGRIND_MAKE_MEM_DEFINED(Free, obj_size);
-        freeCache = *Free;
-        *Free = NULL;
-        return Free;
-    }
-    /* then try perchunk freelist chain */
-    if (nextFreeChunk == NULL) {
-        /* no chunk with frees, so create new one */
-        createChunk();
-    }
-    /* now we have some in perchunk freelist chain */
-    MemChunk *chunk = nextFreeChunk;
-
-    Free = (void **)chunk->freeList;
-    chunk->freeList = *Free;
-    *Free = NULL;
-    chunk->inuse_count++;
-    chunk->lastref = squid_curtime;
-
-    if (chunk->freeList == NULL) {
-        /* last free in this chunk, so remove us from perchunk freelist chain */
-        nextFreeChunk = chunk->nextFreeChunk;
-    }
-    (void) VALGRIND_MAKE_MEM_DEFINED(Free, obj_size);
-    return Free;
-}
-
-/* just create a new chunk and place it into a good spot in the chunk chain */
-void
-MemPool::createChunk()
-{
-    MemChunk *chunk, *newChunk;
-
-    newChunk = new MemChunk(this);
-
-    chunk = Chunks;
-    if (chunk == NULL) {	/* first chunk in pool */
-        Chunks = newChunk;
-        return;
-    }
-    if (newChunk->objCache < chunk->objCache) {
-        /* we are lowest ram chunk, insert as first chunk */
-        newChunk->next = chunk;
-        Chunks = newChunk;
-        return;
-    }
-    while (chunk->next) {
-        if (newChunk->objCache < chunk->next->objCache) {
-            /* new chunk is in lower ram, insert here */
-            newChunk->next = chunk->next;
-            chunk->next = newChunk;
-            return;
-        }
-        chunk = chunk->next;
-    }
-    /* we are the worst chunk in chain, add as last */
-    chunk->next = newChunk;
-}
-
 /* Change the default calue of defaultIsChunked to override
  * all pools - including those used before main() starts where
  * MemPools::GetInstance().setDefaultPoolChunking() can be called.
@@ -369,49 +178,14 @@
 #endif
 }
 
-void
-MemPool::setChunkSize(size_t chunksize)
-{
-    int cap;
-    size_t csize = chunksize;
-
-    if (Chunks)		/* unsafe to tamper */
-        return;
-
-    csize = ((csize + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE) * MEM_PAGE_SIZE;	/* round up to page size */
-    cap = csize / obj_size;
-
-    if (cap < MEM_MIN_FREE)
-        cap = MEM_MIN_FREE;
-    if (cap * obj_size > MEM_CHUNK_MAX_SIZE)
-        cap = MEM_CHUNK_MAX_SIZE / obj_size;
-    if (cap > MEM_MAX_FREE)
-        cap = MEM_MAX_FREE;
-    if (cap < 1)
-        cap = 1;
-
-    csize = cap * obj_size;
-    csize = ((csize + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE) * MEM_PAGE_SIZE;	/* round up to page size */
-    cap = csize / obj_size;
-
-    chunk_capacity = cap;
-    chunk_size = csize;
-}
-
 MemImplementingAllocator *
 MemPools::create(const char *label, size_t obj_size)
 {
-    return create (label, obj_size, defaultIsChunked);
-}
-
-MemImplementingAllocator *
-MemPools::create(const char *label, size_t obj_size, bool const chunked)
-{
     ++poolCount;
-    if (chunked)
-        return new MemPool (label, obj_size);
+    if (defaultIsChunked)
+        return new MemPoolChunked (label, obj_size);
     else
-        return new MemMalloc (label, obj_size);
+        return new MemPoolMalloc (label, obj_size);
 }
 
 void
@@ -420,40 +194,6 @@
     defaultIsChunked = aBool;
 }
 
-/*
- * warning: we do not clean this entry from Pools assuming destruction
- * is used at the end of the program only
- */
-MemPool::~MemPool()
-{
-    MemChunk *chunk, *fchunk;
-    MemImplementingAllocator *find_pool, *prev_pool;
-
-    flushMetersFull();
-    clean(0);
-    assert(inuse == 0 && "While trying to destroy pool");
-
-    chunk = Chunks;
-    while ( (fchunk = chunk) != NULL) {
-        chunk = chunk->next;
-        delete fchunk;
-    }
-    /* TODO we should be doing something about the original Chunks pointer here. */
-
-    assert(MemPools::GetInstance().pools != NULL && "Called MemPool::~MemPool, but no pool exists!");
-
-    /* Pool clean, remove it from List and free */
-    for (find_pool = MemPools::GetInstance().pools, prev_pool = NULL; (find_pool && this != find_pool); find_pool = find_pool->next)
-        prev_pool = find_pool;
-    assert(find_pool != NULL && "pool to destroy not found");
-
-    if (prev_pool)
-        prev_pool->next = next;
-    else
-        MemPools::GetInstance().pools = next;
-    --MemPools::GetInstance().poolCount;
-}
-
 char const *
 MemAllocator::objectType() const
 {
@@ -473,16 +213,12 @@
 
     calls = free_calls;
     if (calls) {
-        getMeter().gb_freed.count += calls;
-        memMeterDel(getMeter().inuse, calls);
-        memMeterAdd(getMeter().idle, calls);
+        meter.gb_freed.count += calls;
         free_calls = 0;
     }
     calls = alloc_calls;
     if (calls) {
         meter.gb_saved.count += calls;
-        memMeterAdd(meter.inuse, calls);
-        memMeterDel(meter.idle, calls);
         alloc_calls = 0;
     }
 }
@@ -532,20 +268,6 @@
 }
 
 void *
-MemMalloc::allocate()
-{
-    inuse++;
-    return xcalloc(1, obj_size);
-}
-
-void
-MemMalloc::deallocate(void *obj)
-{
-    inuse--;
-    xfree(obj);
-}
-
-void *
 MemImplementingAllocator::alloc()
 {
     if (++alloc_calls == FLUSH_LIMIT)
@@ -563,123 +285,6 @@
     ++free_calls;
 }
 
-int
-MemPool::getInUseCount()
-{
-    return inuse;
-}
-
-void *
-MemPool::allocate()
-{
-    void *p = get();
-    assert(idle);
-    --idle;
-    ++inuse;
-    return p;
-}
-
-void
-MemPool::deallocate(void *obj)
-{
-    push(obj);
-    assert(inuse);
-    --inuse;
-    ++idle;
-}
-
-void
-MemPool::convertFreeCacheToChunkFreeCache()
-{
-    void *Free;
-    /*
-     * OK, so we have to go through all the global freeCache and find the Chunk
-     * any given Free belongs to, and stuff it into that Chunk's freelist
-     */
-
-    while ((Free = freeCache) != NULL) {
-        MemChunk *chunk = NULL;
-        chunk = const_cast<MemChunk *>(*allChunks.find(Free, memCompObjChunks));
-        assert(splayLastResult == 0);
-        assert(chunk->inuse_count > 0);
-        chunk->inuse_count--;
-        (void) VALGRIND_MAKE_MEM_DEFINED(Free, sizeof(void *));
-        freeCache = *(void **)Free;	/* remove from global cache */
-        *(void **)Free = chunk->freeList;	/* stuff into chunks freelist */
-        (void) VALGRIND_MAKE_MEM_NOACCESS(Free, sizeof(void *));
-        chunk->freeList = Free;
-        chunk->lastref = squid_curtime;
-    }
-
-}
-
-/* removes empty Chunks from pool */
-void
-MemPool::clean(time_t maxage)
-{
-    MemChunk *chunk, *freechunk, *listTail;
-    time_t age;
-
-    if (!this)
-        return;
-    if (!Chunks)
-        return;
-
-    flushMetersFull();
-    convertFreeCacheToChunkFreeCache();
-    /* Now we have all chunks in this pool cleared up, all free items returned to their home */
-    /* We start now checking all chunks to see if we can release any */
-    /* We start from Chunks->next, so first chunk is not released */
-    /* Recreate nextFreeChunk list from scratch */
-
-    chunk = Chunks;
-    while ((freechunk = chunk->next) != NULL) {
-        age = squid_curtime - freechunk->lastref;
-        freechunk->nextFreeChunk = NULL;
-        if (freechunk->inuse_count == 0)
-            if (age >= maxage) {
-                chunk->next = freechunk->next;
-                delete freechunk;
-                freechunk = NULL;
-            }
-        if (chunk->next == NULL)
-            break;
-        chunk = chunk->next;
-    }
-
-    /* Recreate nextFreeChunk list from scratch */
-    /* Populate nextFreeChunk list in order of "most filled chunk first" */
-    /* in case of equal fill, put chunk in lower ram first */
-    /* First (create time) chunk is always on top, no matter how full */
-
-    chunk = Chunks;
-    nextFreeChunk = chunk;
-    chunk->nextFreeChunk = NULL;
-
-    while (chunk->next) {
-        chunk->next->nextFreeChunk = NULL;
-        if (chunk->next->inuse_count < chunk_capacity) {
-            listTail = nextFreeChunk;
-            while (listTail->nextFreeChunk) {
-                if (chunk->next->inuse_count > listTail->nextFreeChunk->inuse_count)
-                    break;
-                if ((chunk->next->inuse_count == listTail->nextFreeChunk->inuse_count) &&
-                        (chunk->next->objCache < listTail->nextFreeChunk->objCache))
-                    break;
-                listTail = listTail->nextFreeChunk;
-            }
-            chunk->next->nextFreeChunk = listTail->nextFreeChunk;
-            listTail->nextFreeChunk = chunk->next;
-        }
-        chunk = chunk->next;
-    }
-    /* We started from 2nd chunk. If first chunk is full, remove it */
-    if (nextFreeChunk->inuse_count == chunk_capacity)
-        nextFreeChunk = nextFreeChunk->nextFreeChunk;
-
-    return;
-}
-
 /*
  * Returns all cached frees to their home chunks
  * If chunks unreferenced age is over, destroys Idle chunk
@@ -707,96 +312,10 @@
     memPoolIterateDone(&iter);
 }
 
-bool
-MemPool::idleTrigger(int shift) const
-{
-    return getMeter().idle.level > (chunk_capacity << shift);
-}
-
 /* Persistent Pool stats. for GlobalStats accumulation */
 static MemPoolStats pp_stats;
 
 /*
- * Update MemPoolStats struct for single pool
- */
-int
-MemPool::getStats(MemPoolStats * stats)
-{
-    MemChunk *chunk;
-    int chunks_free = 0;
-    int chunks_partial = 0;
-
-    if (stats != &pp_stats)	/* need skip memset for GlobalStats accumulation */
-        /* XXX Fixme */
-        memset(stats, 0, sizeof(MemPoolStats));
-
-    clean((time_t) 555555);	/* don't want to get chunks released before reporting */
-
-    stats->pool = this;
-    stats->label = objectType();
-    stats->meter = &getMeter();
-    stats->obj_size = obj_size;
-    stats->chunk_capacity = chunk_capacity;
-
-    /* gather stats for each Chunk */
-    chunk = Chunks;
-    while (chunk) {
-        if (chunk->inuse_count == 0)
-            chunks_free++;
-        else if (chunk->inuse_count < chunk_capacity)
-            chunks_partial++;
-        chunk = chunk->next;
-    }
-
-    stats->chunks_alloc += chunkCount;
-    stats->chunks_inuse += chunkCount - chunks_free;
-    stats->chunks_partial += chunks_partial;
-    stats->chunks_free += chunks_free;
-
-    stats->items_alloc += getMeter().alloc.level;
-    stats->items_inuse += getMeter().inuse.level;
-    stats->items_idle += getMeter().idle.level;
-
-    stats->overhead += sizeof(MemPool) + chunkCount * sizeof(MemChunk) + strlen(objectType()) + 1;
-
-    return getMeter().inuse.level;
-}
-
-/* TODO extract common logic to MemAllocate */
-int
-MemMalloc::getStats(MemPoolStats * stats)
-{
-    if (stats != &pp_stats)	/* need skip memset for GlobalStats accumulation */
-        /* XXX Fixme */
-        memset(stats, 0, sizeof(MemPoolStats));
-
-    stats->pool = this;
-    stats->label = objectType();
-    stats->meter = &getMeter();
-    stats->obj_size = obj_size;
-    stats->chunk_capacity = 0;
-
-    stats->chunks_alloc += 0;
-    stats->chunks_inuse += 0;
-    stats->chunks_partial += 0;
-    stats->chunks_free += 0;
-
-    stats->items_alloc += getMeter().alloc.level;
-    stats->items_inuse += getMeter().inuse.level;
-    stats->items_idle += getMeter().idle.level;
-
-    stats->overhead += sizeof(MemMalloc) + strlen(objectType()) + 1;
-
-    return getMeter().inuse.level;
-}
-
-int
-MemMalloc::getInUseCount()
-{
-    return inuse;
-}
-
-/*
  * Totals statistics is returned
  */
 int
@@ -814,7 +333,7 @@
     /* gather all stats for Totals */
     iter = memPoolIterate();
     while ((pool = memPoolIterateNext(iter))) {
-        if (pool->getStats(&pp_stats) > 0)
+        if (pool->getStats(&pp_stats, 1) > 0)
             pools_inuse++;
     }
     memPoolIterateDone(&iter);
@@ -833,7 +352,7 @@
     stats->tot_items_inuse = pp_stats.items_inuse;
     stats->tot_items_idle = pp_stats.items_idle;
 
-    stats->tot_overhead += pp_stats.overhead + MemPools::GetInstance().poolCount * sizeof(MemPool *);
+    stats->tot_overhead += pp_stats.overhead + MemPools::GetInstance().poolCount * sizeof(MemAllocator *);
     stats->mem_idle_limit = MemPools::GetInstance().mem_idle_limit;
 
     return pools_inuse;
@@ -848,19 +367,6 @@
     return ((s + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*);
 }
 
-MemMalloc::MemMalloc(char const *aLabel, size_t aSize) : MemImplementingAllocator(aLabel, aSize) { inuse = 0; }
-
-bool
-MemMalloc::idleTrigger(int shift) const
-{
-    return false;
-}
-
-void
-MemMalloc::clean(time_t maxage)
-{
-}
-
 int
 memPoolInUseCount(MemAllocator * pool)
 {
@@ -937,6 +443,7 @@
         free_calls(0),
         obj_size(RoundedSize(aSize))
 {
+	memPID = ++Pool_id_counter;
 }
 
 void

=== added file 'lib/MemPoolChunked.cc'
--- lib/MemPoolChunked.cc	1970-01-01 00:00:00 +0000
+++ lib/MemPoolChunked.cc	2010-05-28 21:53:06 +0000
@@ -0,0 +1,519 @@
+
+/*
+ * $Id$
+ *
+ * DEBUG: section 63    Low Level Memory Pool Management
+ * AUTHOR: Alex Rousskov, Andres Kroonmaa, Robert Collins
+ *
+ * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from the
+ *  Internet community.  Development is led by Duane Wessels of the
+ *  National Laboratory for Applied Network Research and funded by the
+ *  National Science Foundation.  Squid is Copyrighted (C) 1998 by
+ *  the Regents of the University of California.  Please see the
+ *  COPYRIGHT file for full details.  Squid incorporates software
+ *  developed and/or copyrighted by other sources.  Please see the
+ *  CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+/*
+ * Old way:
+ *   xmalloc each item separately, upon free stack into idle pool array.
+ *   each item is individually malloc()ed from system, imposing libmalloc
+ *   overhead, and additionally we add our overhead of pointer size per item
+ *   as we keep a list of pointer to free items.
+ *
+ * Chunking:
+ *   xmalloc Chunk that fits at least MEM_MIN_FREE (32) items in an array, but
+ *   limit Chunk size to MEM_CHUNK_MAX_SIZE (256K). Chunk size is rounded up to
+ *   MEM_PAGE_SIZE (4K), trying to have chunks in multiples of VM_PAGE size.
+ *   Minimum Chunk size is MEM_CHUNK_SIZE (16K).
+ *   A number of items fits into a single chunk, depending on item size.
+ *   Maximum number of items per chunk is limited to MEM_MAX_FREE (65535).
+ *
+ *   We populate Chunk with a linkedlist, each node at first word of item,
+ *   and pointing at next free item. Chunk->FreeList is pointing at first
+ *   free node. Thus we stuff free housekeeping into the Chunk itself, and
+ *   omit pointer overhead per item.
+ *
+ *   Chunks are created on demand, and new chunks are inserted into linklist
+ *   of chunks so that Chunks with smaller pointer value are placed closer
+ *   to the linklist head. Head is a hotspot, servicing most of requests, so
+ *   slow sorting occurs and Chunks in highest memory tend to become idle
+ *   and freeable.
+ *
+ *   event is registered that runs every 15 secs and checks reference time
+ *   of each idle chunk. If a chunk is not referenced for 15 secs, it is
+ *   released.
+ *
+ *   [If mem_idle_limit is exceeded with pools, every chunk that becomes
+ *   idle is immediately considered for release, unless this is the only
+ *   chunk with free items in it.] (not implemented)
+ *
+ *   In cachemgr output, there are new columns for chunking. Special item,
+ *   Frag, is shown to estimate approximately fragmentation of chunked
+ *   pools. Fragmentation is calculated by taking amount of items in use,
+ *   calculating needed amount of chunks to fit all, and then comparing to
+ *   actual amount of chunks in use. Frag number, in percent, is showing
+ *   how many percent of chunks are in use excessively. 100% meaning that
+ *   twice the needed amount of chunks are in use.
+ *   "part" item shows number of chunks partially filled. This shows how
+ *   badly fragmentation is spread across all chunks.
+ *
+ *   Andres Kroonmaa.
+ *   Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
+ */
+
+#include "config.h"
+#if HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#include "MemPoolChunked.h"
+
+#define FLUSH_LIMIT 1000	/* Flush memPool counters to memMeters after flush limit calls */
+#define MEM_MAX_MMAP_CHUNKS 2048
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+/*
+ * XXX This is a boundary violation between lib and src.. would be good
+ * if it could be solved otherwise, but left for now.
+ */
+extern time_t squid_curtime;
+
+/* local prototypes */
+static int memCompChunks(MemChunk * const &, MemChunk * const &);
+static int memCompObjChunks(void * const &, MemChunk * const &);
+
+/* Compare chunks */
+static int
+memCompChunks(MemChunk * const &chunkA, MemChunk * const &chunkB)
+{
+    if (chunkA->objCache > chunkB->objCache)
+        return 1;
+    else if (chunkA->objCache < chunkB->objCache)
+        return -1;
+    else
+        return 0;
+}
+
+/* Compare object to chunk */
+static int
+memCompObjChunks(void *const &obj, MemChunk * const &chunk)
+{
+    /* object is lower in memory than the chunks arena */
+    if (obj < chunk->objCache)
+        return -1;
+    /* object is within the pool */
+    if (obj < (void *) ((char *) chunk->objCache + chunk->pool->chunk_size))
+        return 0;
+    /* object is above the pool */
+    return 1;
+}
+
+MemChunk::MemChunk(MemPoolChunked *aPool)
+{
+    /* should have a pool for this too -
+     * note that this requres:
+     * allocate one chunk for the pool of chunks's first chunk
+     * allocate a chunk from that pool
+     * move the contents of one chunk into the other
+     * free the first chunk.
+     */
+    inuse_count = 0;
+    next = NULL;
+    pool = aPool;
+
+    objCache = xcalloc(1, pool->chunk_size);
+    freeList = objCache;
+    void **Free = (void **)freeList;
+
+    for (int i = 1; i < pool->chunk_capacity; i++) {
+        *Free = (void *) ((char *) Free + pool->obj_size);
+        void **nextFree = (void **)*Free;
+        (void) VALGRIND_MAKE_MEM_NOACCESS(Free, pool->obj_size);
+        Free = nextFree;
+    }
+    nextFreeChunk = pool->nextFreeChunk;
+    pool->nextFreeChunk = this;
+
+    memMeterAdd(pool->getMeter().alloc, pool->chunk_capacity);
+    memMeterAdd(pool->getMeter().idle, pool->chunk_capacity);
+    pool->chunkCount++;
+    lastref = squid_curtime;
+    pool->allChunks.insert(this, memCompChunks);
+}
+
+MemPoolChunked::MemPoolChunked(const char *aLabel, size_t aSize) : MemImplementingAllocator(aLabel, aSize)
+{
+    chunk_size = 0;
+    chunk_capacity = 0;
+    chunkCount = 0;
+    freeCache = 0;
+    nextFreeChunk = 0;
+    Chunks = 0;
+    next = 0;
+    MemImplementingAllocator *last_pool;
+
+    assert(aLabel != NULL && aSize);
+
+    setChunkSize(MEM_CHUNK_SIZE);
+
+    /* Append as Last */
+    for (last_pool = MemPools::GetInstance().pools; last_pool && last_pool->next;)
+        last_pool = last_pool->next;
+    if (last_pool)
+        last_pool->next = this;
+    else
+        MemPools::GetInstance().pools = this;
+}
+
+MemChunk::~MemChunk()
+{
+    memMeterDel(pool->getMeter().alloc, pool->chunk_capacity);
+    memMeterDel(pool->getMeter().idle, pool->chunk_capacity);
+    pool->chunkCount--;
+    pool->allChunks.remove(this, memCompChunks);
+    xfree(objCache);
+}
+
+void
+MemPoolChunked::push(void *obj)
+{
+    void **Free;
+    /* XXX We should figure out a sane way of avoiding having to clear
+     * all buffers. For example data buffers such as used by MemBuf do
+     * not really need to be cleared.. There was a condition based on
+     * the object size here, but such condition is not safe.
+     */
+    if (doZeroOnPush)
+        memset(obj, 0, obj_size);
+    Free = (void **)obj;
+    *Free = freeCache;
+    freeCache = obj;
+    (void) VALGRIND_MAKE_MEM_NOACCESS(obj, obj_size);
+}
+
+/*
+ * Find a chunk with a free item.
+ * Create new chunk on demand if no chunk with frees found.
+ * Insert new chunk in front of lowest ram chunk, making it preferred in future,
+ * and resulting slow compaction towards lowest ram area.
+ */
+void *
+MemPoolChunked::get()
+{
+    void **Free;
+
+    /* first, try cache */
+    if (freeCache) {
+        Free = (void **)freeCache;
+        (void) VALGRIND_MAKE_MEM_DEFINED(Free, obj_size);
+        freeCache = *Free;
+        *Free = NULL;
+        return Free;
+    }
+    /* then try perchunk freelist chain */
+    if (nextFreeChunk == NULL) {
+        /* no chunk with frees, so create new one */
+        createChunk();
+    }
+    /* now we have some in perchunk freelist chain */
+    MemChunk *chunk = nextFreeChunk;
+
+    Free = (void **)chunk->freeList;
+    chunk->freeList = *Free;
+    *Free = NULL;
+    chunk->inuse_count++;
+    chunk->lastref = squid_curtime;
+
+    if (chunk->freeList == NULL) {
+        /* last free in this chunk, so remove us from perchunk freelist chain */
+        nextFreeChunk = chunk->nextFreeChunk;
+    }
+    (void) VALGRIND_MAKE_MEM_DEFINED(Free, obj_size);
+    return Free;
+}
+
+/* just create a new chunk and place it into a good spot in the chunk chain */
+void
+MemPoolChunked::createChunk()
+{
+    MemChunk *chunk, *newChunk;
+
+    newChunk = new MemChunk(this);
+
+    chunk = Chunks;
+    if (chunk == NULL) {	/* first chunk in pool */
+        Chunks = newChunk;
+        return;
+    }
+    if (newChunk->objCache < chunk->objCache) {
+        /* we are lowest ram chunk, insert as first chunk */
+        newChunk->next = chunk;
+        Chunks = newChunk;
+        return;
+    }
+    while (chunk->next) {
+        if (newChunk->objCache < chunk->next->objCache) {
+            /* new chunk is in lower ram, insert here */
+            newChunk->next = chunk->next;
+            chunk->next = newChunk;
+            return;
+        }
+        chunk = chunk->next;
+    }
+    /* we are the worst chunk in chain, add as last */
+    chunk->next = newChunk;
+}
+
+void
+MemPoolChunked::setChunkSize(size_t chunksize)
+{
+    int cap;
+    size_t csize = chunksize;
+
+    if (Chunks)		/* unsafe to tamper */
+        return;
+
+    csize = ((csize + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE) * MEM_PAGE_SIZE;	/* round up to page size */
+    cap = csize / obj_size;
+
+    if (cap < MEM_MIN_FREE)
+        cap = MEM_MIN_FREE;
+    if (cap * obj_size > MEM_CHUNK_MAX_SIZE)
+        cap = MEM_CHUNK_MAX_SIZE / obj_size;
+    if (cap > MEM_MAX_FREE)
+        cap = MEM_MAX_FREE;
+    if (cap < 1)
+        cap = 1;
+
+    csize = cap * obj_size;
+    csize = ((csize + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE) * MEM_PAGE_SIZE;	/* round up to page size */
+    cap = csize / obj_size;
+
+    chunk_capacity = cap;
+    chunk_size = csize;
+}
+
+/*
+ * warning: we do not clean this entry from Pools assuming destruction
+ * is used at the end of the program only
+ */
+MemPoolChunked::~MemPoolChunked()
+{
+    MemChunk *chunk, *fchunk;
+    MemImplementingAllocator *find_pool, *prev_pool;
+
+    flushMetersFull();
+    clean(0);
+    assert(getMeter().inuse.level == 0 && "While trying to destroy pool");
+
+    chunk = Chunks;
+    while ( (fchunk = chunk) != NULL) {
+        chunk = chunk->next;
+        delete fchunk;
+    }
+    /* TODO we should be doing something about the original Chunks pointer here. */
+
+    assert(MemPools::GetInstance().pools != NULL && "Called MemPoolChunked::~MemPoolChunked, but no pool exists!");
+
+    /* Pool clean, remove it from List and free */
+    for (find_pool = MemPools::GetInstance().pools, prev_pool = NULL; (find_pool && this != find_pool); find_pool = find_pool->next)
+        prev_pool = find_pool;
+    assert(find_pool != NULL && "pool to destroy not found");
+
+    if (prev_pool)
+        prev_pool->next = next;
+    else
+        MemPools::GetInstance().pools = next;
+    --MemPools::GetInstance().poolCount;
+}
+
+int
+MemPoolChunked::getInUseCount()
+{
+    return getMeter().inuse.level;
+}
+
+void *
+MemPoolChunked::allocate()
+{
+    void *p = get();
+    assert(meter.idle.level > 0);
+    memMeterDec(meter.idle);
+    memMeterInc(meter.inuse);
+    return p;
+}
+
+void
+MemPoolChunked::deallocate(void *obj)
+{
+    push(obj);
+    assert(meter.inuse.level > 0);
+    memMeterDec(meter.inuse);
+    memMeterInc(meter.idle);
+}
+
+void
+MemPoolChunked::convertFreeCacheToChunkFreeCache()
+{
+    void *Free;
+    /*
+     * OK, so we have to go through all the global freeCache and find the Chunk
+     * any given Free belongs to, and stuff it into that Chunk's freelist
+     */
+
+    while ((Free = freeCache) != NULL) {
+        MemChunk *chunk = NULL;
+        chunk = const_cast<MemChunk *>(*allChunks.find(Free, memCompObjChunks));
+        assert(splayLastResult == 0);
+        assert(chunk->inuse_count > 0);
+        chunk->inuse_count--;
+        (void) VALGRIND_MAKE_MEM_DEFINED(Free, sizeof(void *));
+        freeCache = *(void **)Free;	/* remove from global cache */
+        *(void **)Free = chunk->freeList;	/* stuff into chunks freelist */
+        (void) VALGRIND_MAKE_MEM_NOACCESS(Free, sizeof(void *));
+        chunk->freeList = Free;
+        chunk->lastref = squid_curtime;
+    }
+
+}
+
+/* removes empty Chunks from pool */
+void
+MemPoolChunked::clean(time_t maxage)
+{
+    MemChunk *chunk, *freechunk, *listTail;
+    time_t age;
+
+    if (!this)
+        return;
+    if (!Chunks)
+        return;
+
+    flushMetersFull();
+    convertFreeCacheToChunkFreeCache();
+    /* Now we have all chunks in this pool cleared up, all free items returned to their home */
+    /* We start now checking all chunks to see if we can release any */
+    /* We start from Chunks->next, so first chunk is not released */
+    /* Recreate nextFreeChunk list from scratch */
+
+    chunk = Chunks;
+    while ((freechunk = chunk->next) != NULL) {
+        age = squid_curtime - freechunk->lastref;
+        freechunk->nextFreeChunk = NULL;
+        if (freechunk->inuse_count == 0)
+            if (age >= maxage) {
+                chunk->next = freechunk->next;
+                delete freechunk;
+                freechunk = NULL;
+            }
+        if (chunk->next == NULL)
+            break;
+        chunk = chunk->next;
+    }
+
+    /* Recreate nextFreeChunk list from scratch */
+    /* Populate nextFreeChunk list in order of "most filled chunk first" */
+    /* in case of equal fill, put chunk in lower ram first */
+    /* First (create time) chunk is always on top, no matter how full */
+
+    chunk = Chunks;
+    nextFreeChunk = chunk;
+    chunk->nextFreeChunk = NULL;
+
+    while (chunk->next) {
+        chunk->next->nextFreeChunk = NULL;
+        if (chunk->next->inuse_count < chunk_capacity) {
+            listTail = nextFreeChunk;
+            while (listTail->nextFreeChunk) {
+                if (chunk->next->inuse_count > listTail->nextFreeChunk->inuse_count)
+                    break;
+                if ((chunk->next->inuse_count == listTail->nextFreeChunk->inuse_count) &&
+                        (chunk->next->objCache < listTail->nextFreeChunk->objCache))
+                    break;
+                listTail = listTail->nextFreeChunk;
+            }
+            chunk->next->nextFreeChunk = listTail->nextFreeChunk;
+            listTail->nextFreeChunk = chunk->next;
+        }
+        chunk = chunk->next;
+    }
+    /* We started from 2nd chunk. If first chunk is full, remove it */
+    if (nextFreeChunk->inuse_count == chunk_capacity)
+        nextFreeChunk = nextFreeChunk->nextFreeChunk;
+
+    return;
+}
+
+bool
+MemPoolChunked::idleTrigger(int shift) const
+{
+    return getMeter().idle.level > (chunk_capacity << shift);
+}
+
+/*
+ * Update MemPoolStats struct for single pool
+ */
+int
+MemPoolChunked::getStats(MemPoolStats * stats, int accumulate)
+{
+    MemChunk *chunk;
+    int chunks_free = 0;
+    int chunks_partial = 0;
+
+    if (!accumulate)	/* need skip memset for GlobalStats accumulation */
+        memset(stats, 0, sizeof(MemPoolStats));
+
+    clean((time_t) 555555);	/* don't want to get chunks released before reporting */
+
+    stats->pool = this;
+    stats->label = objectType();
+    stats->meter = &getMeter();
+    stats->obj_size = obj_size;
+    stats->chunk_capacity = chunk_capacity;
+
+    /* gather stats for each Chunk */
+    chunk = Chunks;
+    while (chunk) {
+        if (chunk->inuse_count == 0)
+            chunks_free++;
+        else if (chunk->inuse_count < chunk_capacity)
+            chunks_partial++;
+        chunk = chunk->next;
+    }
+
+    stats->chunks_alloc += chunkCount;
+    stats->chunks_inuse += chunkCount - chunks_free;
+    stats->chunks_partial += chunks_partial;
+    stats->chunks_free += chunks_free;
+
+    stats->items_alloc += getMeter().alloc.level;
+    stats->items_inuse += getMeter().inuse.level;
+    stats->items_idle += getMeter().idle.level;
+
+    stats->overhead += sizeof(MemPoolChunked) + chunkCount * sizeof(MemChunk) + strlen(objectType()) + 1;
+
+    return getMeter().inuse.level;
+}

=== added file 'lib/MemPoolMalloc.cc'
--- lib/MemPoolMalloc.cc	1970-01-01 00:00:00 +0000
+++ lib/MemPoolMalloc.cc	2010-05-28 21:53:06 +0000
@@ -0,0 +1,117 @@
+
+/*
+ * $Id$
+ *
+ * DEBUG: section 63    Low Level Memory Pool Management
+ * AUTHOR: Alex Rousskov, Andres Kroonmaa, Robert Collins
+ *
+ * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/
+ * ----------------------------------------------------------
+ *
+ *  Squid is the result of efforts by numerous individuals from the
+ *  Internet community.  Development is led by Duane Wessels of the
+ *  National Laboratory for Applied Network Research and funded by the
+ *  National Science Foundation.  Squid is Copyrighted (C) 1998 by
+ *  the Regents of the University of California.  Please see the
+ *  COPYRIGHT file for full details.  Squid incorporates software
+ *  developed and/or copyrighted by other sources.  Please see the
+ *  CREDITS file for full details.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+
+#include "config.h"
+#if HAVE_ASSERT_H
+#include <assert.h>
+#endif
+
+#include "MemPoolMalloc.h"
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+/*
+ * XXX This is a boundary violation between lib and src.. would be good
+ * if it could be solved otherwise, but left for now.
+ */
+extern time_t squid_curtime;
+
+void *
+MemPoolMalloc::allocate()
+{
+    memMeterInc(meter.alloc);
+    memMeterInc(meter.inuse);
+    return xcalloc(1, obj_size);
+}
+
+void
+MemPoolMalloc::deallocate(void *obj)
+{
+    memMeterDec(meter.inuse);
+    memMeterDec(meter.alloc);
+    xfree(obj);
+}
+
+/* TODO extract common logic to MemAllocate */
+int
+MemPoolMalloc::getStats(MemPoolStats * stats, int accumulate)
+{
+    if (!accumulate)	/* need skip memset for GlobalStats accumulation */
+        memset(stats, 0, sizeof(MemPoolStats));
+
+    stats->pool = this;
+    stats->label = objectType();
+    stats->meter = &getMeter();
+    stats->obj_size = obj_size;
+    stats->chunk_capacity = 0;
+
+    stats->chunks_alloc += 0;
+    stats->chunks_inuse += 0;
+    stats->chunks_partial += 0;
+    stats->chunks_free += 0;
+
+    stats->items_alloc += meter.alloc.level;
+    stats->items_inuse += meter.inuse.level;
+    stats->items_idle += meter.idle.level;
+
+    stats->overhead += sizeof(MemPoolMalloc) + strlen(objectType()) + 1;
+
+    return meter.inuse.level;
+}
+
+int
+MemPoolMalloc::getInUseCount()
+{
+    return meter.inuse.level;
+}
+
+MemPoolMalloc::MemPoolMalloc(char const *aLabel, size_t aSize) : MemImplementingAllocator(aLabel, aSize)
+{
+}
+
+bool
+MemPoolMalloc::idleTrigger(int shift) const
+{
+    return false;
+}
+
+void
+MemPoolMalloc::clean(time_t maxage)
+{
+}
+

# Begin bundle
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
/XaSf/i7kinChIOSgYcQ

