diff --git a/nano/core_test/block.cpp b/nano/core_test/block.cpp index fb6cc53bc1..ac0450595b 100644 --- a/nano/core_test/block.cpp +++ b/nano/core_test/block.cpp @@ -6,8 +6,6 @@ #include -#include - #include TEST (ed25519, signing) @@ -591,14 +589,17 @@ TEST (block_uniquer, cleanup) .build_shared (); nano::block_uniquer uniquer; - auto block3 = uniquer.unique (block1); - auto block4 = uniquer.unique (block2); + auto block3 (uniquer.unique (block1)); + auto block4 (uniquer.unique (block2)); block2.reset (); block4.reset (); ASSERT_EQ (2, uniquer.size ()); - std::this_thread::sleep_for (nano::block_uniquer::cleanup_cutoff); - auto block5 = uniquer.unique (block1); - ASSERT_EQ (1, uniquer.size ()); + auto iterations (0); + while (uniquer.size () == 2) + { + auto block5 (uniquer.unique (block1)); + ASSERT_LT (iterations++, 200); + } } TEST (block_builder, from) diff --git a/nano/lib/blocks.cpp b/nano/lib/blocks.cpp index 8076a400a8..fab4c2466b 100644 --- a/nano/lib/blocks.cpp +++ b/nano/lib/blocks.cpp @@ -1881,19 +1881,24 @@ std::shared_ptr nano::block_uniquer::unique (std::shared_ptr::max () > blocks.size ()); + for (auto i (0); i < cleanup_count && !blocks.empty (); ++i) { - cleanup_last = now; - for (auto i = blocks.begin (), n = blocks.end (); i != n;) + auto random_offset (nano::random_pool::generate_word32 (0, static_cast (blocks.size () - 1))); + auto existing (std::next (blocks.begin (), random_offset)); + if (existing == blocks.end ()) { - if (auto block_l = i->second.lock ()) + existing = blocks.begin (); + } + if (existing != blocks.end ()) + { + if (auto block_l = existing->second.lock ()) { - ++i; + // Still live } else { - i = blocks.erase (i); + blocks.erase (existing); } } } diff --git a/nano/lib/blocks.hpp b/nano/lib/blocks.hpp index 3b779fa63c..abfb6521ca 100644 --- a/nano/lib/blocks.hpp +++ b/nano/lib/blocks.hpp @@ -413,10 +413,7 @@ class block_uniquer private: nano::mutex mutex{ mutex_identifier (mutexes::block_uniquer) }; std::unordered_map, value_type::second_type> blocks; - std::chrono::steady_clock::time_point cleanup_last{ std::chrono::steady_clock::now () }; - -public: - static std::chrono::milliseconds constexpr cleanup_cutoff{ 500 }; + static unsigned constexpr cleanup_count = 2; }; std::unique_ptr collect_container_info (block_uniquer & block_uniquer, std::string const & name);