/* Puts a new, heap allocated VgHashNode, into the VgHashTable. Prepends the node to the appropriate chain. */ void VG_(HT_add_node) ( VgHashTable table, void* vnode ) { VgHashNode* node = (VgHashNode*)vnode; UInt chain = CHAIN_NO(node->key, table); node->next = table->chains[chain]; table->chains[chain] = node; }
/* Looks up a VgHashNode in the table. Also returns the address of the previous node's 'next' pointer which allows it to be removed from the list later without having to look it up again. */ void* VG_(HT_get_node) ( VgHashTable table, UWord key, /*OUT*/VgHashNode*** next_ptr ) { VgHashNode *prev, *curr; Int chain; chain = CHAIN_NO(key, table); prev = NULL; curr = table->chains[chain]; while (True) { if (curr == NULL) break; if (key == curr->key) break; prev = curr; curr = curr->next; } if (NULL == prev) *next_ptr = & (table->chains[chain]); else *next_ptr = & (prev->next); return curr; }
/* Looks up a HashNode in the table. Returns NULL if not found. */ void* HT_lookup ( BasicBlockHashTable table, UWord key ) { HashNode* curr = table->chains[ CHAIN_NO(key, table) ]; while (curr) { #ifdef DEBUG_HASH printf("chain no: %d key=%x curr-key=%x\n",CHAIN_NO(key, table), key, curr->key); #endif if (key == curr->key) { return curr; } curr = curr->next; } return NULL; }
/* Looks up a VgHashNode in the table. Returns NULL if not found. */ void * HT_lookup(HashTable * table, UWord key) { HashNode * curr = table->chains[CHAIN_NO(key, table)]; while (curr) { if (key == curr->key) return curr; curr = curr->next; } return NULL; }
/* Looks up a VgHashNode in the table. Returns NULL if not found. */ void* VG_(HT_lookup) ( VgHashTable table, UWord key ) { VgHashNode* curr = table->chains[ CHAIN_NO(key, table) ]; while (curr) { if (key == curr->key) { return curr; } curr = curr->next; } return NULL; }
static void resize(HashTable * table) { Int i; SizeT sz; SizeT old_chains = table->n_chains; SizeT new_chains = old_chains + 1; HashNode ** chains; HashNode * node; /* If we've run out of primes, do nothing. */ if (old_chains == primes[N_HASH_PRIMES - 1]) return; vg_assert(old_chains >= primes[0] && old_chains < primes[N_HASH_PRIMES-1]); for (i = 0; i < N_HASH_PRIMES; i++) { if (primes[i] > new_chains) { new_chains = primes[i]; break; } } vg_assert(new_chains > old_chains); vg_assert(new_chains > primes[0] && new_chains <= primes[N_HASH_PRIMES-1]); #if DEBUG_ALLOCATION UInt q; for (q = 0; q < (new_chains - table->n_chains); q++) APROF_(add_alloc)(HTC_S); //VG_(umsg)("Adding %lu chains\n", new_chains - table->n_chains); #endif table->n_chains = new_chains; sz = new_chains * sizeof(HashNode *); chains = VG_(calloc)("chains", 1, sz); for (i = 0; i < old_chains; i++) { node = table->chains[i]; while (node != NULL) { HashNode * next = node->next; UWord chain = CHAIN_NO(node->key, table); node->next = chains[chain]; chains[chain] = node; node = next; } } VG_(free)(table->chains); table->chains = chains; }
static void resize ( VgHashTable *table ) { Int i; SizeT sz; SizeT old_chains = table->n_chains; SizeT new_chains = old_chains + 1; VgHashNode** chains; VgHashNode * node; /* If we've run out of primes, do nothing. */ if (old_chains == primes[N_HASH_PRIMES-1]) return; vg_assert(old_chains >= primes[0] && old_chains < primes[N_HASH_PRIMES-1]); for (i = 0; i < N_HASH_PRIMES; i++) { if (primes[i] > new_chains) { new_chains = primes[i]; break; } } vg_assert(new_chains > old_chains); vg_assert(new_chains > primes[0] && new_chains <= primes[N_HASH_PRIMES-1]); VG_(debugLog)( 1, "hashtable", "resizing table `%s' from %lu to %lu (total elems %lu)\n", table->name, (UWord)old_chains, (UWord)new_chains, (UWord)table->n_elements ); table->n_chains = new_chains; sz = new_chains * sizeof(VgHashNode*); chains = VG_(calloc)("hashtable.resize.1", 1, sz); for (i = 0; i < old_chains; i++) { node = table->chains[i]; while (node != NULL) { VgHashNode* next = node->next; UWord chain = CHAIN_NO(node->key, table); node->next = chains[chain]; chains[chain] = node; node = next; } } VG_(free)(table->chains); table->chains = chains; }
/* Looks up a VgHashNode by node in the table. Returns NULL if not found. GEN!!! marks the lines that differs from VG_(HT_lookup). */ void* VG_(HT_gen_lookup) ( const VgHashTable *table, const void* node, HT_Cmp_t cmp ) { const VgHashNode* hnode = node; // GEN!!! VgHashNode* curr = table->chains[ CHAIN_NO(hnode->key, table) ]; // GEN!!! while (curr) { if (cmp (hnode, curr) == 0) { // GEN!!! return curr; } curr = curr->next; } return NULL; }
/* Puts a new, heap allocated VgHashNode, into the VgHashTable. Prepends the node to the appropriate chain. No duplicate key detection is done. */ void VG_(HT_add_node) ( VgHashTable *table, void* vnode ) { VgHashNode* node = (VgHashNode*)vnode; UWord chain = CHAIN_NO(node->key, table); node->next = table->chains[chain]; table->chains[chain] = node; table->n_elements++; if ( (1 * (ULong)table->n_elements) > (1 * (ULong)table->n_chains) ) { resize(table); } /* Table has been modified; hence HT_Next should assert. */ table->iterOK = False; }
/* Removes a VgHashNode from the table. Returns NULL if not found. */ void* VG_(HT_remove) ( VgHashTable table, UWord key ) { Int chain = CHAIN_NO(key, table); VgHashNode* curr = table->chains[chain]; VgHashNode** prev_next_ptr = &(table->chains[chain]); while (curr) { if (key == curr->key) { *prev_next_ptr = curr->next; return curr; } prev_next_ptr = &(curr->next); curr = curr->next; } return NULL; }
/* Puts a new, heap allocated VgHashNode, into the VgHashTable. Prepends the node to the appropriate chain. No duplicate key detection is done. */ void HT_add_node(HashTable * table, UWord key, void * n) { HashNode * node = (HashNode *) n; node->next = NULL; //vg_assert(node->key == key); UWord chain = CHAIN_NO(key, table); node->next = table->chains[chain]; table->chains[chain] = node; table->n_elements++; if ((1 * (ULong) table->n_elements) > (1 * (ULong) table->n_chains)) { resize(table); } /* Table has been modified; hence HT_Next should assert. */ table->iterOK = False; }
/* Puts a new, heap allocated HashNode, into the BasicBlockHashTable. Prepends the node to the appropriate chain. */ void HT_add_node ( BasicBlockHashTable table, void* vnode ) { HashNode* node = (HashNode*)vnode; UInt chain = CHAIN_NO(node->key, table); #ifdef DEBUG_HASH printf("\n%d node->key = %x chain in HT\n",chain, node->key); #endif node->next = table->chains[chain]; table->chains[chain] = node; #ifdef DEBUG_HASH printf("inserted node->key = %x chain in HT\n",table->chains[chain]->key); #endif }
/* Removes a HashNode from the table. Returns NULL if not found. */ void* HT_remove( BasicBlockHashTable table, UWord key ) { Int chain = CHAIN_NO(key, table); HashNode* curr = table->chains[chain]; HashNode** prev_next_ptr = &(table->chains[chain]); while (curr) { if (key == curr->key) { *prev_next_ptr = curr->next; free(curr); return curr; } prev_next_ptr = &(curr->next); curr = curr->next; } return NULL; }
/* Removes a VgHashNode from the table. Returns NULL if not found. */ void * HT_remove(HashTable * table, UWord key) { UWord chain = CHAIN_NO(key, table); HashNode* curr = table->chains[chain]; HashNode** prev_next_ptr = &(table->chains[chain]); /* Table has been modified; hence HT_Next should assert. */ table->iterOK = False; while (curr) { if (key == curr->key) { *prev_next_ptr = curr->next; table->n_elements--; return curr; } prev_next_ptr = &(curr->next); curr = curr->next; } return NULL; }
/* Removes a VgHashNode by node from the table. Returns NULL if not found. GEN!!! marks the lines that differs from VG_(HT_remove). */ void* VG_(HT_gen_remove) ( VgHashTable *table, const void* node, HT_Cmp_t cmp ) { const VgHashNode* hnode = node; // GEN!!! UWord chain = CHAIN_NO(hnode->key, table); // GEN!!! VgHashNode* curr = table->chains[chain]; VgHashNode** prev_next_ptr = &(table->chains[chain]); /* Table has been modified; hence HT_Next should assert. */ table->iterOK = False; while (curr) { if (cmp(hnode, curr) == 0) { // GEN!!! *prev_next_ptr = curr->next; table->n_elements--; return curr; } prev_next_ptr = &(curr->next); curr = curr->next; } return NULL; }