-
Notifications
You must be signed in to change notification settings - Fork 747
/
Copy pathHashTable.hpp
153 lines (121 loc) · 5.28 KB
/
HashTable.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*******************************************************************************
* Copyright IBM Corp. and others 2000
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
* or the Apache License, Version 2.0 which accompanies this distribution and
* is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* This Source Code may also be made available under the following
* Secondary Licenses when the conditions for such availability set
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
* General Public License, version 2 with the GNU Classpath
* Exception [1] and GNU General Public License, version 2 with the
* OpenJDK Assembly Exception [2].
*
* [1] https://www.gnu.org/software/classpath/license.html
* [2] https://openjdk.org/legal/assembly-exception.html
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
*******************************************************************************/
#ifndef HASHTABLE_INCL
#define HASHTABLE_INCL
#include <stddef.h>
#include <stdint.h>
#include "env/jittypes.h"
#include "infra/Assert.hpp"
class TR_Memory;
#define MINIMUM_HASHTABLE_SIZE 16
typedef uint32_t TR_HashIndex;
typedef uintptr_t TR_HashCode;
class TR_HashTableEntry
{
public:
TR_HashTableEntry() {}
TR_HashTableEntry(void *key, void *data, TR_HashCode hashCode)
: _key(key),
_data(data),
_hashCode(hashCode),
_chain(0) {}
TR_HashTableEntry(const TR_HashTableEntry &entry)
: _key(entry._key),
_data(entry._data),
_hashCode(entry._hashCode),
_chain(entry._chain) {}
void *operator new[](size_t size, TR_Memory *m);
void *operator new(size_t size, void *cell) {return cell;}
void operator delete[] (void *p, TR_Memory *m) {}
void *getKey() const {return _key;}
void *setKey(void *key) {return (_key = key);}
void *getData() const {return _data;}
void *setData(void *data) {return (_data = data);}
TR_HashCode getHashCode() const {return _hashCode;}
TR_HashCode setHashCode(TR_HashCode hashCode) {return (_hashCode = hashCode);}
TR_HashIndex getCollisionChain() const {return _chain;}
TR_HashIndex setCollisionChain(TR_HashIndex chain) {return (_chain = chain);}
bool isValid() const {return (_hashCode != 0);}
void invalidate() {_hashCode = 0;}
private:
void * _key;
void * _data;
TR_HashCode _hashCode; // unmasked hash value
TR_HashIndex _chain; // collision chain
};
// TR_HashTable
//
// An extensible hash table with arbitrary key and data types.
// Note that keys and data must be explicitly cast when adding
// to, and retrieving from, the hash table, for efficiency sake.
// The following methods can be overridden to suit the desired
// key type.
//
// TR_HashCode calculateHashCode(void *key)
// Computes a hash function for the given key
//
// bool isEqual (void *key1, void *key2)
// Determines if a pair of keys are equal
//
class TR_HashTable
{
public:
TR_HashTable(TR_Memory *mem, TR_HashIndex numElements = 64);
TR_HashTable(const TR_HashTable &table, TR_Memory *mem); // copy constructor
void *operator new(size_t size, TR_Memory *mem);
// Locates a record with the given key. Returns true iff a record is
// found. If the record is found, set the index reference parameter.
// If a hash code is given, use it instead of computing a new code.
//
bool locate(void *key, TR_HashIndex &index, TR_HashCode hashCode = 0);
// Adds a record given a (key, data) pair. Returns true iff the record
// is successfully added. If a record with the given key already exists,
// the add will fail. If the add succeeds, the index reference parameter
// is set to the index at which the record was added. If a hash code is
// given, it is used instead of recomputing the code based on the key.
//
bool add(void *key, void *data, TR_HashCode hashCode = 0);
void *getData(TR_HashIndex index)
{
TR_ASSERT(_table[index].isValid(), "cannot retrieve invalid data from hash table\n");
return _table[index].getData();
}
void remove(TR_HashIndex index);
void removeAll();
bool isEmpty() const;
void grow(uint32_t newSize);
// Assuming key is a pointer to an object , divide its
// address by 4, and return the quotient as the hash code
//
virtual TR_HashCode calculateHashCode(void *key) const {return (TR_HashCode) key >> 2;}
virtual bool isEqual (void *key1, void *key2) const {return (key1 == key2);}
protected:
void grow();
void growAndRehash(TR_HashTableEntry *, TR_HashIndex, TR_HashIndex, TR_HashIndex);
TR_Memory *_mem;
TR_HashIndex _tableSize; // Total table size (closed + open)
TR_HashIndex _mask; // Mask to compute modulus for closed area
TR_HashIndex _nextFree; // Next free slot in the open area
TR_HashIndex _highestIndex; // Highest allocated index
TR_HashTableEntry *_table;
};
#endif