Path: blob/master/runtime/compiler/ras/HashTable.hpp
6000 views
/*******************************************************************************1* Copyright (c) 2000, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#ifndef HASHTABLE_INCL23#define HASHTABLE_INCL2425#include <stddef.h>26#include <stdint.h>27#include "env/jittypes.h"28#include "infra/Assert.hpp"2930class TR_Memory;3132#define MINIMUM_HASHTABLE_SIZE 163334typedef uint32_t TR_HashIndex;35typedef uintptr_t TR_HashCode;3637class TR_HashTableEntry38{39public:4041TR_HashTableEntry() {}4243TR_HashTableEntry(void *key, void *data, TR_HashCode hashCode)44: _key(key),45_data(data),46_hashCode(hashCode),47_chain(0) {}4849TR_HashTableEntry(const TR_HashTableEntry &entry)50: _key(entry._key),51_data(entry._data),52_hashCode(entry._hashCode),53_chain(entry._chain) {}5455void *operator new[](size_t size, TR_Memory *m);56void *operator new(size_t size, void *cell) {return cell;}57void operator delete[] (void *p, TR_Memory *m) {}5859void *getKey() const {return _key;}60void *setKey(void *key) {return (_key = key);}6162void *getData() const {return _data;}63void *setData(void *data) {return (_data = data);}6465TR_HashCode getHashCode() const {return _hashCode;}66TR_HashCode setHashCode(TR_HashCode hashCode) {return (_hashCode = hashCode);}6768TR_HashIndex getCollisionChain() const {return _chain;}69TR_HashIndex setCollisionChain(TR_HashIndex chain) {return (_chain = chain);}7071bool isValid() const {return (_hashCode != 0);}72void invalidate() {_hashCode = 0;}7374private:7576void * _key;77void * _data;78TR_HashCode _hashCode; // unmasked hash value79TR_HashIndex _chain; // collision chain80};8182// TR_HashTable83//84// An extensible hash table with arbitrary key and data types.85// Note that keys and data must be explicitly cast when adding86// to, and retrieving from, the hash table, for efficiency sake.87// The following methods can be overridden to suit the desired88// key type.89//90// TR_HashCode calculateHashCode(void *key)91// Computes a hash function for the given key92//93// bool isEqual (void *key1, void *key2)94// Determines if a pair of keys are equal95//96class TR_HashTable97{98public:99100TR_HashTable(TR_Memory *mem, TR_HashIndex numElements = 64);101102TR_HashTable(const TR_HashTable &table, TR_Memory *mem); // copy constructor103104void *operator new(size_t size, TR_Memory *mem);105106// Locates a record with the given key. Returns true iff a record is107// found. If the record is found, set the index reference parameter.108// If a hash code is given, use it instead of computing a new code.109//110bool locate(void *key, TR_HashIndex &index, TR_HashCode hashCode = 0);111112// Adds a record given a (key, data) pair. Returns true iff the record113// is successfully added. If a record with the given key already exists,114// the add will fail. If the add succeeds, the index reference parameter115// is set to the index at which the record was added. If a hash code is116// given, it is used instead of recomputing the code based on the key.117//118bool add(void *key, void *data, TR_HashCode hashCode = 0);119120void *getData(TR_HashIndex index)121{122TR_ASSERT(_table[index].isValid(), "cannot retrieve invalid data from hash table\n");123return _table[index].getData();124}125126void remove(TR_HashIndex index);127void removeAll();128129bool isEmpty() const;130131void grow(uint32_t newSize);132133// Assuming key is a pointer to an object , divide its134// address by 4, and return the quotient as the hash code135//136virtual TR_HashCode calculateHashCode(void *key) const {return (TR_HashCode) key >> 2;}137138virtual bool isEqual (void *key1, void *key2) const {return (key1 == key2);}139140protected:141142void grow();143void growAndRehash(TR_HashTableEntry *, TR_HashIndex, TR_HashIndex, TR_HashIndex);144145TR_Memory *_mem;146TR_HashIndex _tableSize; // Total table size (closed + open)147TR_HashIndex _mask; // Mask to compute modulus for closed area148TR_HashIndex _nextFree; // Next free slot in the open area149TR_HashIndex _highestIndex; // Highest allocated index150TR_HashTableEntry *_table;151};152#endif153154155