blob: 22673675a3705975beae106a692bfcc65978d50e [file] [log] [blame]
njn81c00df2005-05-14 21:28:43 +00001
2/*--------------------------------------------------------------------*/
3/*--- A hash table implementation. pub_tool_hashtable.h ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
Elliott Hughesed398002017-06-21 14:41:24 -070010 Copyright (C) 2005-2017 Nicholas Nethercote
sewardj0c24f8a2006-10-17 02:11:55 +000011 njn@valgrind.org
njn81c00df2005-05-14 21:28:43 +000012
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 02111-1307, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29*/
30
31#ifndef __PUB_TOOL_HASHTABLE_H
32#define __PUB_TOOL_HASHTABLE_H
33
florian535fb1b2013-09-15 13:54:34 +000034#include "pub_tool_basics.h" // VG_ macro
35
njn81c00df2005-05-14 21:28:43 +000036/* Generic type for a separately-chained hash table. Via a kind of dodgy
37 C-as-C++ style inheritance, tools can extend the VgHashNode type, so long
38 as the first two fields match the sizes of these two fields. Requires
39 a bit of casting by the tool. */
40
njnf69f9452005-07-03 17:53:11 +000041// Problems with this data structure:
njn81c00df2005-05-14 21:28:43 +000042// - Separate chaining gives bad cache behaviour. Hash tables with linear
43// probing give better cache behaviour.
njn81c00df2005-05-14 21:28:43 +000044
45typedef
46 struct _VgHashNode {
47 struct _VgHashNode * next;
48 UWord key;
49 }
50 VgHashNode;
51
florian09a4c792014-10-18 10:58:05 +000052typedef struct _VgHashTable VgHashTable;
njn81c00df2005-05-14 21:28:43 +000053
sewardj3f94a7d2007-08-25 07:19:08 +000054/* Make a new table. Allocates the memory with VG_(calloc)(), so can
55 be freed with VG_(free)(). The table starts small but will
56 periodically be expanded. This is transparent to the users of this
florian9c39f512014-09-13 22:31:13 +000057 module. The function never returns NULL. */
florian09a4c792014-10-18 10:58:05 +000058extern VgHashTable *VG_(HT_construct) ( const HChar* name );
njn81c00df2005-05-14 21:28:43 +000059
60/* Count the number of nodes in a table. */
floriana6a6d922015-08-05 11:26:10 +000061extern UInt VG_(HT_count_nodes) ( const VgHashTable *table );
njn81c00df2005-05-14 21:28:43 +000062
njnb965efb2009-08-10 07:36:54 +000063/* Add a node to the table. Duplicate keys are permitted. */
florian09a4c792014-10-18 10:58:05 +000064extern void VG_(HT_add_node) ( VgHashTable *t, void* node );
njn81c00df2005-05-14 21:28:43 +000065
philippe7293d252014-06-14 16:30:09 +000066/* Looks up a VgHashNode by key in the table.
67 * Returns NULL if not found. If entries
njnb965efb2009-08-10 07:36:54 +000068 * with duplicate keys are present, the most recently-added of the dups will
69 * be returned, but it's probably better to avoid dups altogether. */
florian09a4c792014-10-18 10:58:05 +000070extern void* VG_(HT_lookup) ( const VgHashTable *table, UWord key );
njn34582fb2005-08-11 00:06:36 +000071
philippe7293d252014-06-14 16:30:09 +000072/* Removes a VgHashNode by key from the table. Returns NULL if not found. */
florian09a4c792014-10-18 10:58:05 +000073extern void* VG_(HT_remove) ( VgHashTable *table, UWord key );
njn34582fb2005-08-11 00:06:36 +000074
philippe7293d252014-06-14 16:30:09 +000075typedef Word (*HT_Cmp_t) ( const void* node1, const void* node2 );
76
77/* Same as VG_(HT_lookup) and VG_(HT_remove), but allowing a part of or
78 the full element to be compared for equality, not only the key.
79 The typical use for the below function is to store a hash value of the
80 element in the key, and have the comparison function checking for equality
81 of the full element data.
82 Attention about the comparison function:
83 * It must *not* compare the 'next' pointer.
84 * when comparing the rest of the node, if the node data contains holes
85 between components, either the node memory should be fully initialised
86 (e.g. allocated using VG_(calloc)) or each component should be compared
philippee4374272015-05-20 15:08:09 +000087 individually.
88 Note that the cmp function is only called for elements that already
89 have keys that are equal. So, it is not needed for cmp to check for
90 key equality. */
florian09a4c792014-10-18 10:58:05 +000091extern void* VG_(HT_gen_lookup) ( const VgHashTable *table, const void* node,
92 HT_Cmp_t cmp );
93extern void* VG_(HT_gen_remove) ( VgHashTable *table, const void* node,
94 HT_Cmp_t cmp );
philippe7293d252014-06-14 16:30:09 +000095
96/* Output detailed usage/collision statistics.
97 cmp will be used to verify if 2 elements with the same key are equal.
98 Use NULL cmp if the hash table elements are only to be compared by key. */
florian09a4c792014-10-18 10:58:05 +000099extern void VG_(HT_print_stats) ( const VgHashTable *table, HT_Cmp_t cmp );
philippe7293d252014-06-14 16:30:09 +0000100
njn29a5c012009-05-06 06:15:55 +0000101/* Allocates a suitably-sized array, copies pointers to all the hashtable
102 elements into it, then returns both the array and the size of it. The
florian9c39f512014-09-13 22:31:13 +0000103 array must be freed with VG_(free). If the hashtable is empty, the
104 function returns NULL and assigns *nelems = 0. */
florian09a4c792014-10-18 10:58:05 +0000105extern VgHashNode** VG_(HT_to_array) ( const VgHashTable *table,
106 /*OUT*/ UInt* n_elems );
njn81c00df2005-05-14 21:28:43 +0000107
njn1af79722005-08-14 17:42:35 +0000108/* Reset the table's iterator to point to the first element. */
florian09a4c792014-10-18 10:58:05 +0000109extern void VG_(HT_ResetIter) ( VgHashTable *table );
njn1af79722005-08-14 17:42:35 +0000110
sewardj3f94a7d2007-08-25 07:19:08 +0000111/* Return the element pointed to by the iterator and move on to the
112 next one. Returns NULL if the last one has been passed, or if
113 HT_ResetIter() has not been called previously. Asserts if the
114 table has been modified (HT_add_node, HT_remove) since
115 HT_ResetIter. This guarantees that callers cannot screw up by
116 modifying the table whilst iterating over it (and is necessary to
117 make the implementation safe; specifically we must guarantee that
118 the table will not get resized whilst iteration is happening.
119 Since resizing only happens as a result of calling HT_add_node,
120 disallowing HT_add_node during iteration should give the required
121 assurance. */
florian09a4c792014-10-18 10:58:05 +0000122extern void* VG_(HT_Next) ( VgHashTable *table );
njn1af79722005-08-14 17:42:35 +0000123
Elliott Hughesa0664b92017-04-18 17:46:52 -0700124/* Remove the element pointed to by the iterator and leave the iterator
125 in a state where VG_(HT_Next) will return the element just after the removed
126 node.
127 This allows removing elements from the table whilst iterating over it.
128 Note that removing an entry does not resize the hash table, making this
129 safe. */
130extern void VG_(HT_remove_at_Iter)( VgHashTable *table );
131
philippe6643e962012-01-17 21:16:30 +0000132/* Destroy a table and deallocates the memory used by the nodes using
133 freenode_fn.*/
florian09a4c792014-10-18 10:58:05 +0000134extern void VG_(HT_destruct) ( VgHashTable *table, void(*freenode_fn)(void*) );
njn81c00df2005-05-14 21:28:43 +0000135
136
137#endif // __PUB_TOOL_HASHTABLE_H
138
139/*--------------------------------------------------------------------*/
140/*--- end ---*/
141/*--------------------------------------------------------------------*/