#include "HashTable_WithStandardKeys.h" #include class t_Signal; using namespace std; // //template //inline bool t_HTStatusValue ::success() //{ // // return m_isSuccess; //} // //template //inline t_Value t_HTStatusValue ::getValue() //{ // return m_value; //} // //template //t_HTStatusValue ::t_HTStatusValue(bool status_to_update, t_Value v) //{ // m_value = v; // m_isSuccess = status_to_update; //} template inline t_Key t_HashTable :: t_HashTableEntry :: getKey() { return m_key; } template inline t_Value t_HashTable :: t_HashTableEntry :: getValue() { return m_value; } template t_HashTable :: t_HashTableEntry :: t_HashTableEntry():first(m_key), second(m_value) { } template t_HashTable :: t_HashTableEntry :: t_HashTableEntry (const t_Value& value_of_entry, const t_Key& key_of_entry): first(m_key), second(m_value) { m_value = value_of_entry; m_key = key_of_entry; m_next = NULL; } template inline void t_HashTable :: t_HashTableEntry:: printHashTableEntry() { cout<<"Key: "< t_HashTable :: t_HashTableEntryListHeader :: t_HashTableEntryListHeader() { m_next = NULL; } template inline t_index t_HashTable ::Hash(const string& string_to_hash) { /* needs three primes; assumes hashtable's size (m_Buckets.size()) is a prime; PRIME0, PRIME1 are both assumed to be < hashtable's size */ int hashval = 0; int i=0; while (string_to_hash[i]) { char c = string_to_hash[i]; hashval = (hashval*PRIME0 + c*PRIME1) % m_Buckets.size(); i++; } return hashval; } #ifdef KEEP_INT_HASH template inline t_index t_HashTable ::Hash(int integer_to_hash) { /* needs just two primes; hashtable's size (m_Buckets.size()) is assumed to be a prime PRIME1 is assumed to be less than hashtable's size */ int hashval = 0; while (integer_to_hash != 0) { int lastbit = integer_to_hash & 1; integer_to_hash = integer_to_hash >> 1; hashval = (hashval + lastbit*PRIME1) % m_Buckets.size(); } return hashval; } #endif template inline t_index t_HashTable ::Hash(unsigned long long int integer_to_hash) { /* needs just two primes; hashtable's size (m_Buckets.size()) is assumed to be a prime PRIME1 is assumed to be less than hashtable's size */ int hashval = 0; while (integer_to_hash != 0) { int lastbit = integer_to_hash & 1; integer_to_hash = integer_to_hash >> 1; hashval = (hashval*PRIME0 + lastbit*PRIME1) % m_Buckets.size(); } return hashval; } template vector t_HashTable::getCollisionCounts()const { vector coll; for(int i=0; im_next; ++count; } coll.push_back(count); } return coll; } template inline bool t_HashTable ::CompareKeys(const string& key1, const string& key2) { if(! key1.compare(key2)) return true; return false; } template inline bool t_HashTable ::CompareKeys(const int key1, const int key2) { return (key1 == key2); } template inline bool t_HashTable ::insertEntryInList(const t_index& index,const t_Value& value_to_insert, const t_Key& key) { t_HashTableEntryListHeader head=m_Buckets[index]; if(head.m_next == NULL) { t_HashTableEntry *entry_to_insert = new t_HashTableEntry (value_to_insert, key); if (entry_to_insert == NULL) { cerr << "Memory allocation failure while adding entry to HashTable" << endl; return false; } entry_to_insert->m_next = NULL; (m_Buckets[index]).m_next = entry_to_insert; m_nBucketsUsed +=1; //head.m_next=1 means this is new bucket return true; } else if(head.m_next != NULL) { t_HashTableEntryListHeader head = m_Buckets[index]; //head cannot be null here t_HashTableEntry *entry = head.m_next; while(entry->m_next != NULL) { entry = entry->m_next; } t_HashTableEntry *entry_to_insert = new t_HashTableEntry (value_to_insert, key); if (entry_to_insert == NULL) { cerr << "Memory allocation failure while adding entry to HashTable" << endl; return false; } entry_to_insert->m_next = NULL; entry->m_next = entry_to_insert; m_nCollisions += 1; return true; } return true; } template inline bool t_HashTable :: freeDynamicallyAllocatedMemory() { int counter = 0; int size = m_Buckets.size(); for(int i=0;im_next; delete(entry_to_delete); counter ++; } head.m_next = NULL; } } //cout<<"Freeed "< t_HashTable ::t_HashTable() { m_nKeysStored = 0; m_nCollisions = 0; m_nBucketsUsed = 0; #ifdef DEBUG cout<<"Created the HashTable \n"; #endif t_HashTableEntryListHeader entryHeader; m_Buckets.resize(m_SIZE, entryHeader); #ifdef DEBUG cout<<"HashTable size is "< t_HashTable ::t_HashTable(int size) { m_nKeysStored = 0; m_nCollisions = 0; m_nBucketsUsed = 0; cout<<"Created the HashTable \n"; t_HashTableEntryListHeader entryHeader; if(size<=0) { cerr<<"Invalid value for size entered "< t_HashTable ::~t_HashTable() { //Release the resources allocated to the HashTable entrys //cout<<"Freeing the memory\n"; bool free_mem_result = freeDynamicallyAllocatedMemory(); } template inline bool t_HashTable ::clear() { bool free_mem_result = freeDynamicallyAllocatedMemory(); if(!free_mem_result) { return false; } else { m_nKeysStored = 0; m_nCollisions = 0; m_nBucketsUsed = 0; return true; } } template inline t_HTStatusValue t_HashTable ::hashtable_insert(const t_Key& key, const t_Value& val) { t_HTStatusValue s = hashtable_search(key); if(s.success()) { // a entry with this key exists in the hashtable t_HTStatusValue result (false, s.getValue()); return result; } t_index index = Hash(key); //the hash functions always return 0<= Hash(key) result (false, Dummy_Val); return result; } t_HTStatusValue result (true, val); m_nKeysStored+=1; return result; } /** *The deletion of a value takes a reference to value. However, we cannot delete it directly. Need to search... * **/ template inline t_HTStatusValue t_HashTable ::hashtable_delete(const t_Key& key) { //REVIEW THIS CODE THOUROUGHLY t_index index = Hash(key); t_HashTableEntryListHeader head = m_Buckets[index]; if(head.m_next == NULL) { t_Value DummyValue=t_Value(); t_HTStatusValue result(false, DummyValue); return result; } else { t_HashTableEntry *entry = head.m_next; //head cannot be null here t_HashTableEntry *prev = NULL; //must specify the starting condition while(entry!=NULL) { t_Key current_key = entry->getKey(); if(CompareKeys(current_key,key)) { t_HTStatusValue result(true, entry->getValue()); t_HashTableEntry *entry_to_delete = entry; m_nKeysStored-=1; if(prev == NULL) { //first entry in the list (m_Buckets[index]).m_next = entry->m_next; // entry = entry->m_next; delete(entry_to_delete); m_nBucketsUsed -=1; //We are releasing this bucket... return result; } else if(entry->m_next==NULL) { //last but not the first entry in the list prev->m_next = entry->m_next; delete(entry_to_delete); m_nCollisions -= 1; return result; } else { //middle entry in the list prev->m_next = entry->m_next; // entry = entry->m_next; delete(entry_to_delete); m_nCollisions -= 1; return result; } } else { prev = entry; entry = entry->m_next; } } } t_Value DummyValue=t_Value(); t_HTStatusValue result(false, DummyValue); return result; } template inline t_HTStatusValue t_HashTable ::hashtable_search(const t_Key& key) { t_index index = Hash(key); t_HashTableEntryListHeader head = m_Buckets[index]; if(head.m_next == NULL) { t_Value Dummy_Val= t_Value(); t_HTStatusValue result (false, Dummy_Val); return result; } else { t_HashTableEntryListHeader head = m_Buckets[index]; //head cannot be null here t_HashTableEntry *entry = head.m_next; while(entry != NULL) { t_Key current_key = (t_Key)(entry->getKey()); if(CompareKeys(current_key,key)) { t_HTStatusValue result (true, entry->getValue()); return result; } entry = entry->m_next; } t_Value Dummy_Val=t_Value(); t_HTStatusValue result (false, Dummy_Val); return result; } } template inline t_Value& t_HashTable ::operator[](const t_Key& key) { t_index index = Hash(key); t_HashTableEntryListHeader head = m_Buckets[index]; if(head.m_next == NULL) { t_Value Dummy_Val; //t_HTStatusValue result (false, Dummy_Val); hashtable_insert(key, Dummy_Val); return (*this)[key]; //return result; } else { t_HashTableEntryListHeader head = m_Buckets[index]; //head cannot be null here t_HashTableEntry *entry = head.m_next; while(entry != NULL) { t_Key current_key = (t_Key)(entry->getKey()); if(CompareKeys(current_key,key)) { //t_HTStatusValue result (true, entry->getValue()); //return result; return entry->m_value; } entry = entry->m_next; } t_Value Dummy_Val; hashtable_insert(key, Dummy_Val); return (*this)[key]; //t_HTStatusValue result (false, Dummy_Val); //return result; } } template inline HashTableIterator t_HashTable::find(const t_Key& key) { t_index index = Hash(key); t_HashTableEntryListHeader head = m_Buckets[index]; if(head.m_next == NULL) { //t_Value Dummy_Val; //t_HTStatusValue result (false, Dummy_Val); return end(); //return result; } else { t_HashTableEntryListHeader head = m_Buckets[index]; //head cannot be null here t_HashTableEntry *entry = head.m_next; while(entry != NULL) { t_Key current_key = (t_Key)(entry->getKey()); if(CompareKeys(current_key,key)) { //t_HTStatusValue result (true, entry->getValue()); //return result; return HashTableIterator(*this, index, entry); } entry = entry->m_next; } return end(); //t_HTStatusValue result (false, Dummy_Val); //return result; } } /** * This function prints the hashtable, but only when standard values are used. Not otherwise. * * */ template inline void t_HashTable :: printHashTableKeys() { cout<<"Printing the keys in the hashtable\n"; //if somebody wants values as well, then he can use //1. hashtable_search(key) //2. print the value associated with key t_index index = 0; for(index =0;indexprintHashTableEntry(); entry = entry->m_next; } // cout< inline int t_HashTable :: getMaximumSizeOfHashTable() { return m_SIZE; } template inline float t_HashTable ::getLoadFactor() { return ((float)m_nKeysStored/m_SIZE); //Load factor w.r.t. size } template inline int t_HashTable :: getStoredKeysCount() { return m_nKeysStored; } template inline int t_HashTable :: getCountOfCollisions() { return m_nCollisions; } template inline int t_HashTable :: getNumberOfBucketsUsed() { return m_nBucketsUsed; } template class t_HashTable; template class t_HTStatusValue; /** Putting classes as arbitrary types does not work This means following code will not work template class t_HashTable ; template class t_HTStatusValue; */ class t_DAGNode; template class t_HashTable; template class t_HTStatusValue; template class t_HashTable; template class t_HashTable* >; template class t_HashTable; class t_Expression; template class t_HashTable; template class t_HashTable; //template class t_HashTable; template class t_HTStatusValue; template class t_HashTable; template class t_HashTable< string, bool>; template class t_HashTable; template class t_HashTable > >; template class t_HashTable >; #ifdef QE //#ifdef added by Ajith John on 24 July 2013 template class t_HashTable > >; #endif //#ifdef added by Ajith John on 24 July 2013 ends here #ifdef QE //#ifdef added by Ajith John on 8 Jan 2014 template class t_HashTable >; #endif //#ifdef added by Ajith John on 8 Jan 2014 ends here #ifdef QE //#ifdef added by Ajith John on 3 Feb 2014 template class t_HashTable; #endif //#ifdef added by Ajith John on 3 Feb 2014 ends here #ifdef QE //#ifdef added by Ajith John on 11 April 2014 template class t_HashTable; #endif //#ifdef added by Ajith John on 11 April 2014 ends here #ifdef QE //#ifdef added by Ajith John on 17 April 2014 template class t_HashTable >; #endif //#ifdef added by Ajith John on 17 April 2014 ends here #ifdef QE //#ifdef added by Ajith John on 15 March 2015: There's some problem with the // following code when linking is done. struct not supported? struct Aig_Obj_t; template class t_HashTable; template class t_HashTable; template class t_HTStatusValue; #endif //#ifdef added by Ajith John on 15 March 2015 ends here