/* * (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 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;binIndexnextItem; 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; } }