summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-03-23 22:29:05 +0100
committerStanislaw Halik <sthalik@misaki.pl>2023-03-23 23:58:20 +0100
commita3762299ba5416ae2f85df2fb27b262d088a1e06 (patch)
tree1c64488d390b65399773b3a955dd58921b1f7055 /src
parentf253663d63233caf1b030b224de94d040141f1cf (diff)
src/rtree: store free nodes as linked list
Diffstat (limited to 'src')
-rw-r--r--src/RTree.cpp63
-rw-r--r--src/RTree.h31
-rw-r--r--src/RTree.hpp18
3 files changed, 72 insertions, 40 deletions
diff --git a/src/RTree.cpp b/src/RTree.cpp
index bee4641c..40343e31 100644
--- a/src/RTree.cpp
+++ b/src/RTree.cpp
@@ -11,53 +11,68 @@
namespace floormat::detail {
-template<typename T> rtree_pool<T>::rtree_pool()
-{
- free_list.reserve(128);
-}
+#ifdef RTREE_POOL_DEBUG
+static size_t fresh_counter, reuse_counter, dtor_counter; // NOLINT
+#endif
+
+template<typename T> rtree_pool<T>::rtree_pool() noexcept = default;
-template<typename T> rtree_pool<T>::~rtree_pool()
+template<typename T>
+rtree_pool<T>::~rtree_pool()
{
- for (auto* ptr : free_list)
- ::operator delete(ptr);
- free_list.clear();
- free_list.shrink_to_fit();
+#ifdef RTREE_POOL_DEBUG
+ auto last = dtor_counter;
+#endif
+ while (free_list)
+ {
+#ifdef RTREE_POOL_DEBUG
+ ++dtor_counter;
+#endif
+ auto* p = free_list;
+ free_list = free_list->next;
+ p->data.~T();
+ delete p;
+ }
+#ifdef RTREE_POOL_DEBUG
+ if (dtor_counter != last) { Debug{} << "rtree-pool: dtor" << dtor_counter; std::fflush(stdout); }
+#endif
}
template<typename T> T* rtree_pool<T>::construct()
{
- if (free_list.empty())
+ if (!free_list)
{
#ifdef RTREE_POOL_DEBUG
- static unsigned i = 0; Debug{} << "rtree-pool: fresh"_s << ++i; std::fflush(stdout);
+ Debug{} << "rtree-pool: fresh"_s << ++fresh_counter; std::fflush(stdout);
#endif
- return new T;
+ auto* ptr = new node_u;
+ auto* ret = new(&ptr->data) T;
+ return ret;
}
else
{
- auto* ret = free_list.back();
- free_list.pop_back();
- new (ret) T();
+ auto* ret = free_list;
+ free_list = free_list->next;
+ new (&ret->data) T();
#ifdef RTREE_POOL_DEBUG
- static unsigned i = 0; Debug{} << "rtree-pool: reused"_s << ++i; std::fflush(stdout);
+ Debug{} << "rtree-pool: reused"_s << ++reuse_counter; std::fflush(stdout);
#endif
- return ret;
+ return &ret->data;
}
}
template<typename T> void rtree_pool<T>::free(T* ptr)
{
ptr->~T();
- free_list.push_back(ptr);
+ node_p p = {.ptr = ptr };
+ node_u* n = p.data_ptr;
+ n->next = free_list;
+ free_list = n;
}
using my_rtree = RTree<uint64_t, float, 2, float>;
-
-template<> std::vector<my_rtree::Node*> rtree_pool<my_rtree::Node>::free_list = {}; // NOLINT
-template<> std::vector<my_rtree::ListNode*> rtree_pool<my_rtree::ListNode>::free_list = {}; // NOLINT
-
-template struct floormat::detail::rtree_pool<my_rtree::Node>;
-template struct floormat::detail::rtree_pool<my_rtree::ListNode>;
+template struct rtree_pool<my_rtree::Node>;
+template struct rtree_pool<my_rtree::ListNode>;
} // namespace floormat::detail
diff --git a/src/RTree.h b/src/RTree.h
index 1a30a735..3ceb64ac 100644
--- a/src/RTree.h
+++ b/src/RTree.h
@@ -22,6 +22,28 @@
namespace floormat::detail { template<typename T> struct rtree_pool; }
+template<typename T> struct floormat::detail::rtree_pool final
+{
+ rtree_pool() noexcept;
+ rtree_pool(const rtree_pool&) = delete;
+ rtree_pool& operator=(const rtree_pool&) = delete;
+ ~rtree_pool();
+ T* construct();
+ void free(T* pool);
+
+ union node_u {
+ union { T data; };
+ node_u* next;
+ };
+ union node_p {
+ T* ptr;
+ node_u* data_ptr;
+ };
+
+private:
+ node_u* free_list = nullptr;
+};
+
#ifdef RTREE_STDIO
// Fwd decl
class RTFileStream; // File I/O helper class, look below for implementation and notes.
@@ -45,7 +67,7 @@ class RTFileStream; // File I/O helper class, look below for implementation and
///
template<class DATATYPE, class ELEMTYPE, int NUMDIMS,
class ELEMTYPEREAL = ELEMTYPE, int TMAXNODES = 8, int TMINNODES = TMAXNODES / 2>
-class RTree
+class RTree final
{
public:
@@ -65,7 +87,7 @@ public:
RTree();
RTree(const RTree& other);
- virtual ~RTree() noexcept;
+ ~RTree() noexcept;
RTree& operator=(const RTree&);
/// Insert entry
@@ -212,6 +234,9 @@ public:
Node* m_node; ///< Node
};
+ floormat::detail::rtree_pool<Node> node_pool;
+ floormat::detail::rtree_pool<ListNode> list_node_pool;
+
protected:
/// Variables for finding a split partition
struct PartitionVars
@@ -278,6 +303,8 @@ public:
};
extern template class RTree<floormat::uint64_t, float, 2, float>;
+extern template struct floormat::detail::rtree_pool<RTree<floormat::uint64_t, float, 2, float>::Node>;
+extern template struct floormat::detail::rtree_pool<RTree<floormat::uint64_t, float, 2, float>::ListNode>;
//#undef RTREE_TEMPLATE
//#undef RTREE_QUAL
diff --git a/src/RTree.hpp b/src/RTree.hpp
index 45cbb378..046c5e1d 100644
--- a/src/RTree.hpp
+++ b/src/RTree.hpp
@@ -4,7 +4,6 @@
#include <math.h>
#include <stdlib.h>
-#include <cassert>
#include <limits>
#include <algorithm>
@@ -33,16 +32,7 @@
#endif //Max
namespace floormat::detail {
-template<typename T> struct rtree_pool final
-{
- rtree_pool();
- ~rtree_pool();
- static T* construct();
- static void free(T* pool);
-private:
- static std::vector<T*> free_list; // NOLINT
-};
#ifndef RTREE_NO_EXTERN_TEMPLATE_POOL
extern template struct rtree_pool<RTree<std::uint64_t, float, 2, float>::Node>;
@@ -560,7 +550,7 @@ typename RTREE_QUAL::Node* RTREE_QUAL::AllocNode()
#ifdef RTREE_DONT_USE_MEMPOOLS
newNode = new Node;
#else // RTREE_DONT_USE_MEMPOOLS
- newNode = floormat::detail::rtree_pool<Node>::construct();
+ newNode = node_pool.construct();
#endif // RTREE_DONT_USE_MEMPOOLS
InitNode(newNode);
return newNode;
@@ -575,7 +565,7 @@ void RTREE_QUAL::FreeNode(Node* a_node)
#ifdef RTREE_DONT_USE_MEMPOOLS
delete a_node;
#else // RTREE_DONT_USE_MEMPOOLS
- floormat::detail::rtree_pool<Node>::free(a_node);
+ node_pool.free(a_node);
#endif // RTREE_DONT_USE_MEMPOOLS
}
@@ -588,7 +578,7 @@ typename RTREE_QUAL::ListNode* RTREE_QUAL::AllocListNode()
#ifdef RTREE_DONT_USE_MEMPOOLS
return new ListNode;
#else // RTREE_DONT_USE_MEMPOOLS
- return floormat::detail::rtree_pool<ListNode>::construct();
+ return list_node_pool.construct();
#endif // RTREE_DONT_USE_MEMPOOLS
}
@@ -599,7 +589,7 @@ void RTREE_QUAL::FreeListNode(ListNode* a_listNode)
#ifdef RTREE_DONT_USE_MEMPOOLS
delete a_listNode;
#else // RTREE_DONT_USE_MEMPOOLS
- floormat::detail::rtree_pool<ListNode>::free(a_listNode);
+ list_node_pool.free(a_listNode);
#endif // RTREE_DONT_USE_MEMPOOLS
}