Skip to content

Instantly share code, notes, and snippets.

@gchatelet
Last active December 12, 2015 12:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gchatelet/4773947 to your computer and use it in GitHub Desktop.
Save gchatelet/4773947 to your computer and use it in GitHub Desktop.
/*
* Pool.h
*
* Created on: Feb 12, 2013
* Author: Guillaume Chatelet
*/
#ifndef POOL_H_
#define POOL_H_
#include <functional>
#include <memory>
#include <map>
#include <stack>
namespace pool {
template<typename KEY, typename DATA>
struct PoolBase {
PoolBase() = default;
PoolBase(const PoolBase&) = delete;
PoolBase& operator=(const PoolBase&) = delete;
typedef KEY key_type;
typedef DATA value_type;
typedef std::shared_ptr<value_type> DataPtr;
typedef std::stack<DataPtr> DataStack;
typedef std::map<key_type, DataStack> PoolMap;
};
template<class BASE>
struct Pool: public BASE {
using typename BASE::DataPtr;
using typename BASE::key_type;
using typename BASE::value_type;
DataPtr get(const key_type &key) {
auto& stack = m_Pool[key];
if (!stack.empty()) {
DataPtr pData = std::move(stack.top());
stack.pop();
return pData;
}
return {BASE::evictAndCreate(key, m_Pool), recycleFunc()};
}
private:
void recycle(value_type* pData) {
m_Pool[BASE::retrieveKey(pData)].emplace(pData, recycleFunc());
}
inline std::function<void(value_type*)> recycleFunc() {
return std::bind(&Pool::recycle, this, std::placeholders::_1);
}
typename BASE::PoolMap m_Pool;
};
} // namespace pool
#endif /* POOL_H_ */
#include "Pool.h"
#include <cassert>
struct HeavyDuty {
HeavyDuty(size_t size) :
size(size) {
}
size_t size;
};
struct PoolPolicy: public ::pool::PoolBase<size_t, HeavyDuty> {
value_type* evictAndCreate(const key_type& key, PoolMap &map) {
++creationCount;
return new HeavyDuty(key);
}
key_type retrieveKey(const value_type* pData) {
return pData->size;
}
size_t creationCount = 0;
};
int main(int argc, char **argv) {
::pool::Pool<PoolPolicy> pool;
assert(pool.creationCount==0);
{
auto pData = pool.get(15); // create and recycle
assert(pool.creationCount==1);
}
{
auto pData = pool.get(15); // use recycled
assert(pool.creationCount==1);
}
{
auto pOne = pool.get(15); // use recycled
auto pTwo = pool.get(15); // create a new one
assert(pool.creationCount==2);
}
{
auto pData = pool.get(2); // create a new one
assert(pool.creationCount==3);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment