}
//Store objects and their pointers into hash
-unsigned int chashInsert(chashtable_t *table, unsigned int key, void *val) {
+void chashInsert(chashtable_t *table, unsigned int key, void *val) {
unsigned int newsize;
int index;
chashlistnode_t *ptr, *node;
chashResize(table,newsize);
}
- ptr = table->table;
+ index = (key & table->mask) >>1;
+ ptr = &table->table[index];
table->numelements++;
- index = chashFunction(table, key);
-#ifdef DEBUG
- printf("chashInsert(): 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;
+
+ if(ptr->key==0) {
+ ptr->key=key;
+ ptr->val=val;
} else { // Insert in the beginning of linked list
- if ((node = calloc(1, sizeof(chashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
+ node = calloc(1, sizeof(chashlistnode_t));
node->key = key;
node->val = val;
- node->next = ptr[index].next;
- ptr[index].next = node;
+ node->next = ptr->next;
+ ptr->next=node;
}
- return 0;
}
// Search for an address for a given oid
}
unsigned int chashResize(chashtable_t *table, unsigned int newsize) {
- chashlistnode_t *node, *ptr, *curr, *next; // curr and next keep track of the current and the next chashlistnodes in a linked list
+ chashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next chashlistnodes in a linked list
unsigned int oldsize;
int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
- int i,index;
- chashlistnode_t *newnode;
-
+ unsigned int i,index;
+ unsigned int mask;
+
ptr = table->table;
oldsize = table->size;
table->table = node; //Update the global hashtable upon resize()
table->size = newsize;
table->threshold = newsize * table->loadfactor;
- table->mask = (newsize << 1)-1;
+ mask=table->mask = (newsize << 1)-1;
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
+ do { //Inner loop to go through linked lists
+ unsigned int key;
+ chashlistnode_t *tmp,*next;
+
+ if ((key=curr->key) == 0) { //Exit inner loop if there the first element is 0
break; //key = val =0 for element if not present within the hash table
}
next = curr->next;
-
- index = chashFunction(table, curr->key);
-#ifdef DEBUG
- printf("DEBUG(resize) -> index = %d, key = %d, val = %x\n", index, curr->key, curr->val);
-#endif
+ index = (key & mask) >>1;
+ tmp=&node[index];
// 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(chashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- return 1;
+ if(tmp->key == 0) {
+ tmp->key = curr->key;
+ tmp->val = curr->val;
+ if (!isfirst) {
+ free(curr);
}
+ } else if (isfirst) {
+ chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
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 chashlistnode_t if not the first element in the hash table
- if (isfirst != 1) {
- free(curr);
+ newnode->next = tmp->next;
+ tmp->next=newnode;
+ } else {
+ curr->next=tmp->next;
+ tmp->next=curr;
}
isfirst = 0;
curr = next;
- }
+ } while(curr!=NULL);
}
free(ptr); //Free the memory of the old hash table
//Delete the entire hash table
void chashDelete(chashtable_t *ctable) {
- int i, isFirst;
- chashlistnode_t *ptr, *curr, *next;
- ptr = ctable->table;
+ int i;
+ chashlistnode_t *ptr = ctable->table;
for(i=0 ; i<ctable->size ; i++) {
- curr = &ptr[i];
- isFirst = 1 ;
- while(curr != NULL) {
- next = curr->next;
- if(isFirst != 1) {
- free(curr);
- }
- isFirst = 0;
- curr = next;
+ chashlistnode_t * curr = ptr[i].next;
+ while(curr!=NULL) {
+ chashlistnode_t * next = curr->next;
+ free(curr);
+ curr=next;
}
}
-
free(ptr);
- ptr = NULL;
free(ctable);
- ctable = NULL;
}
/* Prototypes for hash*/
chashtable_t *chashCreate(unsigned int size, double loadfactor);
static unsigned int chashFunction(chashtable_t *table, unsigned int key);
-unsigned int chashInsert(chashtable_t *table, unsigned int key, void *val);
+void chashInsert(chashtable_t *table, unsigned int key, void *val);
void *chashSearch(chashtable_t *table, unsigned int key); //returns val, NULL if not found
unsigned int chashRemove(chashtable_t *table, unsigned int key); //returns -1 if not found
void * chashRemove2(chashtable_t *table, unsigned int key); //returns -1 if not found
/* Prototypes for object store */
objstr_t *objstrCreate(unsigned int size); //size in bytes
void objstrDelete(objstr_t *store); //traverse and free entire list
-void *objstrAlloc(objstr_t *store, unsigned int size); //size in bytes
+void *objstrAlloc(objstr_t **store, unsigned int size); //size in bytes
void clearObjStore(); // TODO:currently only clears the prefetch cache object store
/* end object store */
mhashtable_t mlookup; //Global hash table
// Creates a machine lookup table with size =" size"
-unsigned int mhashCreate(unsigned int size, float loadfactor) {
+unsigned int mhashCreate(unsigned int size, double loadfactor) {
mhashlistnode_t *nodes;
// Allocate space for the hash table
if((nodes = calloc(size, sizeof(mhashlistnode_t))) == NULL) {
mlookup.table = nodes;
mlookup.size = size;
+ mlookup.threshold=size*loadfactor;
mlookup.mask = (size << 1) -1;
mlookup.numelements = 0; // Initial number of elements in the hash
mlookup.loadfactor = loadfactor;
}
// Insert value and key mapping into the hash table
-unsigned int mhashInsert(unsigned int key, void *val) {
+void mhashInsert(unsigned int key, void *val) {
unsigned int newsize;
int index;
mhashlistnode_t *ptr, *node;
- if (mlookup.numelements > (mlookup.loadfactor * mlookup.size)) {
+ pthread_mutex_lock(&mlookup.locktable);
+ if (mlookup.numelements > mlookup.threshold) {
//Resize Table
newsize = mlookup.size << 1;
- pthread_mutex_lock(&mlookup.locktable);
mhashResize(newsize);
- pthread_mutex_unlock(&mlookup.locktable);
}
- ptr = mlookup.table;
+ index = (key & mlookup.mask) >>1;
+ ptr = &mlookup.table[index];
mlookup.numelements++;
-#ifdef DEBUG
- printf("DEBUG -> index = %d, key = %d, val = %x\n", index, key, val);
-#endif
- pthread_mutex_lock(&mlookup.locktable);
- index = mhashFunction(key);
- 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;
+
+ if(ptr->key ==0) {
+ ptr->key=key;
+ ptr->val=val;
} else { // Insert in the beginning of linked list
- if ((node = calloc(1, sizeof(mhashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- pthread_mutex_unlock(&mlookup.locktable);
- return 1;
- }
+ node = calloc(1, sizeof(mhashlistnode_t));
node->key = key;
node->val = val;
- node->next = ptr[index].next;
- ptr[index].next = node;
+ node->next = ptr->next;
+ ptr->next=node;
}
pthread_mutex_unlock(&mlookup.locktable);
- return 0;
}
// Return val for a given key in the hash table
return 1;
}
+
+
// Resize table
unsigned int mhashResize(unsigned int newsize) {
- mhashlistnode_t *node, *ptr, *curr, *next; // curr and next keep track of the current and the next mhashlistnodes in a linked list
+ mhashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next mhashlistnodes in a linked list
unsigned int oldsize;
int isfirst; // Keeps track of the first element in the mhashlistnode_t for each bin in hashtable
- int i,index;
- mhashlistnode_t *newnode;
+ unsigned int i,index;
+ unsigned int mask;
ptr = mlookup.table;
oldsize = mlookup.size;
mlookup.table = node; //Update the global hashtable upon resize()
mlookup.size = newsize;
- mlookup.mask = (newsize << 1)-1;
- mlookup.numelements = 0;
+ mlookup.threshold=newsize*mlookup.loadfactor;
+ mask=mlookup.mask = (newsize << 1)-1;
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
+ do {
+ unsigned int key;
+ mhashlistnode_t *tmp,*next;
+
+ if ((key=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 = (key & mask) >>1;
+ tmp=&mlookup.table[index];
- index = mhashFunction(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(mlookup.table[index].next == NULL && mlookup.table[index].key == 0) {
- mlookup.table[index].key = curr->key;
- mlookup.table[index].val = curr->val;
- mlookup.numelements++;
- } else {
- if((newnode = calloc(1, sizeof(mhashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
+ if(tmp->key ==0) {
+ tmp->key=curr->key;
+ tmp->val=curr->val;
+ if (!isfirst)
+ free(curr);
+ } else if (isfirst) {
+ mhashlistnode_t *newnode = calloc(1, sizeof(mhashlistnode_t));
newnode->key = curr->key;
newnode->val = curr->val;
- newnode->next = mlookup.table[index].next;
- mlookup.table[index].next = newnode;
- mlookup.numelements++;
- }
-
- //free the linked list of mhashlistnode_t if not the first element in the hash table
- if (isfirst != 1) {
- free(curr);
+ newnode->next = tmp->next;
+ tmp->next=newnode;
+ } else {
+ curr->next=tmp;
+ tmp->next=curr;
}
-
isfirst = 0;
curr = next;
-
- }
+ } while(curr!=NULL);
}
free(ptr); //Free the memory of the old hash table
unsigned int size;
unsigned int mask;
unsigned int numelements;
- float loadfactor;
+ unsigned int threshold;
+ double loadfactor;
pthread_mutex_t locktable;
} mhashtable_t;
-unsigned int mhashCreate(unsigned int size, float loadfactor);
+unsigned int mhashCreate(unsigned int size, double loadfactor);
unsigned int mhashFunction(unsigned int key);
-unsigned mhashInsert(unsigned int key, void *val);
+void mhashInsert(unsigned int key, void *val);
void *mhashSearch(unsigned int key); //returns val, NULL if not found
unsigned int mhashRemove(unsigned int key); //returns -1 if not found
unsigned int mhashResize(unsigned int newsize);
#include "dstm.h"
+#define OSUSED(x) (((unsigned int)(x)->top)-((unsigned int) (x+1)))
+#define OSFREE(x) ((x)->size-OSUSED(x))
+
objstr_t *objstrCreate(unsigned int size) {
objstr_t *tmp;
if((tmp = calloc(1, (sizeof(objstr_t) + size))) == NULL) {
return;
}
-void *objstrAlloc(objstr_t *store, unsigned int size) {
+void *objstrAlloc(objstr_t **osptr, unsigned int size) {
void *tmp;
- while (1) {
- if (((unsigned int)store->top - (((unsigned int)store) + sizeof(objstr_t)) + size) <= store->size) { //store not full
- tmp = store->top;
- store->top += size;
+ int i=0;
+ objstr_t *store=*osptr;
+ for(;i<3;i++) {
+ if (OSFREE(store)>=size) {
+ tmp=store->top;
+ store->top +=size;
return tmp;
}
- //store full
- if (store->next == NULL) {
- //end of list, all full
- if (size > DEFAULT_OBJ_STORE_SIZE) {
- //in case of large objects
- if((store->next = (objstr_t *)calloc(1,(sizeof(objstr_t) + size))) == NULL) {
- printf("%s() Calloc error at line %d, %s\n", __func__, __LINE__, __FILE__);
- return NULL;
- }
- store = store->next;
- store->size = size;
- } else {
- if((store->next = calloc(1,(sizeof(objstr_t) + DEFAULT_OBJ_STORE_SIZE))) == NULL) {
- printf("%s() Calloc error at line %d, %s\n", __func__, __LINE__, __FILE__);
- return NULL;
- }
- store = store->next;
- store->size = DEFAULT_OBJ_STORE_SIZE;
- }
- store->top = (void *)(((unsigned int)store) + sizeof(objstr_t) + size);
- return (void *)(((unsigned int)store) + sizeof(objstr_t));
- } else
- store = store->next;
+ if ((store=store->next)==NULL)
+ break;
+ }
+
+ {
+ unsigned int newsize=size>DEFAULT_OBJ_STORE_SIZE?size:DEFAULT_OBJ_STORE_SIZE;
+ objstr_t *os=(objstr_t *)calloc(1,(sizeof(objstr_t) + newsize));
+ void *ptr=&os[1];
+ os->next=store;
+ (*osptr)=os;
+ os->size=newsize;
+ os->top=((char *)ptr)+size;
+ return ptr;
}
}
pflookup.mask = (size << 1) -1;
pflookup.numelements = 0; // Initial number of elements in the hash
pflookup.loadfactor = loadfactor;
+ pflookup.threshold=loadfactor*size;
//Intiliaze and set prefetch table mutex attribute
pthread_mutexattr_init(&pflookup.prefetchmutexattr);
}
//Store oids and their pointers into hash
-unsigned int prehashInsert(unsigned int key, void *val) {
+void prehashInsert(unsigned int key, void *val) {
unsigned int newsize;
int index;
prehashlistnode_t *ptr, *node;
+ pthread_mutex_lock(&pflookup.lock);
- if(pflookup.numelements > (pflookup.loadfactor * pflookup.size)) {
+ if(pflookup.numelements > (pflookup.threshold)) {
//Resize
newsize = pflookup.size << 1;
- pthread_mutex_lock(&pflookup.lock);
prehashResize(newsize);
- pthread_mutex_unlock(&pflookup.lock);
}
- ptr = pflookup.table;
+ index = (key & pflookup.mask)>>1;
+ ptr = &pflookup.table[index];
pflookup.numelements++;
- pthread_mutex_lock(&pflookup.lock);
- index = prehashFunction(key);
- 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;
+ if(ptr->key==0) {
+ ptr->key = key;
+ ptr->val = val;
} else { // Insert in the beginning of linked list
- if ((node = calloc(1, sizeof(prehashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- pthread_mutex_unlock(&pflookup.lock);
- return 1;
- }
+ node = calloc(1, sizeof(prehashlistnode_t));
node->key = key;
node->val = val ;
- node->next = ptr[index].next;
- ptr[index].next = node;
+ node->next = ptr->next;
+ ptr->next=node;
}
pthread_mutex_unlock(&pflookup.lock);
- return 0;
}
// Search for an address for a given oid
}
unsigned int prehashResize(unsigned int newsize) {
- prehashlistnode_t *node, *ptr, *curr, *next; // curr and next keep track of the current and the next chashlistnodes in a linked list
+ prehashlistnode_t *node, *ptr; // curr and next keep track of the current and the next chashlistnodes in a linked list
unsigned int oldsize;
- int isfirst; // Keeps track of the first element in the prehashlistnode_t for each bin in hashtable
int i,index;
- prehashlistnode_t *newnode;
+ unsigned int mask;
ptr = pflookup.table;
oldsize = pflookup.size;
pflookup.table = node; //Update the global hashtable upon resize()
pflookup.size = newsize;
- pflookup.mask = (newsize << 1) -1;
- pflookup.numelements = 0;
+ pflookup.threshold=newsize*pflookup.loadfactor;
+ mask=pflookup.mask = (newsize << 1) -1;
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
+ prehashlistnode_t * curr = &ptr[i];
+ prehashlistnode_t *tmp, *next;
+ int isfirst = 1;
+ do {
+ unsigned int key;
+ if ((key=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 = prehashFunction(curr->key);
+ index = (key & mask)>>1;
+ tmp=&pflookup.table[index];
// Insert into the new table
- if(pflookup.table[index].next == NULL && pflookup.table[index].key == 0) {
- pflookup.table[index].key = curr->key;
- pflookup.table[index].val = curr->val;
- pflookup.numelements++;
- } else {
- if((newnode = calloc(1, sizeof(prehashlistnode_t))) == NULL) {
- printf("Calloc error %s, %d\n", __FILE__, __LINE__);
- return 1;
- }
+ if(tmp->key==0) {
+ tmp->key=curr->key;
+ tmp->val=curr->val;
+ if (!isfirst)
+ free(curr);
+ } else if (isfirst) {
+ prehashlistnode_t * newnode = calloc(1, sizeof(prehashlistnode_t));
newnode->key = curr->key;
newnode->val = curr->val;
- newnode->next = pflookup.table[index].next;
- pflookup.table[index].next = newnode;
- pflookup.numelements++;
- }
-
- //free the linked list of prehashlistnode_t if not the first element in the hash table
- if (isfirst != 1) {
- free(curr);
+ newnode->next = tmp->next;
+ tmp->next=newnode;
+ } else {
+ curr->next=tmp->next;
+ tmp->next=curr;
}
isfirst = 0;
curr = next;
- }
+ } while(curr!=NULL);
}
free(ptr); //Free the memory of the old hash table
unsigned int size;
unsigned int mask;
unsigned int numelements;
- float loadfactor;
+ unsigned int threshold;
+ double loadfactor;
pthread_mutex_t lock;
pthread_mutexattr_t prefetchmutexattr;
pthread_cond_t cond;
/* Prototypes for hash*/
unsigned int prehashCreate(unsigned int size, float loadfactor);
unsigned int prehashFunction(unsigned int key);
-unsigned int prehashInsert(unsigned int key, void *val);
+void prehashInsert(unsigned int key, void *val);
void *prehashSearch(unsigned int key); //returns val, NULL if not found
unsigned int prehashRemove(unsigned int key); //returns -1 if not found
unsigned int prehashResize(unsigned int newsize);
/* Look up in machine lookup table and copy into cache*/
GETSIZE(size, objheader);
size += sizeof(objheader_t);
- objcopy = (objheader_t *) objstrAlloc(record->cache, size);
+ objcopy = (objheader_t *) objstrAlloc(&record->cache, size);
memcpy(objcopy, objheader, size);
/* Insert into cache's lookup table */
STATUS(objcopy)=0;
/* Look up in prefetch cache */
GETSIZE(size, tmp);
size+=sizeof(objheader_t);
- objcopy = (objheader_t *) objstrAlloc(record->cache, size);
+ objcopy = (objheader_t *) objstrAlloc(&record->cache, size);
memcpy(objcopy, tmp, size);
/* Insert into cache's lookup table */
chashInsert(record->lookupTable, OID(tmp), objcopy);
/* This function creates objects in the transaction record */
objheader_t *transCreateObj(transrecord_t *record, unsigned int size) {
- objheader_t *tmp = (objheader_t *) objstrAlloc(record->cache, (sizeof(objheader_t) + size));
+ objheader_t *tmp = (objheader_t *) objstrAlloc(&record->cache, (sizeof(objheader_t) + size));
OID(tmp) = getNewOID();
tmp->version = 1;
tmp->rcount = 1;
} else {
/* Read object if found into local cache */
recv_data(sd, &size, sizeof(int));
- objcopy = objstrAlloc(record->cache, size);
+ objcopy = objstrAlloc(&record->cache, size);
recv_data(sd, objcopy, size);
STATUS(objcopy)=0;
/* Insert into cache's lookup table */
GETSIZE(tmpsize, header);
tmpsize += sizeof(objheader_t);
pthread_mutex_lock(&mainobjstore_mutex);
- if ((ptrcreate = objstrAlloc(mainobjstore, tmpsize)) == NULL) {
+ if ((ptrcreate = objstrAlloc(&mainobjstore, tmpsize)) == NULL) {
printf("Error: transComProcess() failed objstrAlloc %s, %d\n", __FILE__, __LINE__);
pthread_mutex_unlock(&mainobjstore_mutex);
return 1;