From 62016d94a3f60c4f6064af39898cdb12af8b6c43 Mon Sep 17 00:00:00 2001 From: Iurii Tatishchev Date: Tue, 18 Jun 2024 16:35:55 -0700 Subject: [PATCH] implement initial version of list and rehash (rehash has issues) --- DisplayManager.h | 18 ++++++++++-------- HashTable.h | 37 +++++++++++++++++++++++++++++++++++++ SearchManager.h | 14 ++++++++------ UndoManager.h | 12 ++++++------ fio.cpp | 47 +++++------------------------------------------ main.cpp | 14 +++++++++----- utils.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ utils.h | 2 ++ 8 files changed, 117 insertions(+), 67 deletions(-) diff --git a/DisplayManager.h b/DisplayManager.h index 2321f0f..7d27e38 100644 --- a/DisplayManager.h +++ b/DisplayManager.h @@ -8,19 +8,21 @@ template class DisplayManager { private: - HashTable hashTable; - BinarySearchTree bst; + HashTable *hashTable; + BinarySearchTree *bst; public: - DisplayManager(HashTable& ht, BinarySearchTree& bst); + DisplayManager(HashTable *ht, BinarySearchTree *bst); + ~DisplayManager(); void displayAll() const; + void displayTree() const; }; template -DisplayManager::DisplayManager(HashTable &ht, BinarySearchTree &bst) { +DisplayManager::DisplayManager(HashTable *ht, BinarySearchTree *bst) { this->hashTable = ht; this->bst = bst; } @@ -35,9 +37,9 @@ void DisplayManager::displayAll() const { std::cout << "All CPUs in the database:" << std::endl; // Iterate over the HashTable and display each CPU - for (int i = 0; i < hashTable.getSize(); i++) { - if (hashTable.getItem(i) != nullptr) { - std::cout << *(hashTable.getItem(i)) << std::endl; + for (int i = 0; i < hashTable->getCount(); i++) { + if (hashTable->getItem(i) != nullptr) { + std::cout << *(hashTable->getItem(i)) << std::endl; } } } @@ -48,7 +50,7 @@ void DisplayManager::displayTree() const { // Call the BST's inorder traversal method to display the tree // TODO: Use a proper display function - bst.inOrder([](const std::string& key) { + bst->inOrder([](const std::string &key) { std::cout << key << std::endl; }); } diff --git a/HashTable.h b/HashTable.h index 70ea525..50d9c97 100644 --- a/HashTable.h +++ b/HashTable.h @@ -4,6 +4,7 @@ #include #include "HashNode.h" #include "CPU.h" +#include "utils.h" using std::string, std::ofstream, std::cout, std::endl; @@ -50,6 +51,8 @@ public: int search(T &itemOut, const T &key, int h(const T &key, int size)) const; void outputFile(const string &filename, string visit(const T &)); + + void reHash(int h(const T &key, int size)); }; /*~*~*~* @@ -185,4 +188,38 @@ void HashTable::outputFile(const string &filename, string visit(const T &)) { outputFile.close(); } +template +void HashTable::reHash(int h(const T &key, int size)){ + + int nHashSize = hashSize * 2; + + nHashSize = findNextPrime(nHashSize); + + HashNode* nHashAry = new HashNode[nHashSize]; + + // Goes through each bucket and puts it in the new array + T aT; + for(int i = 0; i < hashSize; i++){ + if(hashAry[i].getOccupied() == 1){ + aT = hashAry[i].getItem(); + + int nIndex = h(aT, nHashSize); + + for(int j = 0; j < hashSize; j++){ + if(nHashAry[nIndex].getOccupied() != 1){ + nHashAry[nIndex].setItem(aT); + nHashAry[nIndex].setOccupied(1); + nHashAry[nIndex].setNumCollisions(i); + break; + } + + nIndex = (nIndex + 1) % hashSize; + } + } + } + + hashAry = nHashAry; + hashSize = nHashSize; +} + #endif // INC_08_TEAM_PROJECT_HASHTABLE_H diff --git a/SearchManager.h b/SearchManager.h index d3d8ed1..428c9ce 100644 --- a/SearchManager.h +++ b/SearchManager.h @@ -7,16 +7,16 @@ template class SearchManager { private: - HashTable hashTable; + HashTable *hashTable; public: - SearchManager(HashTable &ht); + SearchManager(HashTable *ht); void searchCPU() const; }; template -SearchManager::SearchManager(HashTable &ht) { +SearchManager::SearchManager(HashTable *ht) { this->hashTable = ht; } @@ -27,11 +27,13 @@ void SearchManager::searchCPU() const { std::cin >> cpuID; // Search for the CPU in the HashTable - CPU *foundCPU = hashTable.search(cpuID); + CPU foundCPU; + foundCPU.setCpuId(cpuID); + int collisionCount = hashTable->search(foundCPU, foundCPU, key_to_index); - if (foundCPU != nullptr) { + if (collisionCount != -1) { std::cout << "CPU found:" << std::endl; - std::cout << *foundCPU << std::endl; + std::cout << foundCPU << std::endl; } else { std::cout << "CPU not found." << std::endl; } diff --git a/UndoManager.h b/UndoManager.h index 2b4ee22..e0f77fb 100644 --- a/UndoManager.h +++ b/UndoManager.h @@ -9,12 +9,12 @@ template class UndoManager { private: - HashTable hashTable; - BinarySearchTree bst; + HashTable *hashTable; + BinarySearchTree *bst; Stack *undoStack; public: - UndoManager(HashTable &ht, BinarySearchTree &bst); + UndoManager(HashTable *ht, BinarySearchTree *bst); ~UndoManager(); @@ -26,7 +26,7 @@ public: }; template -UndoManager::UndoManager(HashTable &ht, BinarySearchTree &bst) { +UndoManager::UndoManager(HashTable *ht, BinarySearchTree *bst) { this->hashTable = ht; this->bst = bst; this->undoStack = new Stack(); @@ -48,8 +48,8 @@ void UndoManager::undoDelete() { T lastDeleted = undoStack->pop(); // Reinsert the CPU into the HashTable and BST - hashTable.insert(lastDeleted, key_to_index); - bst.insert(lastDeleted.getCpuId()); + hashTable->insert(lastDeleted, key_to_index); + bst->insert(lastDeleted.getCpuId()); std::cout << "Undo successful. CPU reinserted:" << std::endl; std::cout << lastDeleted << std::endl; diff --git a/fio.cpp b/fio.cpp index e2d4ea0..cf64c51 100644 --- a/fio.cpp +++ b/fio.cpp @@ -7,7 +7,7 @@ bool isDouble(const string &str); using std::stringstream, std::ifstream, std::getline, std::cout, std::endl, std::stoi, std::stod, std::cin; -int findHashSize(const string& filename) { +int findHashSize(const string &filename) { ifstream inputFile(filename); if (!inputFile) { @@ -25,47 +25,10 @@ int findHashSize(const string& filename) { } count *= 2; - - if (count < 5) { - return 5; - } - - bool found = false; - - while (!found) { - // Every prime number occurs only 1 number before or after a multiple of six. Every other number is divisible by either 2 or 3. - if ((count % 6) == 1) { - count += 4; - } else if ((count % 6) == 5) { - count += 2; - } else if ((count % 6) >= 2) { - count = count - (count % 6) + 5; - } else { - count += 1; - } - - found = true; - for (int i = 5; i < count / 2;) { - if (count % i == 0) { - found = false; - break; - } - - i += 2; - - if (count % i == 0) { - found = false; - break; - } - - i += 4; - } - } - - return count; + return findNextPrime(count); } -void insertFile(const string& filename, BinarySearchTree &bst, HashTable &hash) { +void insertFile(const string &filename, BinarySearchTree &bst, HashTable &hash) { ifstream inputFile(filename); cout << "Reading data from \"" << filename << "\"" << endl; @@ -172,7 +135,7 @@ void insertCPU(BinarySearchTree &bst, HashTable &hash) { hash.insert(aCPU, key_to_index); } -bool isInteger(const string& str) { +bool isInteger(const string &str) { for (int i = 0; i < str.length(); i++) { if (!(isdigit(str[i]))) { return false; @@ -182,7 +145,7 @@ bool isInteger(const string& str) { return true; } -bool isDouble(const string& str) { +bool isDouble(const string &str) { int chance = 0; for (int i = 0; i < str.length(); i++) { diff --git a/main.cpp b/main.cpp index 5b432e7..5b88414 100644 --- a/main.cpp +++ b/main.cpp @@ -51,9 +51,9 @@ int main() { BinarySearchTree cpuTree; // Stack undoStack; - DisplayManager displayManager(cpuTable, cpuTree); - SearchManager searchManager(cpuTable); - UndoManager undoManager(cpuTable, cpuTree); + DisplayManager displayManager(&cpuTable, &cpuTree); + SearchManager searchManager(&cpuTable); + UndoManager undoManager(&cpuTable, &cpuTree); char command = ' '; while (command != 'Q') { @@ -104,10 +104,10 @@ void processInput(char command, HashTable &cpuTable, BinarySearchTree &cpuTable, BinarySearchTree &hashTable, BinarySearchTree &tree) { + if (hashTable.getLoadFactor() >= 75) { + cout << "Load factor is " << hashTable.getLoadFactor() << ". Rehashing...\n"; + hashTable.reHash(key_to_index); + } insertCPU(tree, hashTable); } diff --git a/utils.cpp b/utils.cpp index 0e081c6..28b37c9 100644 --- a/utils.cpp +++ b/utils.cpp @@ -102,3 +102,43 @@ void printTeam() { }; printTable(teamWidths, teamData); } + +int findNextPrime(int n) { + if (n < 5) { + return 5; + } + + bool found = false; + + while (!found) { + // Every prime number occurs only 1 number before or after a multiple of six. Every other number is divisible by either 2 or 3. + if ((n % 6) == 1) { + n += 4; + } else if ((n % 6) == 5) { + n += 2; + } else if ((n % 6) >= 2) { + n = n - (n % 6) + 5; + } else { + n += 1; + } + + found = true; + for (int i = 5; i < n / 2;) { + if (n % i == 0) { + found = false; + break; + } + + i += 2; + + if (n % i == 0) { + found = false; + break; + } + + i += 4; + } + } + + return n; +} diff --git a/utils.h b/utils.h index 0599f65..bc1fdb8 100644 --- a/utils.h +++ b/utils.h @@ -13,4 +13,6 @@ void printHelp(); void printTeam(); +int findNextPrime(int n); + #endif //INC_08_TEAM_PROJECT_UTILS_H