[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. |