From: adash Date: Fri, 9 Mar 2007 18:40:54 +0000 (+0000) Subject: Add cache hash delete function, cache hash functionalities and test files X-Git-Tag: preEdgeChange~670 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=80c5c583705aa18ff57aec498c98ebf2bf13dfb0;p=IRC.git Add cache hash delete function, cache hash functionalities and test files --- diff --git a/Robust/src/Runtime/DSTM/interface/clookup.c b/Robust/src/Runtime/DSTM/interface/clookup.c new file mode 100644 index 00000000..f1cf8548 --- /dev/null +++ b/Robust/src/Runtime/DSTM/interface/clookup.c @@ -0,0 +1,199 @@ + #include "clookup.h" + +cachehashtable_t *cachehashCreate(unsigned int size, float loadfactor) { + cachehashtable_t *ctable; + cachehashlistnode_t *nodes; + int i; + + if((ctable = calloc(1, sizeof(cachehashtable_t))) == NULL) { + printf("Calloc error %s %d\n", __FILE__, __LINE__); + return NULL; + } + + // Allocate space for the hash table + if((nodes = calloc(HASH_SIZE, sizeof(cachehashlistnode_t))) == NULL) { + printf("Calloc error %s %d\n", __FILE__, __LINE__); + return NULL; + } + + ctable->table = nodes; + ctable->size = size; + ctable->numelements = 0; // Initial number of elements in the hash + ctable->loadfactor = loadfactor; + + return ctable; +} + +//Finds the right bin in the hash table +unsigned int cachehashFunction(cachehashtable_t *table, unsigned int key) { + return ( key % (table->size)); +} + +//Store objects and their pointers into hash +unsigned int cachehashInsert(cachehashtable_t *table, unsigned int key, void *val) { + unsigned int newsize; + int index; + cachehashlistnode_t *ptr, *node; + + if(table->numelements > (table->loadfactor * table->size)) { + //Resize + newsize = 2 * table->size + 1; + cachehashResize(table,newsize); + } + + ptr = table->table; + table->numelements++; + index = cachehashFunction(table, key); +#ifdef DEBUG + printf("DEBUG -> index = %d, key = %d, val = %x\n", index, key, val); +#endif + if(ptr[index].next == NULL && ptr[index].key == 0) { // Insert at the first position in the hashtable + ptr[index].key = key; + ptr[index].val = val; + } else { // Insert in the beginning of linked list + if ((node = calloc(1, sizeof(cachehashlistnode_t))) == NULL) { + printf("Calloc error %s, %d\n", __FILE__, __LINE__); + return 1; + } + node->key = key; + node->val = val ; + node->next = ptr[index].next; + ptr[index].next = node; + } + return 0; +} + +// Search for an address for a given oid +void *cachehashSearch(cachehashtable_t *table, unsigned int key) { + int index; + cachehashlistnode_t *ptr, *node; + + ptr = table->table; + index = cachehashFunction(table, key); + node = &ptr[index]; + while(node != NULL) { + if(node->key == key) { + return node->val; + } + node = node->next; + } + return NULL; +} + +unsigned int cachehashRemove(cachehashtable_t *table, unsigned int key) { + int index; + cachehashlistnode_t *curr, *prev; + cachehashlistnode_t *ptr, *node; + + ptr = table->table; + index = cachehashFunction(table,key); + curr = &ptr[index]; + + for (; curr != NULL; curr = curr->next) { + if (curr->key == key) { // Find a match in the hash table + table->numelements--; // Decrement the number of elements in the global hashtable + if ((curr == &ptr[index]) && (curr->next == NULL)) { // Delete the first item inside the hashtable with no linked list of cachehashlistnode_t + curr->key = 0; + curr->val = NULL; + } else if ((curr == &ptr[index]) && (curr->next != NULL)) { //Delete the first item with a linked list of cachehashlistnode_t connected + curr->key = curr->next->key; + curr->val = curr->next->val; + node = curr->next; + curr->next = curr->next->next; + free(node); + } else { // Regular delete from linked listed + prev->next = curr->next; + free(curr); + } + return 0; + } + prev = curr; + } + return 1; +} + +unsigned int cachehashResize(cachehashtable_t *table, unsigned int newsize) { + cachehashlistnode_t *node, *ptr, *curr, *next; // curr and next keep track of the current and the next cachehashlistnodes in a linked list + unsigned int oldsize; + int isfirst; // Keeps track of the first element in the cachehashlistnode_t for each bin in hashtable + int i,index; + cachehashlistnode_t *newnode; + + ptr = table->table; + oldsize = table->size; + + if((node = calloc(newsize, sizeof(cachehashlistnode_t))) == NULL) { + printf("Calloc error %s %d\n", __FILE__, __LINE__); + return 1; + } + + table->table = node; //Update the global hashtable upon resize() + table->size = newsize; + table->numelements = 0; + + for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table + curr = &ptr[i]; + isfirst = 1; + while (curr != NULL) { //Inner loop to go through linked lists + if (curr->key == 0) { //Exit inner loop if there the first element for a given bin/index is NULL + break; //key = val =0 for element if not present within the hash table + } + next = curr->next; + + index = cachehashFunction(table, curr->key); +#ifdef DEBUG + printf("DEBUG(resize) -> index = %d, key = %d, val = %x\n", index, curr->key, curr->val); +#endif + // Insert into the new table + if(table->table[index].next == NULL && table->table[index].key == 0) { + table->table[index].key = curr->key; + table->table[index].val = curr->val; + table->numelements++; + }else { + if((newnode = calloc(1, sizeof(cachehashlistnode_t))) == NULL) { + printf("Calloc error %s, %d\n", __FILE__, __LINE__); + return 1; + } + newnode->key = curr->key; + newnode->val = curr->val; + newnode->next = table->table[index].next; + table->table[index].next = newnode; + table->numelements++; + } + + //free the linked list of cachehashlistnode_t if not the first element in the hash table + if (isfirst != 1) { + free(curr); + } + + isfirst = 0; + curr = next; + } + } + + free(ptr); //Free the memory of the old hash table + return 0; +} + +//Delete the entire hash table +void cachehashDelete(cachehashtable_t *table) { + int i, isFirst; + cachehashlistnode_t *ptr, *curr, *next; + ptr = table->table; + + for(i=0 ; isize ; i++) { + curr = &ptr[i]; + isFirst = 1 ; + while(curr != NULL) { + next = curr->next; + if(isFirst != 1) { + free(curr); + } + isFirst = 0; + curr = next; + } + } + + free(ptr); + free(table); +} diff --git a/Robust/src/Runtime/DSTM/interface/clookup.h b/Robust/src/Runtime/DSTM/interface/clookup.h index 3f99ca24..a90d9287 100644 --- a/Robust/src/Runtime/DSTM/interface/clookup.h +++ b/Robust/src/Runtime/DSTM/interface/clookup.h @@ -1,6 +1,9 @@ #ifndef _CLOOKUP_H_ #define _CLOOKUP_H_ +#include +#include + #define LOADFACTOR 0.75 #define HASH_SIZE 100 @@ -20,10 +23,11 @@ typedef struct hashtable { /* Prototypes for hash*/ cachehashtable_t *cachehashCreate(unsigned int size, float loadfactor); unsigned int cachehashFunction(cachehashtable_t *table, unsigned int key); -void cachehashInsert(cachehashtable_t *table, unsigned int key, void *val); +unsigned int cachehashInsert(cachehashtable_t *table, unsigned int key, void *val); void *cachehashSearch(cachehashtable_t *table, unsigned int key); //returns val, NULL if not found -int cachehashRemove(cachehashtable_t *table, unsigned int key); //returns -1 if not found -void cachehashResize(cachehashtable_t *table, unsigned int newsize); +unsigned int cachehashRemove(cachehashtable_t *table, unsigned int key); //returns -1 if not found +unsigned int cachehashResize(cachehashtable_t *table, unsigned int newsize); +void cachehashDelete(cachehashtable_t *table); /* end hash */ #endif diff --git a/Robust/src/Runtime/DSTM/interface/testclookup.c b/Robust/src/Runtime/DSTM/interface/testclookup.c new file mode 100644 index 00000000..e958e806 --- /dev/null +++ b/Robust/src/Runtime/DSTM/interface/testclookup.c @@ -0,0 +1,58 @@ +#include +#include "clookup.h" + +main() +{ + int i; + void *val; + cachehashtable_t *ctable; + + if (( ctable = cachehashCreate(20, 0.50)) == NULL) { + printf("cachehashCreate error\n"); //creates hashtable + } + + for (i = 1; i <= 10; i++) { // Checks the insert() and resize() + if (cachehashInsert(ctable, 10*i, &i) == 1) + printf("cachehashInsert error\n"); + } + + i = cachehashRemove(ctable, 10);//Delete first element in the hashtable + if(i == 1) + printf("cachehashRemove error "); + + for (i = 1; i <= 10; i++) { // Check if it can search for all keys in hash table + val = cachehashSearch(ctable, 10*i); + if (val != &i) + printf("cachehashSearch error - val = %d\n", val); + else + printf("cachehashSearch key = %d val = %x\n",10*i, val); + } + + i = cachehashRemove(ctable, 30); + if(i == 1) + printf("cachehashRemove error\n "); + i = cachehashRemove(ctable, 40); + if(i == 1) + printf("cachehashRemove error\n "); + i = cachehashRemove(ctable, 80); + if(i == 1) + printf("cachehashRemove error\n "); + i = cachehashRemove(ctable, 100); + if(i == 1) + printf("cachehashRemove error\n "); + i = cachehashRemove(ctable, 90); + if(i == 1) + printf("cachehashRemove error\n "); + + for (i = 1; i <= 10; i++) { //Prints all left over elements inside hash after deletion and prints error if element not found in hash + val = cachehashSearch(ctable, 10*i); + if (val != &i) + printf("cachehashSearch error - val = %d\n", val); + else + printf("cachehashSearch key = %d val = %x\n",10*i, val); + } + + printf("The total number of elements in table : %d\n", ctable->numelements); + +} +