Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

Hashtable.h

Go to the documentation of this file.
00001 #ifndef __HASHTABLE_H
00002 #define __HASHTABLE_H
00003 
00004 #include <vector>
00005 #include <iostream>
00006 
00007 const size_t primes[30] = {2,5,11,23,47,97,197,397,797,1597,3203,6421,12853,25717,51437,102877,205759,411527,823117,1646237,3292489,6584983,13169977,26339969,52679969,105359939,210719881,421439783,842879579,1685759167};
00008 const int numPrimes = 30;
00009 
00010 template <class data, class key, size_t (*hashFunc)(key* K), bool (*equals)(key* k1, key* k2)>
00011 class Hashtable{
00012 private:
00013   int  primeIndex;
00014   size_t sizeOfTable;
00015   std::vector<bool>*  isUsed;
00016   std::vector<key*>*  keys;
00017   std::vector<data*>* datas;
00018   size_t numElems;
00019   size_t numUsedBins;
00020   
00021   size_t find(key* k){
00022     size_t hashVal = (hashFunc(k) % sizeOfTable);
00023     
00024     size_t pos = hashVal;
00025     int i = 1;
00026     while (1){
00027       //        if (pos >= (int)isUsed->size()){
00028       //          cout << "ERROR! " << pos << " " << isUsed->size() << " " << sizeOfTable << endl;
00029       //        }
00030       //        if (pos < 0){
00031       //          cout << "ERROR! " << hashFunc(k) << " " << hashVal << " " << pos << " " << isUsed->size() << " " << sizeOfTable << endl;
00032       //          HoughKey* hk = (HoughKey*)k;
00033       //          cout << hk->scale << " " << hk->x << " " << hk->y << " " << hk->orientation << endl;
00034       //        }
00035       if (!((*isUsed)[pos])){
00036         return pos;
00037       }else if ((*keys)[pos] != NULL && equals((*keys)[pos], k)){
00038         return pos;
00039       }
00040       pos = (hashVal + (i*i)) % sizeOfTable;
00041       //        cout << pos << endl;
00042       i++;
00043     }
00044     
00045     return pos;
00046   }
00047   
00048   void resizeTable(){
00049     using namespace std;
00050     
00051     cout << "RESIZING!\n";
00052     
00053     vector<bool>*  oldIsUsed = isUsed;
00054     vector<key*>*  oldKeys   = keys;
00055     vector<data*>* oldDatas  = datas;
00056     size_t oldSizeOfTable = sizeOfTable;
00057     
00058     numElems = 0;
00059     numUsedBins = 0;
00060     
00061     // Double table size
00062     // Assumes that hashtable never gets bigger than 1685759167
00063     primeIndex++;
00064     sizeOfTable = primes[primeIndex];
00065     
00066     isUsed = new vector<bool>(sizeOfTable, false);
00067     keys   = new vector<key*>(sizeOfTable, NULL);
00068     datas  = new vector<data*>(sizeOfTable, NULL);
00069     
00070     for (size_t i = 0; i < oldSizeOfTable; i++){
00071       if ((*oldIsUsed)[i] && ((*oldKeys)[i] != NULL)){
00072         size_t index = find((*oldKeys)[i]);
00073         (*isUsed)[index] = true;
00074         numElems++;
00075         numUsedBins++;
00076         (*keys)[index] = (*oldKeys)[i];
00077         (*datas)[index] = (*oldDatas)[i];
00078       }
00079     }
00080     
00081     delete oldKeys;
00082     delete oldIsUsed;
00083     delete oldDatas;
00084   }
00085   
00086 public:
00087   Hashtable() : 
00088     primeIndex(10), sizeOfTable(primes[primeIndex]),
00089     isUsed(new std::vector<bool>(sizeOfTable, false)),
00090     keys(new std::vector<key*>(sizeOfTable, NULL)),
00091     datas(new std::vector<data*>(sizeOfTable, NULL)),
00092     numElems(0), numUsedBins(0) {}
00093   
00094   ~Hashtable(){
00095     delete keys;
00096     delete isUsed;
00097     delete datas;
00098   }
00099   
00100   data* retrieve(key* k){
00101     size_t index = find(k);
00102     if (!(*isUsed)[index])
00103       return NULL;
00104     return (*datas)[index];
00105   }
00106   
00107   void retrieveAllData(std::vector<data*>* returnVec){
00108     returnVec->clear();
00109     
00110     for (size_t i = 0; i < sizeOfTable; i++){
00111       if ((*isUsed)[i] && (*keys)[i] != NULL){
00112         returnVec->push_back((*datas)[i]);
00113       }
00114     }
00115   }
00116   
00117   void retrieveAllKeys(std::vector<key*>* returnVec){
00118     returnVec->clear();
00119     
00120     for (size_t i = 0; i < sizeOfTable; i++){
00121       if ((*isUsed)[i] && (*keys)[i] != NULL){
00122         returnVec->push_back((*keys)[i]);
00123       }
00124     }
00125   }
00126   
00127   bool insert(data* d, key* k){
00128     size_t index = find(k);
00129     
00130     if ((*isUsed)[index]) return false;
00131     
00132     // Check if need to resize
00133     if (numUsedBins+1 >= sizeOfTable / 2){
00134       resizeTable();
00135       index = find(k);
00136     }
00137     
00138     numElems++;
00139     numUsedBins++;
00140     (*isUsed)[index] = true;
00141     (*keys)[index] = k;
00142     (*datas)[index] = d;
00143     
00144     return true;
00145   }
00146   
00147   data* deleteData(key* k, key** retrievedKey){
00148     size_t index = find(k);
00149     
00150     if (!(*isUsed)[index]) return NULL;
00151     
00152     *retrievedKey = (*keys)[index];
00153     data* returnVal = (*datas)[index];
00154     
00155     (*keys)[index] = NULL;
00156     (*datas)[index] = NULL;
00157     
00158     numElems--;
00159     
00160     return returnVal;
00161   }
00162   
00163   size_t numElements(){
00164     return numElems;
00165   }
00166   
00167   size_t usedCapacity(){
00168     return numUsedBins;
00169   }
00170   
00171   size_t capacity(){
00172     return sizeOfTable;
00173   }
00174   
00175 private:
00176   Hashtable(const Hashtable&); // Do not use
00177   Hashtable& operator=(const Hashtable&); // Do not use
00178   
00179 };
00180 
00181 #endif

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:41 2016 by Doxygen 1.6.3