8291970: Add TableStatistics get function to ResourceHashtable
Reviewed-by: iklam, ccheung
This commit is contained in:
parent
cbc9040f3a
commit
f5b3618c42
@ -26,6 +26,8 @@
|
|||||||
#define SHARE_UTILITIES_RESOURCEHASH_HPP
|
#define SHARE_UTILITIES_RESOURCEHASH_HPP
|
||||||
|
|
||||||
#include "memory/allocation.hpp"
|
#include "memory/allocation.hpp"
|
||||||
|
#include "utilities/numberSeq.hpp"
|
||||||
|
#include "utilities/tableStatistics.hpp"
|
||||||
|
|
||||||
template<typename K, typename V>
|
template<typename K, typename V>
|
||||||
class ResourceHashtableNode : public ResourceObj {
|
class ResourceHashtableNode : public ResourceObj {
|
||||||
@ -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>
|
template<unsigned TABLE_SIZE, typename K, typename V>
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -91,7 +91,7 @@ TableStatistics::TableStatistics() :
|
|||||||
_add_rate(0), _remove_rate(0) {
|
_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),
|
_literal_bytes(literal_bytes),
|
||||||
_number_of_buckets(0), _number_of_entries(0),
|
_number_of_buckets(0), _number_of_entries(0),
|
||||||
_maximum_bucket_size(0), _average_bucket_size(0),
|
_maximum_bucket_size(0), _average_bucket_size(0),
|
||||||
@ -114,7 +114,12 @@ TableStatistics::TableStatistics(TableRateStatistics& rate_stats, NumberSeq summ
|
|||||||
|
|
||||||
_bucket_size = (_number_of_buckets <= 0) ? 0 : (_bucket_bytes / _number_of_buckets);
|
_bucket_size = (_number_of_buckets <= 0) ? 0 : (_bucket_bytes / _number_of_buckets);
|
||||||
_entry_size = (_number_of_entries <= 0) ? 0 : (_entry_bytes / _number_of_entries);
|
_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 INCLUDE_JFR
|
||||||
if (Jfr::is_recording()) {
|
if (Jfr::is_recording()) {
|
||||||
rate_stats.stamp();
|
rate_stats.stamp();
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -82,6 +82,7 @@ public:
|
|||||||
float _remove_rate;
|
float _remove_rate;
|
||||||
|
|
||||||
TableStatistics();
|
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(TableRateStatistics& rate_stats, NumberSeq summary, size_t literal_bytes, size_t bucket_bytes, size_t node_bytes);
|
||||||
~TableStatistics();
|
~TableStatistics();
|
||||||
|
|
||||||
|
@ -446,3 +446,46 @@ TEST_VM_F(ResourceHashtableDeleteTest, check_delete_ptr) {
|
|||||||
// Removal should make the refcount be the original refcount.
|
// Removal should make the refcount be the original refcount.
|
||||||
ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be as we started";
|
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);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user