Skip to content

Commit

Permalink
8291970: Add TableStatistics get function to ResourceHashtable
Browse files Browse the repository at this point in the history
Reviewed-by: iklam, ccheung
  • Loading branch information
coleenp committed Aug 9, 2022
1 parent cbc9040 commit f5b3618
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 3 deletions.
22 changes: 22 additions & 0 deletions src/hotspot/share/utilities/resourceHash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#define SHARE_UTILITIES_RESOURCEHASH_HPP

#include "memory/allocation.hpp"
#include "utilities/numberSeq.hpp"
#include "utilities/tableStatistics.hpp"

template<typename K, typename V>
class ResourceHashtableNode : public ResourceObj {
Expand Down Expand Up @@ -259,6 +261,26 @@ class ResourceHashtableBase : public STORAGE {
}
}

template<typename Function>
TableStatistics statistics_calculate(Function size_function) const {
NumberSeq summary;
size_t literal_bytes = 0;
Node* const* bucket = table();
const unsigned sz = table_size();
while (bucket < bucket_at(sz)) {
Node* node = *bucket;
int count = 0;
while (node != NULL) {
literal_bytes += size_function(node->_key, node->_value);
count++;
node = node->_next;
}
summary.add((double)count);
++bucket;
}
return TableStatistics(summary, literal_bytes, sizeof(Node*), sizeof(Node));
}

};

template<unsigned TABLE_SIZE, typename K, typename V>
Expand Down
9 changes: 7 additions & 2 deletions src/hotspot/share/utilities/tableStatistics.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -91,7 +91,7 @@ TableStatistics::TableStatistics() :
_add_rate(0), _remove_rate(0) {
}

TableStatistics::TableStatistics(TableRateStatistics& rate_stats, NumberSeq summary, size_t literal_bytes, size_t bucket_bytes, size_t node_bytes) :
TableStatistics::TableStatistics(NumberSeq summary, size_t literal_bytes, size_t bucket_bytes, size_t node_bytes) :
_literal_bytes(literal_bytes),
_number_of_buckets(0), _number_of_entries(0),
_maximum_bucket_size(0), _average_bucket_size(0),
Expand All @@ -114,7 +114,12 @@ TableStatistics::TableStatistics(TableRateStatistics& rate_stats, NumberSeq summ

_bucket_size = (_number_of_buckets <= 0) ? 0 : (_bucket_bytes / _number_of_buckets);
_entry_size = (_number_of_entries <= 0) ? 0 : (_entry_bytes / _number_of_entries);
}

TableStatistics::TableStatistics(TableRateStatistics& rate_stats,
NumberSeq summary, size_t literal_bytes,
size_t bucket_bytes, size_t node_bytes) :
TableStatistics(summary, literal_bytes, bucket_bytes, node_bytes) {
#if INCLUDE_JFR
if (Jfr::is_recording()) {
rate_stats.stamp();
Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/utilities/tableStatistics.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -82,6 +82,7 @@ class TableStatistics : CHeapObj<mtStatistics> {
float _remove_rate;

TableStatistics();
TableStatistics(NumberSeq summary, size_t literal_bytes, size_t bucket_bytes, size_t node_bytes);
TableStatistics(TableRateStatistics& rate_stats, NumberSeq summary, size_t literal_bytes, size_t bucket_bytes, size_t node_bytes);
~TableStatistics();

Expand Down
43 changes: 43 additions & 0 deletions test/hotspot/gtest/utilities/test_resourceHash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,3 +446,46 @@ TEST_VM_F(ResourceHashtableDeleteTest, check_delete_ptr) {
// Removal should make the refcount be the original refcount.
ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be as we started";
}

class ResourceHashtablePrintTest : public ::testing::Test {
public:
class TestValue {
int _i;
int _j;
int _k;
public:
TestValue(int i) : _i(i), _j(i+1), _k(i+2) {}
};
ResourceHashtable<int, TestValue*, 30, ResourceObj::C_HEAP, mtTest> _test_table;

class TableDeleter {
public:
bool do_entry(int& key, TestValue*& val) {
delete val;
return true;
}
};
};

TEST_VM_F(ResourceHashtablePrintTest, print_test) {
for (int i = 0; i < 300; i++) {
TestValue* tv = new TestValue(i);
_test_table.put(i, tv); // all the entries can be the same.
}
auto printer = [&] (int& key, TestValue*& val) {
return sizeof(*val);
};
TableStatistics ts = _test_table.statistics_calculate(printer);
ResourceMark rm;
stringStream st;
ts.print(&st, "TestTable");
// Verify output in string
const char* strings[] = {
"Number of buckets", "Number of entries", "300", "Number of literals", "Average bucket size", "Maximum bucket size" };
for (const auto& str : strings) {
ASSERT_TRUE(strstr(st.as_string(), str) != nullptr) << "string not present " << str;
}
// Cleanup: need to delete pointers in entries
TableDeleter deleter;
_test_table.unlink(&deleter);
}

1 comment on commit f5b3618

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.