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

hashtable.h

Go to the documentation of this file.
00001 /***************************************************************************
00002     hashtable.h  -  Definition of template class HashTable.
00003                              -------------------
00004     begin                : June 21 2002
00005     copyright            : (C) 2003 by Vojtìch Toman
00006     email                : vtoman@lit.cz
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017 
00026 #ifndef HASHTABLE_H
00027 # define HASHTABLE_H
00028 
00029 
00030 #include <cstring>      //for strcmp()
00031 
00032 #include "defs.h"
00033 #include "collection.h"
00034 #include "debug.h"
00035 #include "xmldefs.h"
00036 #include "xmlchar.h"
00037 
00038 
00039 
00040 
00041 
00050 static inline unsigned long hashXmlString(const XmlChar *s)
00051 {
00052   unsigned long h = 0; 
00053 
00054   for ( ; *s; ++s)
00055     h = 5 * h + *s;
00056   
00057   return h;
00058 }
00059 
00060 
00061 
00068 template<unsigned long size_> struct HashTableHash
00069 {
00071   //unsigned long operator()(XmlChar *s) const { return hashXmlString_(s) % size_; }
00072 
00074   unsigned long operator()(const XmlChar *s) const { return hashXmlString(s) % size_; }
00075 
00077   unsigned long operator()(char x) const { return x % size_; }
00078 
00080   unsigned long operator()(unsigned char x) const { return x % size_; }
00081 
00083   //unsigned long operator()(short x) const { return x % size_; }
00084 
00086   //unsigned long operator()(unsigned short x) const { return x % size_; }
00087 
00089   unsigned long operator()(int x) const { return x % size_; }
00090 
00092   unsigned long operator()(unsigned int x) const { return x % size_; }
00093 
00095   unsigned long operator()(long x) const { return x % size_; }
00096 
00098   unsigned long operator()(unsigned long x) const { return x % size_; }
00099 };
00100 
00101 
00102 
00103 
00104 
00111 struct HashTableComparator
00112 {
00114   bool compare(XmlChar x, XmlChar y) { return x == y; }
00115 
00117   bool compare(unsigned char x, unsigned char y) { return x == y; }
00118   //bool compare(short x, short y) { return x == y; }
00119   //bool compare(unsigned short x, unsigned short y) { return x == y; }
00120 
00122   bool compare(int x, int y) { return x == y; }
00123 
00125   bool compare(unsigned int x, unsigned int y) { return x == y; }
00126 
00128   bool compare(long x, long y) { return x == y; }
00129 
00131   bool compare(unsigned long x, unsigned long y) { return x == y; }
00132 
00134   bool compare(XmlChar *x, XmlChar *y) { return !xmlchar_strcmp(x, y); }
00135 };
00136 
00137 
00138 
00145 template<class Key_, class T_> struct HashTableItem
00146 {
00148   Key_ key_;
00149 
00151   T_ *data_;
00152 };
00153 
00154 
00155 
00163 template<class Key_, class T_, template<class T_>
00164  class HashTableBucketContainer_> class HashTableBucket
00165 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00166    : public HashTableBucketContainer_< HashTableItem<Key_, T_> >
00167 #endif //DOXYGEN_SHOULD_SKIP_THIS
00168 {
00169 public:
00171   HashTableComparator comparator_;
00172 
00178   virtual void insertItem(HashTableItem<Key_, T_> *item)
00179   {
00180     prepend(item);
00181   }
00182 
00183 
00190   virtual T_ *find(Key_ key)
00191   {
00192     HashTableItem<Key_, T_> *pom;
00193 
00194     for (pom = first(); pom; pom = next())
00195       {
00196         if (comparator_.compare(pom->key_, key))
00197           return pom->data_;
00198       }
00199     
00200     return 0;
00201   }
00202 
00203 
00204 
00214   virtual bool removeItem(Key_ key)
00215   {
00216     HashTableItem<Key_, T_> *pom;
00217 
00218     pom = first();
00219 
00220     while (pom)
00221       {
00222         if (comparator_.compare(pom->key_, key))
00223           {
00224             if (autoDelete_)
00225               //if neccessary, delete the contents of found item
00226               DELETE(pom->data_);
00227             
00228             //delete the item
00229             return remove();
00230           }
00231 
00232         pom = next();
00233       }
00234     
00235     return false;
00236   }
00237 };
00238 
00239 
00240 
00262 template<class Key_, class T_, template<class T_> class HashTableBucketContainer_, unsigned long size_> class HashTable : public Collection<T_>
00263 {
00264 public:
00265 
00269   HashTable(void) : Collection<T_>()
00270   {
00271     NEW(table_, (HashTableBucket<Key_, T_, HashTableBucketContainer_> *[size_]));
00272 
00273     for (unsigned long i = 0; i < size_; i++)
00274       table_[i] = 0;
00275   }
00276 
00282   virtual ~HashTable(void)
00283   {
00284     clear();
00285     DELETE_ARRAY(table_);
00286   }
00287 
00288 
00298   virtual T_ *find(Key_ key)
00299   {
00300     unsigned long pos = hash_(key);
00301 
00302     if (!table_[pos])
00303       return 0;
00304     else
00305       return table_[pos]->find(key);
00306   }
00307 
00308 
00317   virtual void insert(Key_ key, T_ *item)
00318   {
00319     unsigned long pos = hash_(key);
00320 
00321     if (!table_[pos])
00322       {
00323         NEW(table_[pos], (HashTableBucket<Key_, T_, HashTableBucketContainer_>));
00324       }
00325 
00326     if (!contains(key))
00327       {
00328         HashTableItem<Key_, T_> *tableItem;
00329 
00330         NEW(tableItem, (HashTableItem<Key_, T_>));
00331         
00332         tableItem->key_ = key;
00333         tableItem->data_ = item;
00334         table_[pos]->insertItem(tableItem);
00335         cnt_++;
00336       }
00337   }
00338 
00339 
00350   virtual bool remove(Key_ key)
00351   {
00352     unsigned long pos = hash_(key);
00353 
00354     if (!table_[pos])
00355       return false;
00356     else
00357       {
00358         if (table_[pos]->removeItem(key))
00359           {
00360             cnt_--;
00361             return true;
00362           }
00363         else
00364           return false;
00365       }
00366   }
00367 
00368 
00377   virtual bool contains(Key_ key)
00378   {
00379     unsigned long pos = hash_(key);
00380 
00381     if (!table_[pos])
00382       return false;
00383     else
00384       return (table_[pos]->find(key) != 0);
00385   }
00386 
00387 
00393   virtual void clear(void)
00394   {
00395     for (unsigned long i = 0; i < size_; i++)
00396       {
00397         if (autoDelete_)
00398           {
00399             if (table_[i])
00400               {
00401                 //HashTableItem<Key_, T_> *pom;
00402 
00403                 //for (pom = table_[i]->first(); pom; pom = table_[i]->next())
00404                 //  DELETE(pom->data_);
00405               }
00406           }
00407 
00408         if (table_[i])
00409           {
00410             DELETE(table_[i]);
00411             //      table_[i] = 0;
00412           }
00413       }
00414   }
00415 
00416   
00424   virtual void setAutoDelete(bool ad)
00425   {
00426     for (unsigned long i = 0; i < size_; i++)
00427       {
00428         if (table_[i])
00429           table_[i]->setAutoDelete(ad);
00430       }
00431 
00432     autoDelete_ = ad;
00433   }
00434 
00435 protected:
00437   HashTableBucket<Key_, T_, HashTableBucketContainer_> **table_;
00438 
00440   HashTableHash<size_> hash_;
00441 };
00442 
00443 #endif //HASHTABLE_H
00444 

Generated on Wed Feb 5 10:43:01 2003 for Exalt by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002