implement initial version of list and rehash (rehash has issues)

This commit is contained in:
Iurii Tatishchev 2024-06-18 16:35:55 -07:00
parent 261acea264
commit 62016d94a3
Signed by: CaZzzer
GPG Key ID: E0EBF441EA424369
8 changed files with 117 additions and 67 deletions

View File

@ -8,19 +8,21 @@
template<typename T> template<typename T>
class DisplayManager { class DisplayManager {
private: private:
HashTable<T> hashTable; HashTable<T> *hashTable;
BinarySearchTree<std::string> bst; BinarySearchTree<std::string> *bst;
public: public:
DisplayManager(HashTable<T>& ht, BinarySearchTree<std::string>& bst); DisplayManager(HashTable<T> *ht, BinarySearchTree<std::string> *bst);
~DisplayManager(); ~DisplayManager();
void displayAll() const; void displayAll() const;
void displayTree() const; void displayTree() const;
}; };
template<typename T> template<typename T>
DisplayManager<T>::DisplayManager(HashTable<T> &ht, BinarySearchTree<std::string> &bst) { DisplayManager<T>::DisplayManager(HashTable<T> *ht, BinarySearchTree<std::string> *bst) {
this->hashTable = ht; this->hashTable = ht;
this->bst = bst; this->bst = bst;
} }
@ -35,9 +37,9 @@ void DisplayManager<T>::displayAll() const {
std::cout << "All CPUs in the database:" << std::endl; std::cout << "All CPUs in the database:" << std::endl;
// Iterate over the HashTable and display each CPU // Iterate over the HashTable and display each CPU
for (int i = 0; i < hashTable.getSize(); i++) { for (int i = 0; i < hashTable->getCount(); i++) {
if (hashTable.getItem(i) != nullptr) { if (hashTable->getItem(i) != nullptr) {
std::cout << *(hashTable.getItem(i)) << std::endl; std::cout << *(hashTable->getItem(i)) << std::endl;
} }
} }
} }
@ -48,7 +50,7 @@ void DisplayManager<T>::displayTree() const {
// Call the BST's inorder traversal method to display the tree // Call the BST's inorder traversal method to display the tree
// TODO: Use a proper display function // TODO: Use a proper display function
bst.inOrder([](const std::string& key) { bst->inOrder([](const std::string &key) {
std::cout << key << std::endl; std::cout << key << std::endl;
}); });
} }

View File

@ -4,6 +4,7 @@
#include <fstream> #include <fstream>
#include "HashNode.h" #include "HashNode.h"
#include "CPU.h" #include "CPU.h"
#include "utils.h"
using std::string, std::ofstream, std::cout, std::endl; 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; 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 outputFile(const string &filename, string visit(const T &));
void reHash(int h(const T &key, int size));
}; };
/*~*~*~* /*~*~*~*
@ -185,4 +188,38 @@ void HashTable<T>::outputFile(const string &filename, string visit(const T &)) {
outputFile.close(); outputFile.close();
} }
template<class T>
void HashTable<T>::reHash(int h(const T &key, int size)){
int nHashSize = hashSize * 2;
nHashSize = findNextPrime(nHashSize);
HashNode<T>* nHashAry = new HashNode<T>[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 #endif // INC_08_TEAM_PROJECT_HASHTABLE_H

View File

@ -7,16 +7,16 @@
template<typename T> template<typename T>
class SearchManager { class SearchManager {
private: private:
HashTable<T> hashTable; HashTable<T> *hashTable;
public: public:
SearchManager(HashTable<T> &ht); SearchManager(HashTable<T> *ht);
void searchCPU() const; void searchCPU() const;
}; };
template<typename T> template<typename T>
SearchManager<T>::SearchManager(HashTable<T> &ht) { SearchManager<T>::SearchManager(HashTable<T> *ht) {
this->hashTable = ht; this->hashTable = ht;
} }
@ -27,11 +27,13 @@ void SearchManager<T>::searchCPU() const {
std::cin >> cpuID; std::cin >> cpuID;
// Search for the CPU in the HashTable // 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 << "CPU found:" << std::endl;
std::cout << *foundCPU << std::endl; std::cout << foundCPU << std::endl;
} else { } else {
std::cout << "CPU not found." << std::endl; std::cout << "CPU not found." << std::endl;
} }

View File

@ -9,12 +9,12 @@
template<typename T> template<typename T>
class UndoManager { class UndoManager {
private: private:
HashTable<T> hashTable; HashTable<T> *hashTable;
BinarySearchTree<std::string> bst; BinarySearchTree<std::string> *bst;
Stack<T> *undoStack; Stack<T> *undoStack;
public: public:
UndoManager(HashTable<T> &ht, BinarySearchTree<std::string> &bst); UndoManager(HashTable<T> *ht, BinarySearchTree<std::string> *bst);
~UndoManager(); ~UndoManager();
@ -26,7 +26,7 @@ public:
}; };
template<typename T> template<typename T>
UndoManager<T>::UndoManager(HashTable<T> &ht, BinarySearchTree<std::string> &bst) { UndoManager<T>::UndoManager(HashTable<T> *ht, BinarySearchTree<std::string> *bst) {
this->hashTable = ht; this->hashTable = ht;
this->bst = bst; this->bst = bst;
this->undoStack = new Stack<CPU>(); this->undoStack = new Stack<CPU>();
@ -48,8 +48,8 @@ void UndoManager<T>::undoDelete() {
T lastDeleted = undoStack->pop(); T lastDeleted = undoStack->pop();
// Reinsert the CPU into the HashTable and BST // Reinsert the CPU into the HashTable and BST
hashTable.insert(lastDeleted, key_to_index); hashTable->insert(lastDeleted, key_to_index);
bst.insert(lastDeleted.getCpuId()); bst->insert(lastDeleted.getCpuId());
std::cout << "Undo successful. CPU reinserted:" << std::endl; std::cout << "Undo successful. CPU reinserted:" << std::endl;
std::cout << lastDeleted << std::endl; std::cout << lastDeleted << std::endl;

47
fio.cpp
View File

@ -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; 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); ifstream inputFile(filename);
if (!inputFile) { if (!inputFile) {
@ -25,47 +25,10 @@ int findHashSize(const string& filename) {
} }
count *= 2; count *= 2;
return findNextPrime(count);
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;
} }
void insertFile(const string& filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash) { void insertFile(const string &filename, BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
ifstream inputFile(filename); ifstream inputFile(filename);
cout << "Reading data from \"" << filename << "\"" << endl; cout << "Reading data from \"" << filename << "\"" << endl;
@ -172,7 +135,7 @@ void insertCPU(BinarySearchTree<string> &bst, HashTable<CPU> &hash) {
hash.insert(aCPU, key_to_index); hash.insert(aCPU, key_to_index);
} }
bool isInteger(const string& str) { bool isInteger(const string &str) {
for (int i = 0; i < str.length(); i++) { for (int i = 0; i < str.length(); i++) {
if (!(isdigit(str[i]))) { if (!(isdigit(str[i]))) {
return false; return false;
@ -182,7 +145,7 @@ bool isInteger(const string& str) {
return true; return true;
} }
bool isDouble(const string& str) { bool isDouble(const string &str) {
int chance = 0; int chance = 0;
for (int i = 0; i < str.length(); i++) { for (int i = 0; i < str.length(); i++) {

View File

@ -51,9 +51,9 @@ int main() {
BinarySearchTree<string> cpuTree; BinarySearchTree<string> cpuTree;
// Stack<CPU> undoStack; // Stack<CPU> undoStack;
DisplayManager<CPU> displayManager(cpuTable, cpuTree); DisplayManager<CPU> displayManager(&cpuTable, &cpuTree);
SearchManager<CPU> searchManager(cpuTable); SearchManager<CPU> searchManager(&cpuTable);
UndoManager<CPU> undoManager(cpuTable, cpuTree); UndoManager<CPU> undoManager(&cpuTable, &cpuTree);
char command = ' '; char command = ' ';
while (command != 'Q') { while (command != 'Q') {
@ -104,10 +104,10 @@ void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<strin
undoManager.undoDelete(); undoManager.undoDelete();
break; break;
case 'L': // List all CPUs sorted by primary key case 'L': // List all CPUs sorted by primary key
throw std::logic_error("Not yet implemented: List all CPUs sorted by primary key"); displayManager.displayTree();
break; break;
case 'S': // Search for a CPU by the primary key case 'S': // Search for a CPU by the primary key
throw std::logic_error("Not yet implemented: Search for a CPU by the primary key"); searchManager.searchCPU();
break; break;
case 'W': // Write data to a file case 'W': // Write data to a file
handleFileOutput(cpuTable, undoManager); handleFileOutput(cpuTable, undoManager);
@ -131,6 +131,10 @@ void processInput(char command, HashTable<CPU> &cpuTable, BinarySearchTree<strin
} }
void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree) { void handleInsert(HashTable<CPU> &hashTable, BinarySearchTree<string> &tree) {
if (hashTable.getLoadFactor() >= 75) {
cout << "Load factor is " << hashTable.getLoadFactor() << ". Rehashing...\n";
hashTable.reHash(key_to_index);
}
insertCPU(tree, hashTable); insertCPU(tree, hashTable);
} }

View File

@ -102,3 +102,43 @@ void printTeam() {
}; };
printTable(teamWidths, teamData); 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;
}

View File

@ -13,4 +13,6 @@ void printHelp();
void printTeam(); void printTeam();
int findNextPrime(int n);
#endif //INC_08_TEAM_PROJECT_UTILS_H #endif //INC_08_TEAM_PROJECT_UTILS_H