167 lines
4.3 KiB
C++
167 lines
4.3 KiB
C++
/*
|
|
* (C) Copyright The MITRE Corporation 1999 All rights reserved.
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License
|
|
* Version 1.0 (the "License"); you may not use this file except in
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* The program provided "as is" without any warranty express or
|
|
* implied, including the warranty of non-infringement and the implied
|
|
* warranties of merchantibility and fitness for a particular purpose.
|
|
* The Copyright owner will not be liable for any damages suffered by
|
|
* you as a result of using the Program. In no event will the Copyright
|
|
* owner be liable for any special, indirect or consequential damages or
|
|
* lost profits even if the Copyright owner has been advised of the
|
|
* possibility of their occurrence.
|
|
*
|
|
* Please see release.txt distributed with this file for more information.
|
|
*
|
|
*/
|
|
|
|
// Tom Kneeland (01/21/2000)
|
|
//
|
|
// Implementation of a simple Hash Table. All objects are stored as
|
|
// MITREObject pointers and hashed using the provided value. Collisions
|
|
// are solved using a linked list for each hash bin.
|
|
//
|
|
// Modification History:
|
|
// Who When What
|
|
|
|
#include "HashTable.h"
|
|
#include <iostream.h>
|
|
|
|
HashTable::HashTable()
|
|
{
|
|
for (Int32 binIndex=0; binIndex < HASHTABLE_SIZE; binIndex++)
|
|
table[binIndex] = NULL;
|
|
}
|
|
|
|
//
|
|
//Destroy the hash table. Loop through all the bins, deleting all the objects
|
|
//and list items.
|
|
//
|
|
HashTable::~HashTable()
|
|
{
|
|
Int32 binIndex = 0;
|
|
HashItem* currentItem = NULL;
|
|
HashItem* nextItem = NULL;
|
|
|
|
for (binIndex=0;binIndex<HASHTABLE_SIZE;binIndex++)
|
|
{
|
|
currentItem = table[binIndex];
|
|
while (currentItem != NULL)
|
|
{
|
|
nextItem = currentItem->nextItem;
|
|
delete currentItem->objPtr;
|
|
delete currentItem;
|
|
currentItem = nextItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
//Compute the bin from the Hash value, and store the object in the table
|
|
//
|
|
void HashTable::add(MITREObject* obj, Int32 hashValue)
|
|
{
|
|
Int32 bin = hashValue % HASHTABLE_SIZE;
|
|
HashItem* newHashItem = new HashItem;
|
|
HashItem* existingItem = NULL;
|
|
|
|
//Create a new Hash Object to hold the MITREObject being inserted
|
|
newHashItem->objPtr = obj;
|
|
newHashItem->hashValue = hashValue;
|
|
newHashItem->prevItem = NULL;
|
|
newHashItem->nextItem = NULL;
|
|
|
|
//Addition is simple if there is nothing in the bin
|
|
if (table[bin] == NULL)
|
|
table[bin] = newHashItem;
|
|
else
|
|
{
|
|
//The bin has at least one item in it already, so check the list to
|
|
//make sure the item doesn't already exit. If it does, replace it,
|
|
//else just prepend a new item.
|
|
if ((existingItem = retrieveHashItem(hashValue)) != NULL)
|
|
{
|
|
delete existingItem->objPtr;
|
|
existingItem->objPtr = obj;
|
|
}
|
|
else
|
|
{
|
|
newHashItem->nextItem = table[bin];
|
|
table[bin]->prevItem = newHashItem;
|
|
table[bin] = newHashItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
//Locate the object specified by the hashValue
|
|
//
|
|
MITREObject* HashTable::retrieve(Int32 hashValue)
|
|
{
|
|
HashItem* searchValue = retrieveHashItem(hashValue);
|
|
|
|
if (searchValue)
|
|
return searchValue->objPtr;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
//Locate the object specified by the hashValue, remove it from the table
|
|
//and return the orriginal object to the caller
|
|
//
|
|
MITREObject* HashTable::remove(Int32 hashValue)
|
|
{
|
|
Int32 bin = hashValue % HASHTABLE_SIZE;
|
|
MITREObject* returnObj = NULL;
|
|
HashItem* searchItem = table[bin];
|
|
|
|
while (1)
|
|
{
|
|
if (searchItem == NULL)
|
|
return NULL;
|
|
|
|
if (searchItem->hashValue == hashValue)
|
|
{
|
|
returnObj = searchItem->objPtr;
|
|
|
|
if (searchItem->prevItem == NULL)
|
|
table[bin] = searchItem->nextItem;
|
|
else
|
|
searchItem->prevItem->nextItem = searchItem->nextItem;
|
|
|
|
if (searchItem->nextItem != NULL)
|
|
searchItem->nextItem->prevItem = searchItem->prevItem;
|
|
|
|
delete searchItem;
|
|
return returnObj;
|
|
}
|
|
|
|
searchItem = searchItem->nextItem;
|
|
}
|
|
}
|
|
|
|
HashTable::HashItem* HashTable::retrieveHashItem(Int32 hashValue)
|
|
{
|
|
Int32 bin = hashValue % HASHTABLE_SIZE;
|
|
HashItem* searchItem = NULL;
|
|
|
|
//Goto the calculated bin, and begin a linear search for the specified
|
|
//value.
|
|
searchItem = table[bin];
|
|
while (1)
|
|
{
|
|
if (searchItem == NULL)
|
|
return NULL;
|
|
|
|
if (searchItem->hashValue == hashValue)
|
|
return searchItem;
|
|
|
|
searchItem = searchItem->nextItem;
|
|
}
|
|
}
|