blob: b4dfc4f6240e15215f4049421a98defb8929bd58 [file] [edit]
/*
* Copyright (c) 2025, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_JFR_UTILITIES_JFRSET_HPP
#define SHARE_JFR_UTILITIES_JFRSET_HPP
#include "jfr/utilities/jfrAllocation.hpp"
#include "jfr/utilities/jfrTypes.hpp"
#include "utilities/resizeableResourceHash.hpp"
template <typename AllocPolicy = JfrCHeapObj, AnyObj::allocation_type AllocType = AnyObj::C_HEAP, MemTag memtag = mtTracing>
class ConfigTraceID : public AllStatic {
public:
typedef AllocPolicy STORAGE;
typedef traceid TYPE;
constexpr static AnyObj::allocation_type alloc_type() {
return AllocType;
}
constexpr static MemTag memory_tag() {
return memtag;
}
// Knuth multiplicative hashing.
static uint32_t hash(const TYPE& id) {
const uint32_t v = static_cast<uint32_t>(id);
return v * UINT32_C(2654435761);
}
static bool cmp(const TYPE& lhs, const TYPE& rhs) {
return lhs == rhs;
}
};
constexpr static unsigned int MAX_TABLE_SIZE = 0x3fffffff;
template <typename CONFIG>
class JfrSet : public CONFIG::STORAGE {
public:
typedef typename CONFIG::TYPE TYPE;
typedef ResizeableResourceHashtable<TYPE, TYPE, CONFIG::alloc_type(), CONFIG::memory_tag(), CONFIG::hash, CONFIG::cmp> HashMap;
constexpr static bool is_cheap() {
return CONFIG::alloc_type() == AnyObj::C_HEAP;
}
JfrSet(unsigned int initial_size, unsigned int max_size = MAX_TABLE_SIZE) :
_map(is_cheap() ? new (CONFIG::memory_tag()) HashMap(initial_size, max_size) : new HashMap(initial_size, max_size)) {}
~JfrSet() {
if (is_cheap()) {
delete _map;
}
}
bool add(const TYPE& k) {
bool inserted;
_map->put_if_absent(k, &inserted);
return inserted;
}
bool remove(const TYPE& k) {
return _map->remove(k);
}
bool contains(const TYPE& k) const {
return _map->contains(k);
}
bool is_empty() const {
return _map->number_of_entries() == 0;
}
bool is_nonempty() const {
return !is_empty();
}
int size() const {
return _map->number_of_entries();
}
void clear() {
if (is_nonempty()) {
_map->unlink(this);
}
assert(is_empty(), "invariant");
}
// Callback for node deletion, used by clear().
bool do_entry(const TYPE& k, const TYPE& v) {
return true;
}
private:
HashMap* _map;
};
typedef JfrSet<ConfigTraceID<> > JfrCHeapTraceIdSet;
typedef JfrSet<ConfigTraceID<ResourceObj, AnyObj::RESOURCE_AREA> > JfrResourceAreaTraceIdSet;
#endif // SHARE_JFR_UTILITIES_JFRSET_HPP