From 0b51fe2bce55991e608352954a2266f4702642bf Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 3 Feb 2022 08:21:41 +0000 Subject: [PATCH] 8271506: Add ResourceHashtable support for deleting selected entries Reviewed-by: stuefe Backport-of: f15d6cbcaf191b9718ab51b1e8b72938c0abdd6b --- src/hotspot/share/utilities/resourceHash.hpp | 26 +++++++++++++++++++ .../gtest/utilities/test_resourceHash.cpp | 24 +++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/hotspot/share/utilities/resourceHash.hpp b/src/hotspot/share/utilities/resourceHash.hpp index f56763f562d..cfd6a848e27 100644 --- a/src/hotspot/share/utilities/resourceHash.hpp +++ b/src/hotspot/share/utilities/resourceHash.hpp @@ -195,6 +195,32 @@ class ResourceHashtable : public ResourceObj { ++bucket; } } + + // ITER contains bool do_entry(K const&, V const&), which will be + // called for each entry in the table. If do_entry() returns true, + // the entry is deleted. + template + void unlink(ITER* iter) { + Node** bucket = const_cast(_table); + while (bucket < &_table[SIZE]) { + Node** ptr = bucket; + while (*ptr != NULL) { + Node* node = *ptr; + // do_entry must clean up the key and value in Node. + bool clean = iter->do_entry(node->_key, node->_value); + if (clean) { + *ptr = node->_next; + if (ALLOC_TYPE == ResourceObj::C_HEAP) { + delete node; + } + } else { + ptr = &(node->_next); + } + } + ++bucket; + } + } + }; diff --git a/test/hotspot/gtest/utilities/test_resourceHash.cpp b/test/hotspot/gtest/utilities/test_resourceHash.cpp index a10241a84f3..f9a8f090e30 100644 --- a/test/hotspot/gtest/utilities/test_resourceHash.cpp +++ b/test/hotspot/gtest/utilities/test_resourceHash.cpp @@ -60,6 +60,21 @@ class CommonResourceHashtableTest : public ::testing::Test { } }; + class DeleterTestIter { + int _val; + public: + DeleterTestIter(int i) : _val(i) {} + + bool do_entry(K const& k, V const& v) { + if ((uintptr_t) k == (uintptr_t) _val) { + // Delete me! + return true; + } else { + return false; // continue iteration + } + } + }; + }; class SmallResourceHashtableTest : public CommonResourceHashtableTest { @@ -233,6 +248,15 @@ class GenericResourceHashtableTest : public CommonResourceHashtableTest { ASSERT_FALSE(rh.remove(as_K(index))); } rh.iterate(&et); + + // Add more entries in and then delete one. + for (uintptr_t i = 10; i > 0; --i) { + uintptr_t index = i - 1; + ASSERT_TRUE(rh.put(as_K(index), index)); + } + DeleterTestIter dt(5); + rh.unlink(&dt); + ASSERT_FALSE(rh.get(as_K(5))); } }; };