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