178 lines
5.0 KiB
C++
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
|
|
}
|