mirror of
				https://github.com/pocoproject/poco.git
				synced 2025-10-27 11:06:50 +01:00 
			
		
		
		
	Any SOO
This commit is contained in:
		
							
								
								
									
										251
									
								
								Foundation/include/Poco/SmallObjectAllocator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										251
									
								
								Foundation/include/Poco/SmallObjectAllocator.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,251 @@ | ||||
| // | ||||
| // SmallObjectAllocator.h | ||||
| // | ||||
| // $Id: //poco/1.4/Foundation/include/Poco/SmallObjectAllocator.h#1 $ | ||||
| // | ||||
| // Library: Foundation | ||||
| // Package: Core | ||||
| // Module:  SmallObjectAllocator | ||||
| // | ||||
| // Definition of the SmallObjectAllocator template. | ||||
| // | ||||
| // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. | ||||
| // and Contributors. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person or organization | ||||
| // obtaining a copy of the software and accompanying documentation covered by | ||||
| // this license (the "Software") to use, reproduce, display, distribute, | ||||
| // execute, and transmit the Software, and to prepare derivative works of the | ||||
| // Software, and to permit third-parties to whom the Software is furnished to | ||||
| // do so, all subject to the following: | ||||
| //  | ||||
| // The copyright notices in the Software and this entire statement, including | ||||
| // the above license grant, this restriction and the following disclaimer, | ||||
| // must be included in all copies of the Software, in whole or in part, and | ||||
| // all derivative works of the Software, unless such copies or derivative | ||||
| // works are solely in the form of machine-executable object code generated by | ||||
| // a source language processor. | ||||
| //  | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT | ||||
| // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE | ||||
| // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, | ||||
| // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||
| // DEALINGS IN THE SOFTWARE. | ||||
| // | ||||
|  | ||||
|  | ||||
| #ifndef Foundation_SmallObjectAllocator_INCLUDED | ||||
| #define Foundation_SmallObjectAllocator_INCLUDED | ||||
|  | ||||
|  | ||||
| #include "Poco/Foundation.h" | ||||
| #include "Poco/Types.h" | ||||
|  | ||||
|  | ||||
| namespace Poco { | ||||
|  | ||||
|  | ||||
| template <typename T, std::size_t S = sizeof(T)> | ||||
| class SmallObjectAllocator | ||||
| 	/// SmallObjectAllocator template is a lightweight wrapper implementing | ||||
| 	/// small object allocation optimization idiom. Class is statically | ||||
| 	/// parameterized on type created and the size threshold, which defaults | ||||
| 	/// to the created object size; it follows that the default behavior is | ||||
| 	/// use of automatically allocated memory (i.e. the value wrapped is | ||||
| 	/// stored in the pre-allocated buffer). To enforce heap allocation, | ||||
| 	/// specify S parameter to a value smaller than the size of the type  | ||||
| 	/// being instantiated. | ||||
| 	///  | ||||
| 	/// The SmallObjectAllocator trade-off is the runtime check for memory  | ||||
| 	/// location where the value resides. The runtime check occurs at  | ||||
| 	/// construction/destruction as well as every value access. Value | ||||
| 	/// access check can be alleviated by caching the value reference. | ||||
| 	/// | ||||
| 	/// Usage example: | ||||
| 	///  | ||||
| 	///    SmallObjectAllocator<int> s; // on the stack | ||||
| 	///    SmallObjectAllocator<int, 1> h; // force heap alloc | ||||
| 	///    int& i = s.get(); // no runtime performance penalty after this point | ||||
| 	///    i = 5; | ||||
| 	///  | ||||
| { | ||||
| public: | ||||
| 	SmallObjectAllocator() | ||||
| 	{ | ||||
| 		if (isOnHeap()) _memory.ptr = new T(); | ||||
| 		else new (_memory.buf) T; | ||||
| 	} | ||||
|  | ||||
| 	SmallObjectAllocator(const T& val) | ||||
| 	{ | ||||
| 		if (isOnHeap()) _memory.ptr = new T(val); | ||||
| 		else new (_memory.buf) T(val); | ||||
| 	} | ||||
|  | ||||
| 	SmallObjectAllocator(const SmallObjectAllocator& other) | ||||
| 	{ | ||||
| 		if (this != &other) | ||||
| 		{ | ||||
| 			if (isOnHeap()) | ||||
| 				_memory.ptr = new T(*other._memory.ptr); | ||||
| 			else | ||||
| 				new (_memory.buf) T(*reinterpret_cast<const T*>(other._memory.buf)); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	~SmallObjectAllocator() | ||||
| 	{ | ||||
| 		if (isOnHeap()) delete _memory.ptr; | ||||
| 		else reinterpret_cast<T*>(_memory.buf)->~T(); | ||||
| 	} | ||||
|  | ||||
| 	SmallObjectAllocator& operator =(const SmallObjectAllocator& other) | ||||
| 	{ | ||||
| 		if (this != &other) | ||||
| 		{ | ||||
| 			if (isOnHeap()) | ||||
| 				_memory.ptr = new T(*other._memory.ptr); | ||||
| 			else | ||||
| 				new (_memory.buf) T(*reinterpret_cast<const T*>(other._memory.buf)); | ||||
| 		} | ||||
|  | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
| 	T& get() | ||||
| 	{ | ||||
| 		if (isOnHeap()) | ||||
| 			return *_memory.ptr; | ||||
| 		else | ||||
| 			return reinterpret_cast<T&>(*(_memory.buf)); | ||||
| 	} | ||||
|  | ||||
| 	const T& get() const | ||||
| 	{ | ||||
| 		if (isOnHeap()) | ||||
| 			return *_memory.ptr; | ||||
| 		else | ||||
| 			return reinterpret_cast<const T&>(*_memory.buf); | ||||
| 	} | ||||
|  | ||||
| 	bool isOnHeap() const | ||||
| 	{ | ||||
| 		return sizeof(T) > S; | ||||
| 	} | ||||
|  | ||||
| private: | ||||
| 	union | ||||
| 	{ | ||||
| 		unsigned char buf[S];  | ||||
| 		T* ptr; | ||||
| 	} _memory; | ||||
| }; | ||||
|  | ||||
|  | ||||
| template <> | ||||
| class SmallObjectAllocator <char*> | ||||
| 	/// SmallObjectAllocator char* specialization. | ||||
| 	///  | ||||
| 	/// The treshold between auto and heap allocation | ||||
| 	/// is controlled through POCO_SMALL_OBJECT_SIZE compile | ||||
| 	/// time constant, which on 32 or 64 systems defaults | ||||
| 	/// to 31 or 63 bytes respectively. This specialization | ||||
| 	/// adds an extra byte to indicate the allocation strategy. | ||||
| 	///  | ||||
| 	/// To summarize, e.g. POCO_SMALL_OBJECT_SIZE value of 7 will | ||||
| 	/// take up at least 8 bytes of storage (for auto allocation) | ||||
| 	/// with 6 bytes as the effective string length: | ||||
| 	///  | ||||
| 	///  +---+---+---+---+---+---+---+---+ | ||||
| 	///  | c | c | c | c | c | c | 0 | f | | ||||
| 	///  +---+---+---+---+---+---+---+---+ | ||||
| 	/// | ||||
| 	/// Legend: | ||||
| 	///    c - character | ||||
| 	///    0 - terminating zero | ||||
| 	///    f - allocation flag | ||||
| 	///  | ||||
| { | ||||
| public: | ||||
| 	static const std::size_t Size = POCO_SMALL_OBJECT_SIZE; | ||||
|  | ||||
| 	SmallObjectAllocator(std::size_t sz) | ||||
| 	{ | ||||
| 		_memory.buf[Size] = (sz > Size) ? 1 : 0; | ||||
| 		if (_memory.buf[Size]) _memory.ptr = new char[sz + 1]; | ||||
| 	} | ||||
|  | ||||
| 	SmallObjectAllocator(const char* pCh, std::size_t sz) | ||||
| 	{ | ||||
| 		allocateAndAssign(pCh, sz); | ||||
| 	} | ||||
|  | ||||
| 	SmallObjectAllocator(const char* pCh) | ||||
| 	{ | ||||
| 		allocateAndAssign(pCh, strlen(pCh)); | ||||
| 	} | ||||
| 	 | ||||
| 	~SmallObjectAllocator() | ||||
| 	{ | ||||
| 		if (_memory.buf[Size]) delete _memory.ptr; | ||||
| 	} | ||||
|  | ||||
| 	SmallObjectAllocator <char*>& operator = (const char* pCh) | ||||
| 	{ | ||||
| 		allocateAndAssign(pCh, strlen(pCh)); | ||||
| 		return *this; | ||||
| 	} | ||||
|  | ||||
| 	char* get() | ||||
| 	{ | ||||
| 		if (_memory.buf[Size]) return _memory.ptr; | ||||
| 		else return _memory.buf; | ||||
| 	} | ||||
|  | ||||
| 	const char* get() const | ||||
| 	{ | ||||
| 		if (_memory.buf[Size]) return _memory.ptr; | ||||
| 		else return _memory.buf; | ||||
| 	} | ||||
|  | ||||
| 	bool isOnHeap() const | ||||
| 	{ | ||||
| 		return _memory.buf[Size] != 0; | ||||
| 	} | ||||
|  | ||||
| private: | ||||
| 	SmallObjectAllocator(); | ||||
|  | ||||
| 	void allocateAndAssign(const char* pCh, std::size_t sz) | ||||
| 	{ | ||||
| 		_memory.buf[Size] = (sz > Size) ? 1 : 0; | ||||
| 		if (_memory.buf[Size]) | ||||
| 		{ | ||||
| 			_memory.ptr = new char[sz + 1]; | ||||
| 			_memory.ptr[sz] = '\0'; | ||||
| 			std::memcpy(_memory.ptr, pCh, sz); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			_memory.buf[sz] = '\0'; | ||||
| 			std::memcpy(_memory.buf, pCh, sz); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	union | ||||
| 	{ | ||||
| 		char buf[Size + 1];  | ||||
| 		char* ptr; | ||||
| 	} _memory; | ||||
| }; | ||||
|  | ||||
|  | ||||
| typedef SmallObjectAllocator<char*> SmallStringAllocator; | ||||
|  | ||||
|  | ||||
| } // namespace Poco | ||||
|  | ||||
|  | ||||
| #endif // Foundation_SmallObjectAllocator_INCLUDED | ||||
		Reference in New Issue
	
	Block a user
	 aleks-f
					aleks-f