< prev index next >
src/hotspot/share/utilities/hashtable.hpp
Print this page
@@ -23,11 +23,10 @@
*/
#ifndef SHARE_VM_UTILITIES_HASHTABLE_HPP
#define SHARE_VM_UTILITIES_HASHTABLE_HPP
-#include "classfile/classLoaderData.hpp"
#include "memory/allocation.hpp"
#include "oops/oop.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.hpp"
@@ -231,10 +230,20 @@
int number_of_entries() const { return _number_of_entries; }
bool resize(int new_size);
+ // Grow the number of buckets if the average entries per bucket is over the load_factor
+ bool maybe_grow(int load_factor = 8) {
+ if (number_of_entries() / table_size() > load_factor) {
+ resize(table_size() * 2);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
template <class T> void verify_table(const char* table_name) PRODUCT_RETURN;
};
template <class T, MEMFLAGS F> class Hashtable : public BasicHashtable<F> {
@@ -277,6 +286,58 @@
HashtableEntry<T, F>** bucket_addr(int i) {
return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
}
};
+// A subclass of BasicHashtable that allows you to do a simple K -> V mapping
+// without using tons of boilerplate code.
+template<
+ typename K, typename V,
+ MEMFLAGS F = mtInternal,
+ unsigned (*HASH) (K const&) = primitive_hash<K>,
+ bool (*EQUALS)(K const&, K const&) = primitive_equals<K>
+ >
+class KVHashtable : public BasicHashtable<F> {
+ class KVHashtableEntry : public BasicHashtableEntry<F> {
+ public:
+ K _key;
+ V _value;
+ KVHashtableEntry* next() {
+ return (KVHashtableEntry*)BasicHashtableEntry<F>::next();
+ }
+ };
+
+protected:
+ KVHashtableEntry* bucket(int i) const {
+ return (KVHashtableEntry*)BasicHashtable<F>::bucket(i);
+ }
+
+ KVHashtableEntry* new_entry(unsigned int hashValue, K key, V value) {
+ KVHashtableEntry* entry = (KVHashtableEntry*)BasicHashtable<F>::new_entry(hashValue);
+ entry->_key = key;
+ entry->_value = value;
+ return entry;
+ }
+
+public:
+ KVHashtable(int table_size) : BasicHashtable<F>(table_size, sizeof(KVHashtableEntry)) {}
+
+ void add(K key, V value) {
+ unsigned int hash = HASH(key);
+ KVHashtableEntry* entry = new_entry(hash, key, value);
+ BasicHashtable<F>::add_entry(BasicHashtable<F>::hash_to_index(hash), entry);
+ }
+
+ V* lookup(K key) {
+ unsigned int hash = HASH(key);
+ int index = BasicHashtable<F>::hash_to_index(hash);
+ for (KVHashtableEntry* e = bucket(index); e != NULL; e = e->next()) {
+ if (e->hash() == hash && e->_key == key) {
+ return &(e->_value);
+ }
+ }
+ return NULL;
+ }
+};
+
+
#endif // SHARE_VM_UTILITIES_HASHTABLE_HPP
< prev index next >