Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

hashtable.h

Go to the documentation of this file.
00001 /*
00002  * Ethereal
00003  * Copyright (C) 2001-2002 Daniel Horn & Alan Shieh
00004  *
00005  * http://vegastrike.sourceforge.net/ethereabl
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020  */
00021 
00022 #ifndef _HASHTABLE_H_
00023 #define _HASHTABLE_H_
00024 
00025 #include <math.h>
00026 #include <string>
00027 #include <vector>
00028 //#include <set>
00029 
00031 template<class KEY, class VALUE, int SIZ=256> class Hashtable {
00033     typedef std::pair <KEY, VALUE> HashElement;
00034 public:
00036     typedef std::vector<HashElement> vector_type;
00037     typedef HashElement value_type; 
00038 
00039     template <class Type> static int hash(const Type key) {
00040       return ((unsigned int)key)%SIZ;
00041     }
00042     template <class it> class HashIterator {
00043         KEY key;
00044         vector_type *v;
00045         it i;
00046         void findnext() {
00047             const it e= v->end();
00048             for (;i!=e;++i) {
00049                 if (key==(*i).first)
00050                     break;
00051             }
00052         }
00053         friend class Hashtable<KEY,VALUE,SIZ>;
00054     public:
00055         typedef it it_type;
00056         bool operator ==(const HashIterator &o) const {return i==o.i;}
00057         bool operator !=(const HashIterator &o) const {return i!=o.i;}
00058         bool operator ==(const it &o) const {return i==o;}
00059         bool operator !=(const it &o) const {return i!=o;}
00060         it end() {return v->end();}
00061         it begin() {return v->begin();}
00062         unsigned int size() {return v->size();}
00063         value_type &operator * () {
00064             return *i;
00065         }
00066         const value_type &operator * () const {
00067             return *i;
00068         }
00069         value_type *operator-> () {
00070             return &(*i);
00071         }
00072         const value_type &operator-> () const {
00073             return &(*i);
00074         }
00075         HashIterator (const KEY &key, vector_type *v):key(key), v(v), i(v->begin()) {;findnext();}
00076         HashIterator (const KEY &key, vector_type *v, it i):key(key), v(v), i(i) {}
00077 //      HashIterator (it iter) : key(), v(NULL), i(iter) {}
00078 //      HashIterator (const HashIterator<it> &hi):key(hi.key),v (hi.v),i (&(*hi))  {}
00079 /*      HashIterator & operator= (HashIterator &oth) {
00080             i=(&(*oth));
00081             key=oth.key;
00082             v=oth.v;
00083             return (*this);
00084             }*/
00085         operator it_type () {
00086             return i;
00087         }
00088         operator const it_type () const{
00089             return i;
00090         }
00091         HashIterator & operator ++ (){
00092             i++;
00093             findnext();
00094             return *this;
00095         }
00096         HashIterator operator ++ (int){
00097             HashIterator<it> oldthis (*this);
00098             i++;
00099             findnext();
00100             return oldthis;
00101         }
00102         HashIterator & operator + (int inc) const{
00103             HashIterator<it> newit (this);
00104             for (int ii=0;ii<inc;++ii) {
00105                 newit++;
00106             }
00107             return newit;
00108         }
00109     };
00110     typedef HashIterator<typename vector_type::iterator> iterator; 
00111     typedef HashIterator<typename vector_type::const_iterator> const_iterator; 
00112         
00113         
00114 
00117     static int hash(const std::string &key) {
00118         unsigned int k = 0;
00119         std::string::const_iterator start = key.begin();
00120         
00121         for(;start!=key.end(); start++) {
00122             k += (k * 128) + *start;
00123         }
00124         k %= SIZ;
00125         return k;
00126     }
00127 private:
00129     vector_type table[SIZ];
00130     void swapiter (iterator iter1, iterator iter2) {
00131         value_type backup=(*iter1);
00132         (*iter1)=(*iter2);
00133         (*iter2)=backup;
00134     }
00135     iterator SwapIn (vector_type *tbl, HashElement elem) {
00136         tbl.push_back(elem);
00137         iterator iter=tbl.back()-1;
00138         return iter;
00139     }
00140 public:
00142 
00145     vector_type &GetAll(const KEY &key)
00146     {
00147         int hashval = hash(key);
00148         return table[hashval];
00149     }
00151     VALUE *Get(const KEY &key)
00152     {
00153         int hashval = hash(key);
00154         typename vector_type::iterator iter = table[hashval].begin();
00155         typename vector_type::const_iterator end = table[hashval].end();
00156         for(;;iter++) {
00157             if (iter==end)
00158                 return NULL;
00159             if((*iter).first == key)
00160                 break;
00161         }
00162         return &(*iter).second;
00163     }
00164     const VALUE *Get(const KEY &key) const
00165     {
00166         int hashval = hash(key);
00167         typename vector_type::const_iterator iter = table[hashval].find(key);
00168         typename vector_type::const_iterator end = table[hashval].end();
00169         for(;iter!=end;iter++)
00170             if((*iter).first == key)
00171                 break;
00172         if (iter==end)
00173             return NULL;
00174         else
00175             return &(*iter).second;
00176     }
00177     bool Get (const KEY & key, VALUE & k){
00178         VALUE * g = Get(key);
00179         if (g) {
00180             k=*g;
00181             return true;
00182         }
00183         return false;
00184     }
00185     
00187 
00191     iterator find(const KEY &key) {
00192         int tablenum=hash(key);
00193         vector_type *mytyp=&table[tablenum];
00194         return iterator(key, mytyp);
00195     }
00197 
00201     const_iterator find(const KEY &key) const{
00202         int tablenum=hash(key);
00203         const vector_type *mytyp=&table[tablenum];
00204         return const_iterator (key, mytyp);
00205     }
00207     void Put(const KEY &key, const VALUE &value) {
00208         int hashval = hash(key);
00209         table[hashval].push_back(HashElement(key, value));
00210     }
00212     iterator insert(value_type valty) {
00213         int hashval = hash(valty.first);
00214         vector_type &tab=table[hashval];
00215         tab.push_back (valty);
00216         return iterator(valty.first, &tab, tab.end()-1);//fulliterator (SwapIn(table[hashval],valty), hashval);
00217     }
00219     void Delete(const KEY &key)
00220     {
00221         int hashval = hash(key);
00222         typename vector_type::iterator iter = table[hashval].begin(), end = table[hashval].end();
00223 
00224         for(;iter!=end;iter++)
00225             if((*iter).key == key)
00226                 break;
00227         if(iter==end)
00228             return;
00229         else {
00230             table[hashval].erase(iter);
00231         }
00232     }
00234     iterator erase (const iterator &iter) {
00235         iterator ret(iter.key,iter.v,iter.v->erase(iter.i));
00236         ret.findnext();
00237         return ret;
00238     }
00240 
00241     unsigned int size (int vectorname) const {
00242         return table[vectorname].size();
00243     }
00245 
00246 };
00247 
00248 #endif

Generated on Mon Jul 7 21:13:44 2003 for Ethereal by doxygen1.2.15