Std::allocator:Pool
lastmod 2018-08-17created 2016-12-012 edits
The STL provides container objects that can manage objects. When we use an object pool, if we can get help from the STL, we can use a pool that is more usable and easier to manage. When the STL receives and stores a new object, it generally copies the target object to store it, and when releasing, it calls the object's destructor. If we can change this behavior to match our pool, applying a pool to the STL is not just a dream. But changing the STL's internal behavior would mean touching the library, and somewhere in the back of your mind a voice asks, "Is this okay?" As if it understood our concern, the STL provides an API for customizing how it allocates objects it receives and frees them when they are removed. This is the STL Custom Allocator.
STL Allocator usage
There are requirements you must follow when implementing a Custom Allocator.
- A CustomAllocator must be implemented as a template.
- The pointer and reference types must be defined with typedef.
- An allocator cannot have member variables. (stateless functor)
- The rebind template is required. Probably because rebind is used instead of the allocator when reallocation is needed...
STL Allocator example code
Allocator Template using a memory pool:
//템플릿으로 작성할 것
template <class T>
class STLAllocator
{
public:
STLAllocator() = default;
//필요한 타입 정의들...
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
//복사 생성자
template <class U>
STLAllocator(const STLAllocator<U>&)
{}
//rebind 템플릿
template <class U>
struct rebind
{
typedef STLAllocator<U> other;
};
void construct(pointer p, const T& t)
{
//replace new (할당하지 않고 생성자만 호출)
new(p)T(t);
}
void destroy(pointer p)
{
//replace delete (해제하지 않고 소멸자만 호출)
p->~T();
}
//할당시 호출되는 함수
T* allocate(size_t n)
{
//메모리 풀에서 할당요청
return GMemoryPool->Allocate(n);
}
//해제시 호출되는 함수
void deallocate(T* ptr, size_t n)
{
//메모리풀에 반납요청
GMemoryPool->Deallocate(ptr, n);
}
};
Applying the Allocator to the STL:
//Allocator를 적용한 새로운 X-STL
template <class T>
struct xvector
{
typedef std::vector<T, STLAllocator<T>> type;
};
template <class T>
struct xdeque
{
typedef std::deque<T, STLAllocator<T>> type;
};
template <class T>
struct xlist
{
typedef std::list<T, STLAllocator<T>> type;
};
template <class K, class T, class C = std::less<K> >
struct xmap
{
typedef std::map<K, T, C, STLAllocator<std::pair<K,T>>> type;
};
template <class T, class C = std::less<T> >
struct xset
{
typedef std::set<T, C , STLAllocator<T>> type;
};
template <class K, class T, class C = std::hash_compare<K, std::less<K>> >
struct xhash_map
{
typedef std::hash_map<K, T, C, STLAllocator<std::pair<K, T>> > type;
};
template <class T, class C = std::hash_compare<T, std::less<T>> >
struct xhash_set
{
typedef std::hash_set<T, C, STLAllocator<T> > type;
};
template <class T, class C = std::less<std::vector<T>::value_type> >
struct xpriority_queue
{
typedef std::priority_queue<T, std::vector<T, STLAllocator<T>>, C > type;
};
typedef std::basic_string<wchar_t, std::char_traits<wchar_t>, STLAllocator<wchar_t>> xstring;
//실제 적용사례
//typedef ::type으로 X-STL의 타입을 받아 사용한다.
typedef xlist<ClientSession*>::type ClientList;
ClientList mFreeSessionList;
See also
Favorite site
- [Recommended] Study notes :: Pooling (memory pool, object pool, STL pooling)
- https://github.com/zeliard/GSP