/* Holds malloc'd but not freed blocks. Static, so zero-inited by default. */
-#define VG_N_CHAINS 80021 /*4999*/ /* a prime number */
+//#define VG_N_CHAINS 80021 /*4999*/ /* a prime number */
-#define VG_CHAIN_NO(aa) (((UWord)(aa)) % VG_N_CHAINS)
+#define CHAIN_NO(key,tbl) (((UWord)(key)) % tbl->n_chains)
+
+struct {
+ UInt n_chains; // should be prime
+ VgHashNode* chains[0];
+}
+_VgHashTable;
+
+typedef (struct _VgHashTable *) VgHashTable;
/*--------------------------------------------------------------------*/
/*--- Functions ---*/
/*--------------------------------------------------------------------*/
-VgHashTable VG_(HT_construct)(void)
+VgHashTable VG_(HT_construct)(UInt n_chains)
{
/* Initialises to zero, ie. all entries NULL */
- return VG_(calloc)(VG_N_CHAINS, sizeof(VgHashNode*));
+ VgHashTable* table =
+ VG_(calloc)(sizeof(struct _VgHashTable) + n_chains*sizeof(VgHashNode*));
+ table->n_chains = n_chains;
}
Int VG_(HT_count_nodes) ( VgHashTable table )
UInt chain;
Int n = 0;
- for (chain = 0; chain < VG_N_CHAINS; chain++)
- for (node = table[chain]; node != NULL; node = node->next)
+ for (chain = 0; chain < table->n_chains; chain++)
+ for (node = table->chains[chain]; node != NULL; node = node->next)
n++;
return n;
}
/* Puts a new, heap allocated VgHashNode, into the malloclist. */
void VG_(HT_add_node) ( VgHashTable table, VgHashNode* node )
{
- UInt chain = VG_CHAIN_NO(node->key);
- node->next = table[chain];
+ UInt chain = CHAIN_NO(node->key);
+ node->next = table->chains[chain];
table[chain] = node;
}
the previous node's 'next' pointer which allows it to be removed from the
list later without having to look it up again. */
VgHashNode* VG_(HT_get_node) ( VgHashTable table, UWord key,
- /*OUT*/VgHashNode*** next_ptr )
+ /*OUT*/VgHashNode*** next_ptr )
{
VgHashNode *prev, *curr;
Int chain;
- chain = VG_CHAIN_NO(key);
+ chain = CHAIN_NO(key);
prev = NULL;
- curr = table[chain];
+ curr = table->chains[chain];
while (True) {
if (curr == NULL)
break;
}
if (NULL == prev)
- *next_ptr = & table[chain];
+ *next_ptr = & (table->chain[chain]);
else
- *next_ptr = & prev->next;
+ *next_ptr = & (prev->next);
return curr;
}
VgHashNode* node;
*n_shadows = 0;
- for (i = 0; i < VG_N_CHAINS; i++) {
- for (node = table[i]; node != NULL; node = node->next) {
+ for (i = 0; i < table->n_chains; i++) {
+ for (node = table->chains[i]; node != NULL; node = node->next) {
(*n_shadows)++;
}
}
arr = VG_(malloc)( *n_shadows * sizeof(VgHashNode*) );
j = 0;
- for (i = 0; i < VG_N_CHAINS; i++) {
- for (node = table[i]; node != NULL; node = node->next) {
+ for (i = 0; i < table->n_chains; i++) {
+ for (node = table->chains[i]; node != NULL; node = node->next) {
arr[j++] = node;
}
}
UInt i;
VgHashNode* node;
- for (i = 0; i < VG_N_CHAINS; i++)
- for (node = table[i]; node != NULL; node = node->next)
+ for (i = 0; i < table->n_chains; i++)
+ for (node = table->chains[i]; node != NULL; node = node->next)
if ( p(node, d) )
return node;
UInt i;
VgHashNode* node;
- for (i = 0; i < VG_N_CHAINS; i++) {
- for (node = table[i]; node != NULL; node = node->next) {
+ for (i = 0; i < table->n_chains; i++) {
+ for (node = table->chains[i]; node != NULL; node = node->next) {
f(node, d);
}
}
UInt i;
VgHashNode* node;
- for (i = 0; i < VG_N_CHAINS; i++) {
- for (node = table[i]; node != NULL; node = node->next) {
+ for (i = 0; i < table->n_chains; i++) {
+ for (node = table->chains[i]; node != NULL; node = node->next) {
VG_(free)(node);
}
}