2015-12-06 23:42:47 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
#include <queue>
|
|
|
|
|
|
|
|
#include "threading/sync/lockable.hpp"
|
|
|
|
#include "threading/sync/spinlock.hpp"
|
|
|
|
|
|
|
|
template <class T, class Allocator=std::allocator<T>>
|
2015-12-08 04:50:07 +08:00
|
|
|
class Recycler : public Lockable<SpinLock>
|
2015-12-06 23:42:47 +08:00
|
|
|
{
|
|
|
|
static constexpr size_t default_max_reserved = 100;
|
|
|
|
|
|
|
|
public:
|
|
|
|
Recycler() = default;
|
|
|
|
Recycler(size_t max_reserved) : max_reserved(max_reserved) {}
|
|
|
|
|
|
|
|
template <class... Args>
|
|
|
|
T* acquire(Args&&... args)
|
|
|
|
{
|
|
|
|
auto guard = acquire_unique();
|
2015-12-08 04:50:07 +08:00
|
|
|
return fetch_or_create(std::forward<Args>(args)...);
|
2015-12-06 23:42:47 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void release(T* item)
|
|
|
|
{
|
|
|
|
auto guard = acquire_unique();
|
2015-12-08 04:50:07 +08:00
|
|
|
return recycle_or_delete(item);
|
2015-12-06 23:42:47 +08:00
|
|
|
}
|
|
|
|
|
2015-12-08 04:50:07 +08:00
|
|
|
protected:
|
2015-12-06 23:42:47 +08:00
|
|
|
Allocator alloc;
|
|
|
|
size_t max_reserved {default_max_reserved};
|
|
|
|
std::queue<T*> items;
|
2015-12-08 04:50:07 +08:00
|
|
|
|
|
|
|
template <class... Args>
|
|
|
|
T* fetch_or_create(Args&&... args)
|
|
|
|
{
|
|
|
|
return new T(std::forward<Args>(args)...); // todo refactor :D
|
|
|
|
}
|
|
|
|
|
|
|
|
void recycle_or_delete(T* item)
|
|
|
|
{
|
|
|
|
delete item; // todo refactor :D
|
|
|
|
}
|
2015-12-06 23:42:47 +08:00
|
|
|
};
|