From bfbbfc325f081d9523f56accc267167c82ffa495 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 19 Mar 2023 18:20:49 +0100 Subject: src/rtree: add simple object pool impl --- src/RTree.cpp | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/RTree.h | 13 ++++++------- src/RTree.hpp | 28 ++++++++++++++++++++++----- 3 files changed, 90 insertions(+), 12 deletions(-) diff --git a/src/RTree.cpp b/src/RTree.cpp index 81677922..bee4641c 100644 --- a/src/RTree.cpp +++ b/src/RTree.cpp @@ -1,3 +1,64 @@ +#define RTREE_NO_EXTERN_TEMPLATE_POOL #include "RTree.hpp" +//#define RTREE_POOL_DEBUG + +#ifdef RTREE_POOL_DEBUG +#include +#include +#include +#endif + +namespace floormat::detail { + +template rtree_pool::rtree_pool() +{ + free_list.reserve(128); +} + +template rtree_pool::~rtree_pool() +{ + for (auto* ptr : free_list) + ::operator delete(ptr); + free_list.clear(); + free_list.shrink_to_fit(); +} + +template T* rtree_pool::construct() +{ + if (free_list.empty()) + { +#ifdef RTREE_POOL_DEBUG + static unsigned i = 0; Debug{} << "rtree-pool: fresh"_s << ++i; std::fflush(stdout); +#endif + return new T; + } + else + { + auto* ret = free_list.back(); + free_list.pop_back(); + new (ret) T(); +#ifdef RTREE_POOL_DEBUG + static unsigned i = 0; Debug{} << "rtree-pool: reused"_s << ++i; std::fflush(stdout); +#endif + return ret; + } +} + +template void rtree_pool::free(T* ptr) +{ + ptr->~T(); + free_list.push_back(ptr); +} + +using my_rtree = RTree; + +template<> std::vector rtree_pool::free_list = {}; // NOLINT +template<> std::vector rtree_pool::free_list = {}; // NOLINT + +template struct floormat::detail::rtree_pool; +template struct floormat::detail::rtree_pool; + +} // namespace floormat::detail + template class RTree; diff --git a/src/RTree.h b/src/RTree.h index 9ef66f34..1a30a735 100644 --- a/src/RTree.h +++ b/src/RTree.h @@ -17,15 +17,16 @@ // RTree.h // -#define RTREE_DONT_USE_MEMPOOLS // This version does not contain a fixed memory allocator, fill in lines with EXAMPLE to implement one. +//#define RTREE_DONT_USE_MEMPOOLS // This version does not contain a fixed memory allocator, fill in lines with EXAMPLE to implement one. #define RTREE_USE_SPHERICAL_VOLUME // Better split classification, may be slower on some systems +namespace floormat::detail { template struct rtree_pool; } + #ifdef RTREE_STDIO // Fwd decl class RTFileStream; // File I/O helper class, look below for implementation and notes. #endif - /// \class RTree /// Implementation of RTree, a multidimensional bounding rectangle tree. /// Example usage: For a 3-dimensional tree use RTree myTree; @@ -47,11 +48,10 @@ template struct rtree_pool final +{ + rtree_pool(); + ~rtree_pool(); + static T* construct(); + static void free(T* pool); + +private: + static std::vector free_list; // NOLINT +}; + +#ifndef RTREE_NO_EXTERN_TEMPLATE_POOL +extern template struct rtree_pool::Node>; +extern template struct rtree_pool::ListNode>; +#endif +} // namespace floormat::detail + #ifdef RTREE_STDIO // Because there is not stream support, this is a quick and dirty file I/O helper. // Users will likely replace its usage with a Stream implementation from their favorite API. @@ -508,7 +526,7 @@ void RTREE_QUAL::RemoveAll() RTREE_TEMPLATE void RTREE_QUAL::Reset() { -#ifdef RTREE_DONT_USE_MEMPOOLS +#if defined RTREE_DONT_USE_MEMPOOLS || 1 // Delete all existing nodes RemoveAllRec(m_root); #else // RTREE_DONT_USE_MEMPOOLS @@ -542,7 +560,7 @@ typename RTREE_QUAL::Node* RTREE_QUAL::AllocNode() #ifdef RTREE_DONT_USE_MEMPOOLS newNode = new Node; #else // RTREE_DONT_USE_MEMPOOLS - // EXAMPLE + newNode = floormat::detail::rtree_pool::construct(); #endif // RTREE_DONT_USE_MEMPOOLS InitNode(newNode); return newNode; @@ -557,7 +575,7 @@ void RTREE_QUAL::FreeNode(Node* a_node) #ifdef RTREE_DONT_USE_MEMPOOLS delete a_node; #else // RTREE_DONT_USE_MEMPOOLS - // EXAMPLE + floormat::detail::rtree_pool::free(a_node); #endif // RTREE_DONT_USE_MEMPOOLS } @@ -570,7 +588,7 @@ typename RTREE_QUAL::ListNode* RTREE_QUAL::AllocListNode() #ifdef RTREE_DONT_USE_MEMPOOLS return new ListNode; #else // RTREE_DONT_USE_MEMPOOLS - // EXAMPLE + return floormat::detail::rtree_pool::construct(); #endif // RTREE_DONT_USE_MEMPOOLS } @@ -581,7 +599,7 @@ void RTREE_QUAL::FreeListNode(ListNode* a_listNode) #ifdef RTREE_DONT_USE_MEMPOOLS delete a_listNode; #else // RTREE_DONT_USE_MEMPOOLS - // EXAMPLE + floormat::detail::rtree_pool::free(a_listNode); #endif // RTREE_DONT_USE_MEMPOOLS } -- cgit v1.2.3