< prev index next > src/hotspot/share/utilities/resourceHash.hpp
Print this page
ResourceHashtableBase(unsigned size) : STORAGE(size), _number_of_entries(0) {}
NONCOPYABLE(ResourceHashtableBase);
~ResourceHashtableBase() {
if (ALLOC_TYPE == AnyObj::C_HEAP) {
- Node* const* bucket = table();
- const unsigned sz = table_size();
- while (bucket < bucket_at(sz)) {
- Node* node = *bucket;
- while (node != nullptr) {
- Node* cur = node;
- node = node->_next;
- delete cur;
- }
- ++bucket;
- }
+ unlink_all();
}
}
public:
unsigned table_size() const { return STORAGE::table_size(); }
// called for each entry in the table. If do_entry() returns true,
// the entry is deleted.
template<class ITER>
void unlink(ITER* iter) {
const unsigned sz = table_size();
- for (unsigned index = 0; index < sz; index++) {
+ int cnt = _number_of_entries;
+
+ for (unsigned index = 0; cnt > 0 && index < sz; ++index) {
Node** ptr = bucket_at(index);
+
while (*ptr != nullptr) {
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) {
}
_number_of_entries --;
} else {
ptr = &(node->_next);
}
+ if (--cnt <= 0) return;
+ }
+ }
+ }
+
+ // unlink_all() is a specialized version of unlink() when we decide to remove all elements.
+ // It can not replace unlink(ITER* iter) if user-provided iter releases key/value
+ void unlink_all() {
+ Node** bucket = table();
+ const unsigned sz = table_size();
+
+ while (_number_of_entries > 0 && bucket < bucket_at(sz)) {
+ Node* node = *bucket;
+ int n = 0;
+
+ while (node != NULL) {
+ Node* cur = node;
+ node = node->_next;
+ if (ALLOC_TYPE == AnyObj::C_HEAP) {
+ delete cur;
+ }
+ n++;
}
+
+ if (n > 0) {
+ *bucket = nullptr;
+ _number_of_entries -= n;
+ }
+ bucket++;
}
+
+ assert(_number_of_entries == 0, "sanity check");
}
template<typename Function>
TableStatistics statistics_calculate(Function size_function) const {
NumberSeq summary;
< prev index next >