Last active
December 12, 2015 12:39
-
-
Save gchatelet/4773947 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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