Files
ece-250/P2/DoubleHashTable.cpp
2023-05-21 23:28:11 -04:00

178 lines
5.0 KiB
C++

#include <iostream>
#include <cmath>
#include "DoubleHashTable.h"
#include "Process.h"
DoubleHashTable::DoubleHashTable(int size)
{
processList = new Process *[size];
maxCount = size;
count = 0;
for (int i = 0; i < size; i++)
{
processList[i] = nullptr;
}
}
DoubleHashTable::~DoubleHashTable()
{
for (int i = 0; i < maxCount; i++)
{
if (processList[i] != nullptr)
delete processList[i];
}
delete[] processList;
}
/// @brief Insert a process into the hash table
/// @param p pointer to the process to insert
/// @return true if successful, false otherwise
bool DoubleHashTable::Insert(Process *p)
{
if (count >= maxCount)
{
return false;
}
// Continually hash until we have reached a nullpointer, -1, or the end
int emptyIndex = -1;
for (int i = 0; i < maxCount; i++)
{
unsigned int hashedIndex = HashIndex(p->getPid(), i);
// If we have reached a nullptr, and have not seen any empty slots before
if (processList[hashedIndex] == nullptr && emptyIndex == -1)
{
// Replace the nullpointer with the process
processList[hashedIndex] = p;
return true;
}
// If we have reached a nullpointer and have seen an empty slot before
else if (processList[hashedIndex] == nullptr && emptyIndex != -1)
{
// Replace the -1 with the process
hashedIndex = HashIndex(p->getPid(), emptyIndex);
delete processList[hashedIndex];
processList[hashedIndex] = p;
return true;
}
// If we find a process with the same PID already, exit
else if (processList[hashedIndex]->getPid() == p->getPid())
{
return false;
}
// If we have found a slot of -1
else if (processList[hashedIndex]->getStartingIndex() == -1 && emptyIndex == -1)
{
// If we can insert in the empty slot (have reached the end)
emptyIndex = i;
if (!(i + 1 < maxCount))
{
delete processList[hashedIndex];
processList[hashedIndex] = p;
return true;
}
}
}
// Insert into the empty slot - theoretically we do not need the code in the if statement of the last else if clause, but it works...
if (emptyIndex != -1)
{
unsigned int hashedIndex = HashIndex(p->getPid(), emptyIndex);
delete processList[hashedIndex];
processList[hashedIndex] = p;
return true;
}
return false;
}
/// @brief Search the hash table for the given PID
/// @param PID the pid to search for
/// @return the index of the process, or -1 if the process does not exist
int DoubleHashTable::Search(unsigned int PID)
{
for (int i = 0; i < maxCount; i++)
{
int hashedIndex = HashIndex(PID, i);
if (hashedIndex >= maxCount || processList[hashedIndex] == nullptr)
{
return -1;
}
else if (processList[hashedIndex]->getPid() == PID)
{
return hashedIndex;
}
}
return -1;
}
/// @brief Search the hash table for the given PID, and return a pointer to the process object
/// @param PID the pid to search for
/// @return A valid process object if it exists, or a nullpointer otherwise
Process *DoubleHashTable::Get(unsigned int PID)
{
for (int i = 0; i < maxCount; i++)
{
int hashedIndex = HashIndex(PID, i);
if (hashedIndex >= maxCount || processList[hashedIndex] == nullptr)
{
return nullptr;
}
else if (processList[hashedIndex]->getPid() == PID)
{
return processList[hashedIndex];
}
}
return nullptr;
}
/// @brief Remove a process object from the hash table
/// @param PID the PID of the process to remove
/// @return true if the process was successfully removed, false otherwise
bool DoubleHashTable::Remove(unsigned int PID)
{
for (int i = 0; i < maxCount; i++)
{
int hashedIndex = HashIndex(PID, i);
if (hashedIndex >= maxCount || processList[hashedIndex] == nullptr)
{
return false;
}
else if (processList[hashedIndex]->getPid() == PID)
{
delete processList[hashedIndex];
processList[hashedIndex] = new Process(0, -1);
return true;
}
}
return false;
}
/// @brief Compute the hash of k and i.
/// @param k the k value to hash (PID)
/// @param i the i value to hash (index)
/// @return the hashed value
int DoubleHashTable::HashIndex(unsigned int k, int i)
{
unsigned int h1 = k % maxCount;
unsigned int h2 = (int)std::floor(k / maxCount) % maxCount;
if (h2 % 2 == 0)
h2++;
return (h1 + i * h2) % maxCount;
}
void DoubleHashTable::Print(unsigned int m)
{
// Not implemented
}