Hi folks

I've attached a diff for a pool allocator that tries to allocate TPdfRefCountedBuffer instances in 4k chunks (each of which has its own 32 byte internal buffer, and will go out to heap memory if it needs more than that).

It's a pretty dumb implementation, and seems to have minimal effect on performance either way. I'm mostly posting it here so it doesn't get lost.

I'm going to have a play with the Boost pool allocator and see if it does a better job (it'd better). It's trivial to make optional, so we'd use the default ::operator new(...) unless Boost was available.

--
Craig Ringer
Index: src/PdfRefCountedBuffer.cpp
===================================================================
--- src/PdfRefCountedBuffer.cpp (revision 731)
+++ src/PdfRefCountedBuffer.cpp (working copy)
@@ -20,8 +20,11 @@

 #include "PdfRefCountedBuffer.h"

+#include <iostream>//XXX
+
 namespace PoDoFo {

+PdfRefCountedBuffer::TRefCountedBuffer::RCBufAllocator  
PdfRefCountedBuffer::TRefCountedBuffer::m_alloc;

 #define STREAM_SIZE_INCREASE 1024

@@ -241,5 +244,30 @@
     return false;
 }

+#define PAGE_SIZE 4096

+PdfRefCountedBuffer::TRefCountedBuffer::RCBufAllocator::RCBufAllocator()
+    : ALLOC_BLOCK_SIZE( PAGE_SIZE / sizeof(TRefCountedBuffer) )
+{
+    allocBlock();
+    std::cerr << "Each " << (PAGE_SIZE*sizeof(TRefCountedBuffer)) << "byte 
block contains " << ALLOC_BLOCK_SIZE << " instances of the " << 
sizeof(TRefCountedBuffer) << " byte object" << std::endl;
+}
+
+PdfRefCountedBuffer::TRefCountedBuffer::RCBufAllocator::~RCBufAllocator()
+{
+    // We don't actually know what's in use. However, since we don't permit
+    // this class to be used for anything with a dtor that needs to be run,
+    // we don't care. Just free the blocks.
+    for ( std::vector<void*>::iterator it = m_blocks.begin() ; it != 
m_blocks.end() ; ++it )
+        free(*it);
+}
+
+void PdfRefCountedBuffer::TRefCountedBuffer::RCBufAllocator::allocBlock()
+{
+    TRefCountedBuffer* block = static_cast<TRefCountedBuffer*>(malloc( 
ALLOC_BLOCK_SIZE * sizeof(TRefCountedBuffer) ));
+    m_blocks.push_back(block);
+    for ( int i = 1; i < ALLOC_BLOCK_SIZE ; ++i )
+        freelist.push( block + i );
+}
+
 };
Index: src/PdfRefCountedBuffer.h
===================================================================
--- src/PdfRefCountedBuffer.h   (revision 731)
+++ src/PdfRefCountedBuffer.h   (working copy)
@@ -23,6 +23,9 @@

 #include "PdfDefines.h"

+#include <queue>
+#include <vector>
+
 namespace PoDoFo {

 /**
@@ -189,6 +192,29 @@
         bool  m_bPossesion;
         // Are we using the heap-allocated buffer in place of our small 
internal one?
         bool  m_bOnHeap;
+
+        // A custom allocator we use to cluster TRefCountedBuffer allocations
+        // into roughly page sized chunks.
+        struct RCBufAllocator
+        {
+            const int ALLOC_BLOCK_SIZE;
+            std::vector<void*> m_blocks;
+            std::queue<void*> freelist;
+            RCBufAllocator();
+            ~RCBufAllocator();
+            void allocBlock();
+            void* allocate();
+            PODOFO_NOTHROW void deallocate(void* p);
+        };
+        static RCBufAllocator m_alloc;
+        void* operator new(size_t /*size*/)
+        {
+            return m_alloc.allocate();
+        }
+        PODOFO_NOTHROW void operator delete(void* p)
+        {
+            m_alloc.deallocate(p);
+        }
     };

     TRefCountedBuffer* m_pBuffer;
@@ -304,6 +330,27 @@
     m_pBuffer = NULL;
 }

+// -----------------------------------------------------
+//
+// -----------------------------------------------------
+inline void* PdfRefCountedBuffer::TRefCountedBuffer::RCBufAllocator::allocate()
+{
+    void* ret;
+    if (!freelist.size())
+        allocBlock();
+    ret = freelist.front();
+    freelist.pop();
+    return ret;
+}
+
+// -----------------------------------------------------
+//
+// -----------------------------------------------------
+inline PODOFO_NOTHROW void 
PdfRefCountedBuffer::TRefCountedBuffer::RCBufAllocator::deallocate(void* p)
+{
+    freelist.push(p);
+}
+
 };

 #endif // _PDF_REF_COUNTED_BUFFER_H_

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Podofo-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/podofo-users

Reply via email to