src/share/vm/utilities/resourceHash.hpp

Wed, 22 Jan 2014 17:42:23 -0800

author
kvn
date
Wed, 22 Jan 2014 17:42:23 -0800
changeset 6503
a9becfeecd1b
parent 6461
bdd155477289
child 6876
710a3c8b516e
child 9845
68172de2a0d7
permissions
-rw-r--r--

Merge

kamg@4245 1 /*
kamg@4245 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
kamg@4245 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
kamg@4245 4 *
kamg@4245 5 * This code is free software; you can redistribute it and/or modify it
kamg@4245 6 * under the terms of the GNU General Public License version 2 only, as
kamg@4245 7 * published by the Free Software Foundation.
kamg@4245 8 *
kamg@4245 9 * This code is distributed in the hope that it will be useful, but WITHOUT
kamg@4245 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
kamg@4245 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kamg@4245 12 * version 2 for more details (a copy is included in the LICENSE file that
kamg@4245 13 * accompanied this code).
kamg@4245 14 *
kamg@4245 15 * You should have received a copy of the GNU General Public License version
kamg@4245 16 * 2 along with this work; if not, write to the Free Software Foundation,
kamg@4245 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
kamg@4245 18 *
kamg@4245 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
kamg@4245 20 * or visit www.oracle.com if you need additional information or have any
kamg@4245 21 * questions.
kamg@4245 22 *
kamg@4245 23 */
kamg@4245 24
kamg@4245 25 #ifndef SHARE_VM_UTILITIES_RESOURCEHASH_HPP
kamg@4245 26 #define SHARE_VM_UTILITIES_RESOURCEHASH_HPP
kamg@4245 27
kamg@4245 28 #include "memory/allocation.hpp"
kamg@4245 29 #include "utilities/top.hpp"
kamg@4245 30
kamg@4245 31 template<typename K> struct ResourceHashtableFns {
kamg@4245 32 typedef unsigned (*hash_fn)(K const&);
kamg@4245 33 typedef bool (*equals_fn)(K const&, K const&);
kamg@4245 34 };
kamg@4245 35
kamg@4245 36 template<typename K> unsigned primitive_hash(const K& k) {
kamg@4245 37 unsigned hash = (unsigned)((uintptr_t)k);
kamg@4245 38 return hash ^ (hash > 3); // just in case we're dealing with aligned ptrs
kamg@4245 39 }
kamg@4245 40
kamg@4245 41 template<typename K> bool primitive_equals(const K& k0, const K& k1) {
kamg@4245 42 return k0 == k1;
kamg@4245 43 }
kamg@4245 44
kamg@4245 45 template<
kamg@4245 46 typename K, typename V,
goetz@6461 47 // xlC does not compile this:
goetz@6461 48 // http://stackoverflow.com/questions/8532961/template-argument-of-type-that-is-defined-by-inner-typedef-from-other-template-c
goetz@6461 49 //typename ResourceHashtableFns<K>::hash_fn HASH = primitive_hash<K>,
goetz@6461 50 //typename ResourceHashtableFns<K>::equals_fn EQUALS = primitive_equals<K>,
goetz@6461 51 unsigned (*HASH) (K const&) = primitive_hash<K>,
goetz@6461 52 bool (*EQUALS)(K const&, K const&) = primitive_equals<K>,
kamg@4245 53 unsigned SIZE = 256
kamg@4245 54 >
kamg@4245 55 class ResourceHashtable : public ResourceObj {
kamg@4245 56 private:
kamg@4245 57
kamg@4245 58 class Node : public ResourceObj {
kamg@4245 59 public:
kamg@4245 60 unsigned _hash;
kamg@4245 61 K _key;
kamg@4245 62 V _value;
kamg@4245 63 Node* _next;
kamg@4245 64
kamg@4245 65 Node(unsigned hash, K const& key, V const& value) :
kamg@4245 66 _hash(hash), _key(key), _value(value), _next(NULL) {}
kamg@4245 67 };
kamg@4245 68
kamg@4245 69 Node* _table[SIZE];
kamg@4245 70
kamg@4245 71 // Returns a pointer to where the node where the value would reside if
kamg@4245 72 // it's in the table.
kamg@4245 73 Node** lookup_node(unsigned hash, K const& key) {
kamg@4245 74 unsigned index = hash % SIZE;
kamg@4245 75 Node** ptr = &_table[index];
kamg@4245 76 while (*ptr != NULL) {
kamg@4245 77 Node* node = *ptr;
kamg@4245 78 if (node->_hash == hash && EQUALS(key, node->_key)) {
kamg@4245 79 break;
kamg@4245 80 }
kamg@4245 81 ptr = &(node->_next);
kamg@4245 82 }
kamg@4245 83 return ptr;
kamg@4245 84 }
kamg@4245 85
kamg@4245 86 Node const** lookup_node(unsigned hash, K const& key) const {
kamg@4245 87 return const_cast<Node const**>(
kamg@4245 88 const_cast<ResourceHashtable*>(this)->lookup_node(hash, key));
kamg@4245 89 }
kamg@4245 90
kamg@4245 91 public:
kamg@4245 92 ResourceHashtable() { memset(_table, 0, SIZE * sizeof(Node*)); }
kamg@4245 93
kamg@4245 94 bool contains(K const& key) const {
kamg@4245 95 return get(key) != NULL;
kamg@4245 96 }
kamg@4245 97
kamg@4245 98 V* get(K const& key) const {
kamg@4245 99 unsigned hv = HASH(key);
kamg@4245 100 Node const** ptr = lookup_node(hv, key);
kamg@4245 101 if (*ptr != NULL) {
kamg@4245 102 return const_cast<V*>(&(*ptr)->_value);
kamg@4245 103 } else {
kamg@4245 104 return NULL;
kamg@4245 105 }
kamg@4245 106 }
kamg@4245 107
kamg@4245 108 // Inserts or replaces a value in the table
kamg@4245 109 void put(K const& key, V const& value) {
kamg@4245 110 unsigned hv = HASH(key);
kamg@4245 111 Node** ptr = lookup_node(hv, key);
kamg@4245 112 if (*ptr != NULL) {
kamg@4245 113 (*ptr)->_value = value;
kamg@4245 114 } else {
kamg@4245 115 *ptr = new Node(hv, key, value);
kamg@4245 116 }
kamg@4245 117 }
kamg@4245 118
kamg@4245 119 // ITER contains bool do_entry(K const&, V const&), which will be
kamg@4245 120 // called for each entry in the table. If do_entry() returns false,
kamg@4245 121 // the iteration is cancelled.
kamg@4245 122 template<class ITER>
kamg@4245 123 void iterate(ITER* iter) const {
kamg@4245 124 Node* const* bucket = _table;
kamg@4245 125 while (bucket < &_table[SIZE]) {
kamg@4245 126 Node* node = *bucket;
kamg@4245 127 while (node != NULL) {
kamg@4245 128 bool cont = iter->do_entry(node->_key, node->_value);
kamg@4245 129 if (!cont) { return; }
kamg@4245 130 node = node->_next;
kamg@4245 131 }
kamg@4245 132 ++bucket;
kamg@4245 133 }
kamg@4245 134 }
kamg@4245 135 };
kamg@4245 136
kamg@4245 137
kamg@4245 138 #endif // SHARE_VM_UTILITIES_RESOURCEHASH_HPP

mercurial