HPCToolkit
HashTable.hpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 /******************************************************************************
48  * *
49  * File: C++ Hash Table Utility *
50  * Author: Kevin Cureton *
51  * Date: March 1993 *
52  * *
53  *************************** HashTable Usage Warning **************************
54  * *
55  * Since the HashTable uses callbacks and virtual functions, use care if any *
56  * function that is overridden calls the functions of the HashTable. There *
57  * is the possiblity of recursive function calls if this is the case. *
58  * The functions are designed such that recursive calls can take place, but *
59  * if the overriding functions are not designed carefully, poor code *
60  * performance can result. *
61  * *
62  ******************************* HashTable Public *****************************
63  * *
64  * Constructor: *
65  * Allocate and initialize a new hash table (setting a unique id). *
66  * *
67  * Destructor: *
68  * Deallocates all storage for the hash table. Returns an error if the *
69  * user failed to call Destroy before deleting the table. *
70  * *
71  * Create: *
72  * Must be called before the HashTable can be used. *
73  * *
74  * entrySize - size in bytes of each entry in the hash table. *
75  * initialSlots - the initial number of entries for the hash table. *
76  * table. The table will expand automatically as needed. *
77  * Functions - pointers to functions the user wants to use to override *
78  * the default behavior of the HashTable. If any value *
79  * is null, then the default function will be used. *
80  * *
81  * Basic Hash, Rehash, and Compare functions have been *
82  * supplied for integers and strings. The external *
83  * prototypes are supplied below. *
84  * *
85  * HashFunctCallback - user-defined hash function. *
86  * entry - void* to the entry in the HashTable. *
87  * size - the current max size of the HashTable. *
88  * RehashFunctCallback - user-defined rehash function. *
89  * oldHashValue - the previous hash value. *
90  * size - the current max size of the HashTable. *
91  * EntryCompareCallback - user-defined compare function. *
92  * entry - void* to the first entry. *
93  * entry - void* to the second entry. *
94  * EntryCleanupCallback - user-defined cleanup function. *
95  * entry - void* to the entry in the HashTable. *
96  * *
97  * Returns nothing. *
98  * *
99  * Destroy: *
100  * Calls DeleteEntry for all the entries in the table. *
101  * *
102  * Returns nothing. *
103  * *
104  * operator==: *
105  * Tests equality on a unique id. Returns true/false. *
106  * *
107  * AddEntry: *
108  * Add an entry to the hash table. If two entries hash to the same value, *
109  * they are compared using the EntryCompare function. *
110  * *
111  * entry - pointer to the entry to be hashed. *
112  * AddEntryCallback - user supplied function which is executed if an *
113  * identical entry is found while adding the current *
114  * entry. If a function is not supplied, the default *
115  * action is to run EntryCleanup on the old entry and *
116  * copy the new entry onto the old entry's location. *
117  * ... - arguments which are passed to the AddEntryCallback *
118  * when it is executed. An example of how to use *
119  * variable arguments is provided below. *
120  * *
121  * void AddEntryCallback (void* entryyCur, void *entryNew, va_list args) *
122  * { *
123  * while (STILL_MORE_ARGUMENTS_TO_GET) *
124  * { *
125  * theArgValue = va_arg (argList, argType); *
126  * } *
127  * } *
128  * *
129  * Returns nothing. *
130  * *
131  * DeleteEntry: *
132  * Delete an entry from the hash table. Before the entry is deleted, *
133  * the DeleteEntryCallback is called to manage the cleanup of the entry. *
134  * *
135  * entry - pointer to the entry to be deleted. *
136  * DeleteEntryCallback - user supplied function which is executed before *
137  * deleting the entry. If this function is not *
138  * supplied, the EntryCleanup is called as the *
139  * default. *
140  * ... - arguments which are passed to the *
141  * DeleteEntryCallback function when it is executed. *
142  * An example of how to use variable arguments *
143  * is provided below. *
144  * *
145  * void UserDeleteEntry (void *entryCur, void *entryNew, va_list args) *
146  * { *
147  * while (STILL_MORE_ARGUMENTS_TO_GET) *
148  * { *
149  * theArgValue = va_arg (argList, argType); *
150  * } *
151  * } *
152  * *
153  * Returns nothing. *
154  * *
155  * QueryEntry: *
156  * Query the hash table to determine if an entry is present. *
157  * *
158  * entry - pointer to the entry to be queried. *
159  * *
160  * Returns a pointer to the entry which was queried or NULL if the entry *
161  * is not in the hash table. *
162  * *
163  * GetEntryIndex: *
164  * Get the index of an entry in the hash table. *
165  * *
166  * entry - pointer to the entry whose index is wanted. *
167  * *
168  * Returns the index of the entry. *
169  * *
170  * GetEntryByIndex: *
171  * Get a pointer to an entry based on an index. *
172  * *
173  * index - the index returned from a call to GetEntryIndex. Used to access *
174  * the entry. *
175  * *
176  * Returns a pointer to the entry. *
177  * *
178  * NumberOfEntries: *
179  * Get the number of entries in the hash table. *
180  * *
181  * Returns number of entries in the hash table. *
182  * *
183  * Dump: *
184  * Print the table to cout *
185  * *
186  ****************************** HashTable Protected ***************************
187  * *
188  * If it is desired, a derived class can be created and these four functions *
189  * can be overridden. This allows for more specialized operation of the *
190  * HashTable. If a dervied class is created, use the Create function *
191  * supplied in the protected section. This will ensure that the virtual *
192  * functions are called correctly. *
193  * *
194  * Create: *
195  * Must be called before the HashTable can be used. *
196  * *
197  * entrySize - size in bytes of each entry in the hash table. *
198  * initialSlots - the initial number of entries for the hash table. *
199  * table. The table will expand automatically as needed. *
200  * *
201  * The functions perform the same operation as the functions described for *
202  * creating the HashTable with function pointers. If no virtual function is *
203  * supplied, the default function will be used. *
204  * *
205  * virtual HashFunct: *
206  * This function must be supplied by the derived class. Failure to do *
207  * so will result in an assert(0) being called. *
208  * *
209  * virtual RehashFunct: *
210  * A basic rehash function has been supplied. However, it would be *
211  * wise to override this function with one better match to the hash *
212  * function which is being used. *
213  * *
214  * virtual EntryCompare: *
215  * This function must be supplied by the derived class. Failure to do *
216  * so will result in an assert(0) being called. *
217  * *
218  * virtual EntryCleanup: *
219  * The default for this function is empty. *
220  * *
221  ****************************** HashTable Private *****************************
222  * *
223  * QueryIndexSet: *
224  * OverflowIndexSet: *
225  * OverflowEntries: *
226  * *
227  * FailureToCreateError: *
228  * Prints an error message is user fails to call Create() before using the *
229  * HashTable. *
230  * *
231  * FailureToDestroyError: *
232  * Prints an error message if the user fails to call Destroy() before *
233  * deleting the HashTable. *
234  * *
235  ****************************** HashTableIterator *****************************
236  * *
237  * HashTableIterator Class *
238  * Used to step through the entries in the HashTable. *
239  * *
240  * Constructor: *
241  * Takes a pointer to the HashTable it is desired to iterate over. *
242  * *
243  * Destructor: *
244  * Nothing. *
245  * *
246  * operator ++: *
247  * Advances the iterator to the next entry in the HashTable. *
248  * *
249  * Current: *
250  * Returns a pointer to the current entry in the HashTable pointed to by *
251  * the iterator. *
252  * *
253  * Reset: *
254  * Resets the iterator to point to back to the first entry in the *
255  * HashTable. *
256  * *
257  *****************************************************************************/
258 
259 #ifndef support_HashTable_hpp
260 #define support_HashTable_hpp
261 
262 //************************** System Include Files ***************************
263 
264 #ifdef NO_STD_CHEADERS
265 # include <stdarg.h>
266 #else
267 # include <cstdarg>
268 #endif
269 
270 #include <sys/types.h>
271 
272 //*************************** User Include Files ****************************
273 
274 #include <include/uint.h>
275 
276 /******************* HashTable extern function prototypes ********************/
277 
278 extern uint IntegerHashFunct (const int value, const uint size);
279 extern uint IntegerRehashHashFunct (const uint oldHashValue, const uint size);
280 extern int IntegerEntryCompare (const int value1, const int value2);
281 
282 extern uint StringHashFunct (const void* entry, const uint size);
283 extern uint StringRehashFunct (const uint oldHashValue, const uint size);
284 extern int StringEntryCompare (const void* entry1, const void* entry2);
285 
286 /*********************** HashTable function prototypes ***********************/
287 
288 typedef void (*AddEntryFunctPtr)(void*, void*, va_list);
289  /* void* entryCur, void* entryNew, va_list argList */
290 
291 typedef void (*DeleteEntryFunctPtr)(void*, va_list);
292  /* void* entry, va_list argList */
293 
294 typedef uint (*HashFunctFunctPtr)(const void*, const uint);
295  /* void* entry, uint size */
296 
297 typedef uint (*RehashFunctFunctPtr)(const uint, const uint);
298  /* uint oldHashValue, uint newSize */
299 
300 typedef int (*EntryCompareFunctPtr)(const void*, const void*);
301  /* void* entry1, void* entry2 */
302 
303 typedef void (*EntryCleanupFunctPtr)(void*);
304  /* void* entry */
305 
306 
307 /************************ HashTable class definitions ************************/
308 
310 {
311 public:
312  HashTable ();
313  virtual ~HashTable ();
314 
315  // Must be called after creating object
316  void Create (const uint entrySize, uint initialSize,
321 
322  // Must be called before deleting object
323  void Destroy ();
324 
325  bool operator==(HashTable& rhsTab);
326 
327  void AddEntry (void* entry,
328  AddEntryFunctPtr const AddEntryCallback = 0, ...);
329  void DeleteEntry (void* entry,
330  DeleteEntryFunctPtr const DeleteEntryCallback = 0, ...);
331  void* QueryEntry (const void* entry) const;
332  int GetEntryIndex (const void* entry) const;
333  void* GetEntryByIndex (const uint index) const;
334  uint NumberOfEntries () const;
335 
336  void Dump ();
337 
338  friend class HashTableIterator;
339 
340 protected:
341  // Must be called after creating object
342  void Create (const uint entrySize, uint initialSize);
343 
344  virtual uint HashFunct (const void* entry, const uint size);
345  virtual uint RehashFunct (const uint oldHashValue, const uint size);
346  virtual int EntryCompare (const void* entry1, const void* entry2);
347  virtual void EntryCleanup (void* entry);
348 
349  HashTable& operator=(const HashTable &rhs);
350 
351 private:
352  const ulong id; // unique id for determining equality
353  uint numSlots; // number of distinct symbols
354  uint nextSlot; // next available opening
355  uint entrySize; // byte size of the entries
356  void* entries; // array of hash table entries
357  uint indexSetSize; // size of sparse hash index set
358  int* indexSet; // sparse hash index set
359 
361 
366 
367  int QueryIndexSet (const void* entry, const bool expand) const;
368  void OverflowIndexSet ();
369  void OverflowEntries ();
370 
371  void FailureToCreateError () const;
372  void FailureToDestroyError () const;
373 };
374 
375 /******************** HashTableIterator class definitions ********************/
376 
378 {
379 public:
380  HashTableIterator(const HashTable* theHashTable);
381  virtual ~HashTableIterator();
382 
383  void operator ++(int); // prefix
384  void* Current() const;
385  void Reset();
386 
387 private:
390 };
391 
392 /****************************** HashTableSortedIterator **********************/
394 
395 #endif // support_HashTable_hpp
void FailureToDestroyError() const
Definition: HashTable.cpp:786
EntryCleanupFunctPtr EntryCleanupCallback
Definition: HashTable.hpp:365
int(* EntryCompareFunctPtr)(const void *, const void *)
Definition: HashTable.hpp:300
virtual uint RehashFunct(const uint oldHashValue, const uint size)
Definition: HashTable.cpp:551
bool hashTableCreated
Definition: HashTable.hpp:360
uint IntegerRehashHashFunct(const uint oldHashValue, const uint size)
Definition: HashTable.cpp:802
uint StringRehashFunct(const uint oldHashValue, const uint size)
Definition: HashTable.cpp:835
HashTable & operator=(const HashTable &rhs)
Definition: HashTable.cpp:235
void Create(const uint entrySize, uint initialSize, HashFunctFunctPtr const HashFunctCallback, RehashFunctFunctPtr const RehashFunctCallback, EntryCompareFunctPtr const EntryCompareCallback, EntryCleanupFunctPtr const EntryCleanupCallback)
Definition: HashTable.cpp:139
EntryCompareFunctPtr EntryCompareCallback
Definition: HashTable.hpp:364
friend class HashTableIterator
Definition: HashTable.hpp:338
void * entries
Definition: HashTable.hpp:356
void OverflowEntries()
Definition: HashTable.cpp:747
uint entrySize
Definition: HashTable.hpp:355
void(* DeleteEntryFunctPtr)(void *, va_list)
Definition: HashTable.hpp:291
uint(* HashFunctFunctPtr)(const void *, const uint)
Definition: HashTable.hpp:294
virtual void EntryCleanup(void *entry)
Definition: HashTable.cpp:565
virtual ~HashTable()
Definition: HashTable.cpp:129
uint(* RehashFunctFunctPtr)(const uint, const uint)
Definition: HashTable.hpp:297
uint numSlots
Definition: HashTable.hpp:353
const HashTable * hashTable
Definition: HashTable.hpp:389
const ulong id
Definition: HashTable.hpp:352
RehashFunctFunctPtr RehashFunctCallback
Definition: HashTable.hpp:363
void OverflowIndexSet()
Definition: HashTable.cpp:695
bool operator==(HashTable &rhsTab)
Definition: HashTable.cpp:243
unsigned long int ulong
Definition: uint.h:128
uint IntegerHashFunct(const int value, const uint size)
Definition: HashTable.cpp:795
int QueryIndexSet(const void *entry, const bool expand) const
Definition: HashTable.cpp:574
unsigned int uint
Definition: uint.h:124
virtual uint HashFunct(const void *entry, const uint size)
Definition: HashTable.cpp:544
int * indexSet
Definition: HashTable.hpp:358
void Destroy()
Definition: HashTable.cpp:205
void(* AddEntryFunctPtr)(void *, void *, va_list)
Definition: HashTable.hpp:288
void DeleteEntry(void *entry, DeleteEntryFunctPtr const DeleteEntryCallback=0,...)
Definition: HashTable.cpp:296
int GetEntryIndex(const void *entry) const
Definition: HashTable.cpp:426
int IntegerEntryCompare(const int value1, const int value2)
Definition: HashTable.cpp:810
void Dump()
Definition: HashTable.cpp:475
void AddEntry(void *entry, AddEntryFunctPtr const AddEntryCallback=0,...)
Definition: HashTable.cpp:250
uint nextSlot
Definition: HashTable.hpp:354
void FailureToCreateError() const
Definition: HashTable.cpp:779
uint NumberOfEntries() const
Definition: HashTable.cpp:460
HashFunctFunctPtr HashFunctCallback
Definition: HashTable.hpp:362
int StringEntryCompare(const void *entry1, const void *entry2)
Definition: HashTable.cpp:843
void(* EntryCleanupFunctPtr)(void *)
Definition: HashTable.hpp:303
uint StringHashFunct(const void *entry, const uint size)
Definition: HashTable.cpp:817
void * QueryEntry(const void *entry) const
Definition: HashTable.cpp:396
virtual int EntryCompare(const void *entry1, const void *entry2)
Definition: HashTable.cpp:558
void * GetEntryByIndex(const uint index) const
Definition: HashTable.cpp:444
uint indexSetSize
Definition: HashTable.hpp:357