blob: 697891a27e229c4c8b9a6885d7d85a353fa7718d [file] [log] [blame]
njn3e884182003-04-15 13:03:23 +00001
2/*--------------------------------------------------------------------*/
3/*--- A separately chained hash table. vg_hashtable.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, an extensible x86 protected-mode
8 emulator for monitoring program execution on x86-Unixes.
9
nethercotebb1c9912004-01-04 16:43:23 +000010 Copyright (C) 2000-2004 Julian Seward
njn3e884182003-04-15 13:03:23 +000011 jseward@acm.org
12
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
nethercotef1e5e152004-09-01 23:58:16 +000031#include "core.h"
njn3e884182003-04-15 13:03:23 +000032
33/*--------------------------------------------------------------------*/
34/*--- Declarations ---*/
35/*--------------------------------------------------------------------*/
36
37/* Holds malloc'd but not freed blocks. Static, so zero-inited by default. */
38
sewardj59fb25c2003-09-28 16:32:58 +000039#define VG_N_CHAINS 4999 /* a prime number */
njn3e884182003-04-15 13:03:23 +000040
nethercote50397c22004-11-04 18:03:06 +000041#define VG_CHAIN_NO(aa) (((UWord)(aa)) % VG_N_CHAINS)
njn3e884182003-04-15 13:03:23 +000042
43/*--------------------------------------------------------------------*/
44/*--- Functions ---*/
45/*--------------------------------------------------------------------*/
46
47VgHashTable VG_(HT_construct)(void)
48{
njnce46c2a2003-07-21 10:52:07 +000049 /* Initialises to zero, ie. all entries NULL */
njn84d669f2003-07-21 11:42:27 +000050 return VG_(calloc)(VG_N_CHAINS, sizeof(VgHashNode*));
njn3e884182003-04-15 13:03:23 +000051}
52
53Int VG_(HT_count_nodes) ( VgHashTable table )
54{
55 VgHashNode* node;
56 UInt chain;
57 Int n = 0;
58
59 for (chain = 0; chain < VG_N_CHAINS; chain++)
60 for (node = table[chain]; node != NULL; node = node->next)
61 n++;
62 return n;
63}
64
65/* Puts a new, heap allocated VgHashNode, into the malloclist. */
66void VG_(HT_add_node) ( VgHashTable table, VgHashNode* node )
67{
68 UInt chain = VG_CHAIN_NO(node->key);
69 node->next = table[chain];
70 table[chain] = node;
71}
72
73/* Looks up a VgHashNode in the table. Also returns the address of
74 the previous node's `next' pointer which allows it to be removed from the
75 list later without having to look it up again. */
nethercote3d6b6112004-11-04 16:39:43 +000076VgHashNode* VG_(HT_get_node) ( VgHashTable table, UWord key,
njn3e884182003-04-15 13:03:23 +000077 /*OUT*/VgHashNode*** next_ptr )
78{
79 VgHashNode *prev, *curr;
80 Int chain;
81
82 chain = VG_CHAIN_NO(key);
83
84 prev = NULL;
85 curr = table[chain];
86 while (True) {
87 if (curr == NULL)
88 break;
89 if (key == curr->key)
90 break;
91 prev = curr;
92 curr = curr->next;
93 }
94
95 if (NULL == prev)
96 *next_ptr = & table[chain];
97 else
98 *next_ptr = & prev->next;
99
100 return curr;
101}
102
njn3e884182003-04-15 13:03:23 +0000103/* Allocates a suitably-sized array, copies all the malloc'd block
njn06072ec2003-09-30 15:35:13 +0000104 shadows into it, then returns both the array and the size of it. This is
105 used by the memory-leak detector.
njn3e884182003-04-15 13:03:23 +0000106*/
njn06072ec2003-09-30 15:35:13 +0000107VgHashNode** VG_(HT_to_array) ( VgHashTable table, /*OUT*/ UInt* n_shadows )
njn3e884182003-04-15 13:03:23 +0000108{
109 UInt i, j;
110 VgHashNode** arr;
111 VgHashNode* node;
112
113 *n_shadows = 0;
114 for (i = 0; i < VG_N_CHAINS; i++) {
115 for (node = table[i]; node != NULL; node = node->next) {
116 (*n_shadows)++;
117 }
118 }
119 if (*n_shadows == 0)
120 return NULL;
121
122 arr = VG_(malloc)( *n_shadows * sizeof(VgHashNode*) );
123
124 j = 0;
125 for (i = 0; i < VG_N_CHAINS; i++) {
126 for (node = table[i]; node != NULL; node = node->next) {
127 arr[j++] = node;
128 }
129 }
njn8372b7f2003-05-14 12:42:14 +0000130 vg_assert(j == *n_shadows);
njn3e884182003-04-15 13:03:23 +0000131
njn3e884182003-04-15 13:03:23 +0000132 return arr;
133}
134
135/* Return the first VgHashNode satisfying the predicate p. */
thughes4ad52d02004-06-27 17:37:21 +0000136VgHashNode* VG_(HT_first_match) ( VgHashTable table,
137 Bool (*p) ( VgHashNode*, void* ),
138 void* d )
njn3e884182003-04-15 13:03:23 +0000139{
140 UInt i;
141 VgHashNode* node;
142
143 for (i = 0; i < VG_N_CHAINS; i++)
144 for (node = table[i]; node != NULL; node = node->next)
thughes4ad52d02004-06-27 17:37:21 +0000145 if ( p(node, d) )
njn3e884182003-04-15 13:03:23 +0000146 return node;
147
148 return NULL;
149}
150
thughes4ad52d02004-06-27 17:37:21 +0000151void VG_(HT_apply_to_all_nodes)( VgHashTable table,
152 void (*f)(VgHashNode*, void*),
153 void* d )
njn3e884182003-04-15 13:03:23 +0000154{
155 UInt i;
156 VgHashNode* node;
157
158 for (i = 0; i < VG_N_CHAINS; i++) {
159 for (node = table[i]; node != NULL; node = node->next) {
thughes4ad52d02004-06-27 17:37:21 +0000160 f(node, d);
njn3e884182003-04-15 13:03:23 +0000161 }
162 }
163}
164
165void VG_(HT_destruct)(VgHashTable table)
166{
167 UInt i;
168 VgHashNode* node;
169
170 for (i = 0; i < VG_N_CHAINS; i++) {
171 for (node = table[i]; node != NULL; node = node->next) {
172 VG_(free)(node);
173 }
174 }
175 VG_(free)(table);
176}
177
178/*--------------------------------------------------------------------*/
179/*--- end vg_hashtable.c ---*/
180/*--------------------------------------------------------------------*/