Thread: [Assorted-commits] SF.net SVN: assorted: [388] cpp-commons/trunk/src/commons/region.h
Brought to you by:
yangzhang
From: <yan...@us...> - 2008-02-12 16:37:46
|
Revision: 388 http://assorted.svn.sourceforge.net/assorted/?rev=388&view=rev Author: yangzhang Date: 2008-02-12 08:34:43 -0800 (Tue, 12 Feb 2008) Log Message: ----------- added region.h Added Paths: ----------- cpp-commons/trunk/src/commons/region.h Added: cpp-commons/trunk/src/commons/region.h =================================================================== --- cpp-commons/trunk/src/commons/region.h (rev 0) +++ cpp-commons/trunk/src/commons/region.h 2008-02-12 16:34:43 UTC (rev 388) @@ -0,0 +1,177 @@ +// TODO: use shared_ptr instead of custom ref counting? + +#ifndef COMMONS_REGION_H +#define COMMONS_REGION_H + +#include <limits> + +namespace commons +{ + + /** + * Default chunk size is 100MB. + */ + const size_t default_chunk_size = 100000000; + + /** + * Simple dynamically growing memory region that does not support + * deallocation. + */ + class mem_region + { + private: + vector<char*> chunks; + const size_t chunk_size; + size_t top; + int m_refcount; + + public: + mem_region() : + chunk_size(default_chunk_size), + top(0), + m_refcount(0) + { + chunks.push_back(new char[chunk_size]); + } + + ~mem_region() + { + for (unsigned int i = 0; i < chunks.size(); i++) { + delete [] chunks[i]; + } + } + + void addref() { ++m_refcount; } + void decref() { if (--m_refcount == 0) { delete this; } } + + void *alloc_mem(size_t n) + { + if (top + n > chunk_size) { + chunks.push_back(new char[chunk_size]); + top = 0; + } + size_t old_top = top; + top += n; + return chunks.back() + old_top; + } + }; + + /** + * Standard region-based allocator. Useful for restricting locality and/or + * avoiding multithreaded contention. + */ + template <class T> + class region_alloc { + public: + // Type definitions. + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + typedef mem_region pool_type; + + /** + * Rebind allocator to type U. + */ + template <class U> + struct rebind { + typedef region_alloc<U> other; + }; + + /** + * Return address of values. + */ + pointer address (reference value) const { return &value; } + const_pointer address (const_reference value) const { return &value; } + + /** + * Default constructor creates a new pool. + */ + region_alloc() throw() { + region = new pool_type; + region->addref(); + } + + /** + * Copy constructor addrefs the region. + * TODO: This is in fact highly necessary. Understand why. Understand both + * the following ctors. + */ + region_alloc(const region_alloc& src) throw() { + region = src.region; + region->addref(); + } + + /** + * Copy constructor addrefs the region. + */ + template <class U> + region_alloc (const region_alloc<U> &src) throw() { + region = src.region; + region->addref(); + } + + /** + * Destructor decrefs the region. + */ + ~region_alloc() throw() { region->decref(); } + + /** + * Return maximum number of elements that can be allocated. Throws an + * exception. + */ + size_type max_size() const throw() { throw exception(); } + + /** + * Allocate (but don't initialize) num elements of type T. + */ + pointer allocate(size_type num, const void* = 0) + { + return (pointer) region->alloc_mem(num * sizeof(T)); + } + + /** + * Initialize elements of allocated storage p with value `value` using + * placement new. + */ + void construct(pointer p, const T& value) { new((void*)p)T(value); } + + /** + * Destroy elements of initialized storage p by calling their destructor. + */ + void destroy(pointer p) { p->~T(); } + + /** + * Deallocate storage p of deleted elements. This actually does nothing. + */ + void deallocate(pointer p, size_type num) {} + + // TODO: why can't this be private? (cp ctor fails) + pool_type *region; + }; + + /** + * All allocators of the same type are supposed to be equal. + * TODO: Understand why. + */ + template <class T1, class T2> + bool operator== (const region_alloc<T1>&, const region_alloc<T2>&) throw() { + return true; + } + + /** + * All allocators of the same type are supposed to be equal. + * TODO: Understand why. + */ + template <class T1, class T2> + bool operator!= (const region_alloc<T1>&, const region_alloc<T2>&) throw() { + return false; + } + +} + +#endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2008-02-12 16:45:06
|
Revision: 390 http://assorted.svn.sourceforge.net/assorted/?rev=390&view=rev Author: yangzhang Date: 2008-02-12 08:45:07 -0800 (Tue, 12 Feb 2008) Log Message: ----------- implemented max_size Modified Paths: -------------- cpp-commons/trunk/src/commons/region.h Modified: cpp-commons/trunk/src/commons/region.h =================================================================== --- cpp-commons/trunk/src/commons/region.h 2008-02-12 16:35:02 UTC (rev 389) +++ cpp-commons/trunk/src/commons/region.h 2008-02-12 16:45:07 UTC (rev 390) @@ -8,6 +8,8 @@ namespace commons { + using namespace std; + /** * Default chunk size is 100MB. */ @@ -121,10 +123,13 @@ ~region_alloc() throw() { region->decref(); } /** - * Return maximum number of elements that can be allocated. Throws an - * exception. + * Return maximum number of elements that can be allocated. Simply return + * the size based on the size of memory. */ - size_type max_size() const throw() { throw exception(); } + size_type max_size() const throw() + { + return numeric_limits<size_t>::max() / sizeof(T); + } /** * Allocate (but don't initialize) num elements of type T. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2008-02-12 17:08:52
|
Revision: 391 http://assorted.svn.sourceforge.net/assorted/?rev=391&view=rev Author: yangzhang Date: 2008-02-12 09:08:58 -0800 (Tue, 12 Feb 2008) Log Message: ----------- added support for arbitrary-sized allocations Modified Paths: -------------- cpp-commons/trunk/src/commons/region.h Modified: cpp-commons/trunk/src/commons/region.h =================================================================== --- cpp-commons/trunk/src/commons/region.h 2008-02-12 16:45:07 UTC (rev 390) +++ cpp-commons/trunk/src/commons/region.h 2008-02-12 17:08:58 UTC (rev 391) @@ -16,45 +16,62 @@ const size_t default_chunk_size = 100000000; /** + * A fixed-size buffer (really just a pair of length and pointer). + */ + struct chunk + { + size_t size; + char* data; + }; + + /** * Simple dynamically growing memory region that does not support * deallocation. */ class mem_region { private: - vector<char*> chunks; + vector<chunk> chunks; + /** + * The default chunk-size when incrementally resizing; we can still handle + * larger allocations. + */ const size_t chunk_size; size_t top; - int m_refcount; + int refcount; public: mem_region() : chunk_size(default_chunk_size), top(0), - m_refcount(0) + refcount(0) { - chunks.push_back(new char[chunk_size]); + chunks.push_back((chunk) {chunk_size, new char[chunk_size]}); } ~mem_region() { + // cout << "deleting" << endl; for (unsigned int i = 0; i < chunks.size(); i++) { - delete [] chunks[i]; + delete [] chunks[i].data; } } - void addref() { ++m_refcount; } - void decref() { if (--m_refcount == 0) { delete this; } } + void addref() { ++refcount; } + void decref() { if (--refcount == 0) { delete this; } } void *alloc_mem(size_t n) { if (top + n > chunk_size) { - chunks.push_back(new char[chunk_size]); + // chunks.push_back(new char[chunk_size]); + size_t sz = max(n, chunk_size); + chunks.push_back((chunk) {sz, new char[sz] }); top = 0; } + // cout << "alloced" << endl; size_t old_top = top; top += n; - return chunks.back() + old_top; + return chunks.back().data + old_top; } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <yan...@us...> - 2008-02-12 22:13:00
|
Revision: 396 http://assorted.svn.sourceforge.net/assorted/?rev=396&view=rev Author: yangzhang Date: 2008-02-12 14:13:04 -0800 (Tue, 12 Feb 2008) Log Message: ----------- more space-saving; disabled debugs Modified Paths: -------------- cpp-commons/trunk/src/commons/region.h Modified: cpp-commons/trunk/src/commons/region.h =================================================================== --- cpp-commons/trunk/src/commons/region.h 2008-02-12 21:58:51 UTC (rev 395) +++ cpp-commons/trunk/src/commons/region.h 2008-02-12 22:13:04 UTC (rev 396) @@ -7,6 +7,7 @@ // XXX: debug #include <set> +#include <vector> #include <pthread.h> namespace commons @@ -17,7 +18,7 @@ /** * Default chunk size is 100MB. */ - const size_t default_chunk_size = 100000000; + const size_t default_chunk_size = 10000000; /** * A fixed-size buffer (really just a pair of length and pointer). @@ -51,13 +52,13 @@ top(0), refcount(0) { - cout << "created " << this << endl; + // cout << "created " << this << endl; chunks.push_back((chunk) {chunk_size, new char[chunk_size]}); } ~mem_region() { - cout << "deleting" << endl; + // cout << "deleting" << endl; for (unsigned int i = 0; i < chunks.size(); i++) { delete [] chunks[i].data; } @@ -68,18 +69,29 @@ void *alloc_mem(size_t n) { - pthread_t t = pthread_self(); - if (threads.insert(t).second) - cout << this << " -- " << t << endl; + // pthread_t t = pthread_self(); + // if (threads.insert(t).second) + // cout << this << " -- " << t << endl; - if (top + n > chunks.back().size) { + chunk* last = &chunks.back(); + if (top + n > last->size) { size_t sz = max(n, chunk_size); - chunks.push_back((chunk) {sz, new char[sz] }); - top = 0; + chunk c = {sz, new char[sz]}; + if (n > chunk_size) { + // cout << "insert " << this << endl; + chunks.insert(chunks.begin(), c); + return c.data; + } else { + // cout << "append " << this << endl; + chunks.push_back(c); + top = 0; + last = &chunks.back(); + } } + // cout << "ALLOC " << this << endl; size_t old_top = top; top += n; - return chunks.back().data + old_top; + return last->data + old_top; } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |