< 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 >