From 5535faf3ccc19a3cb8034b1c0a498b5b0b4147ec Mon Sep 17 00:00:00 2001 From: joaquintides Date: Sat, 15 Oct 2022 18:56:46 +0200 Subject: [PATCH] introduced internal noshrink_reserve --- include/boost/unordered/detail/foa.hpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/include/boost/unordered/detail/foa.hpp b/include/boost/unordered/detail/foa.hpp index 2a9d812b..ec9450f6 100644 --- a/include/boost/unordered/detail/foa.hpp +++ b/include/boost/unordered/detail/foa.hpp @@ -1174,8 +1174,7 @@ public: if(al()!=x.al())reserve(0); copy_assign_if(al(),x.al()); }); - // TODO may shrink arrays and miss an opportunity for memory reuse - reserve(x.size()); + noshrink_reserve(x.size()); x.for_all_elements([this](value_type* p){ unchecked_insert(*p); }); @@ -1228,8 +1227,7 @@ public: * under noexcept(true) conditions. */ - // TODO may shrink arrays and miss an opportunity for memory reuse - reserve(x.size()); + noshrink_reserve(x.size()); BOOST_TRY{ /* This works because subsequent x.clear() does not depend on the * elements' values. @@ -1652,6 +1650,22 @@ private: ml=max_load(); } + void noshrink_reserve(std::size_t n) + { + /* used only on assignment after element clearance */ + BOOST_ASSERT(size_==0); + + auto c=std::size_t(std::ceil(static_cast(n)/mlf)); + if(c) c=size_policy::size(size_policy::size_index(c/N+1))*N-1; + + if(c>capacity()){ + auto new_arrays_=new_arrays(c); + delete_arrays(arrays); + arrays=new_arrays_; + ml=max_load(); + } + } + template void unchecked_insert(Value&& x) {