This commit is contained in:
Siarhei Fedartsou 2024-07-10 22:01:25 +02:00
parent 1037256a30
commit 6f04aa9587
2 changed files with 73 additions and 50 deletions

View File

@ -13,19 +13,18 @@ namespace osrm::util
{
#if 1
template <typename T, size_t MinItemsInBlock = 1024> class PoolAllocator
template <typename T, size_t MinItemsInBlock = 1024>
class PoolAllocator;
template <typename T, size_t MinItemsInBlock = 1024>
class MemoryManager
{
public:
using value_type = T;
PoolAllocator() noexcept = default;
template <typename U> PoolAllocator(const PoolAllocator<U> &) noexcept {}
template <typename U> struct rebind
static MemoryManager &instance()
{
using other = PoolAllocator<U, MinItemsInBlock>;
};
thread_local MemoryManager instance;
return instance;
}
T *allocate(std::size_t n)
{
@ -55,7 +54,7 @@ template <typename T, size_t MinItemsInBlock = 1024> class PoolAllocator
free_lists_[free_list_index].push_back(p);
}
~PoolAllocator()
~MemoryManager()
{
for (auto block : blocks_)
{
@ -63,44 +62,11 @@ template <typename T, size_t MinItemsInBlock = 1024> class PoolAllocator
}
}
PoolAllocator(const PoolAllocator &) = delete;
PoolAllocator &operator=(const PoolAllocator &) = delete;
PoolAllocator(PoolAllocator &&other) noexcept
: free_lists_(std::move(other.free_lists_)),
blocks_(std::move(other.blocks_)),
current_block_ptr_(other.current_block_ptr_),
current_block_left_items_(other.current_block_left_items_),
total_allocated_(other.total_allocated_)
{
other.current_block_ptr_ = nullptr;
other.current_block_left_items_ = 0;
other.total_allocated_ = 0;
}
PoolAllocator &operator=(PoolAllocator &&other) noexcept
{
if (this != &other)
{
for (auto block : blocks_)
{
std::free(block);
}
free_lists_ = std::move(other.free_lists_);
blocks_ = std::move(other.blocks_);
current_block_ptr_ = other.current_block_ptr_;
current_block_left_items_ = other.current_block_left_items_;
total_allocated_ = other.total_allocated_;
other.current_block_ptr_ = nullptr;
other.current_block_left_items_ = 0;
other.total_allocated_ = 0;
}
return *this;
}
private:
MemoryManager() = default;
MemoryManager(const MemoryManager &) = delete;
MemoryManager &operator=(const MemoryManager &) = delete;
size_t get_next_power_of_two_exponent(size_t n) const
{
BOOST_ASSERT(n > 0);
@ -131,6 +97,48 @@ private:
size_t total_allocated_ = 0;
};
template <typename T, size_t MinItemsInBlock>
class PoolAllocator
{
public:
using value_type = T;
PoolAllocator() noexcept = default;
template <typename U>
PoolAllocator(const PoolAllocator<U> &) noexcept {}
template <typename U>
struct rebind
{
using other = PoolAllocator<U, MinItemsInBlock>;
};
T *allocate(std::size_t n)
{
return MemoryManager<T, MinItemsInBlock>::instance().allocate(n);
}
void deallocate(T *p, std::size_t n) noexcept
{
MemoryManager<T, MinItemsInBlock>::instance().deallocate(p, n);
}
~PoolAllocator() = default;
PoolAllocator(const PoolAllocator &) = default;
PoolAllocator &operator=(const PoolAllocator &) = default;
PoolAllocator(PoolAllocator &&) noexcept = default;
PoolAllocator &operator=(PoolAllocator &&) noexcept = default;
private:
static size_t get_next_power_of_two_exponent(size_t n)
{
BOOST_ASSERT(n > 0);
return (sizeof(size_t) * 8) - std::countl_zero(n - 1);
}
};
template <typename T, typename U>
bool operator==(const PoolAllocator<T> &, const PoolAllocator<U> &)
{

View File

@ -57,6 +57,21 @@ BOOST_AUTO_TEST_CASE(copy)
pool2.deallocate(ptr, 1);
}
BOOST_AUTO_TEST_CASE(move)
{
PoolAllocator<int> pool;
auto ptr = pool.allocate(1);
*ptr = 42;
BOOST_CHECK_NE(ptr, nullptr);
pool.deallocate(ptr, 1);
PoolAllocator<int> pool2(std::move(pool));
ptr = pool2.allocate(1);
*ptr = 42;
BOOST_CHECK_NE(ptr, nullptr);
pool2.deallocate(ptr, 1);
}
BOOST_AUTO_TEST_CASE(unordered_map)
{
std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, PoolAllocator<std::pair<const int, int>>> map;