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

simplehash.h

Go to the documentation of this file.
00001 /** @file simplehash.h */
00002 /* 
00003  * Copyright (C) 2002 Laird Breyer
00004  *  
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  * 
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018  * 
00019  * Author:   Laird Breyer <laird@lbreyer.com>
00020  */
00021 
00022 #ifndef _SIMPLE_HASH_H_
00023 #define _SIMPLE_HASH_H_
00024 
00025 #include "basictypes.h"
00026 #include <stddef.h>
00027 #include <string.h>
00028 #include <cassert>
00029 #include <stdexcept>
00030 
00031 /// A structure used by SimpleHashTable.
00032 template<class R>
00033 struct SimpleHashPair {
00034   ptrdiff_t key;
00035   R value;
00036 };
00037 
00038 /// A simple "linear probing and insertion" hashtable.
00039 /**
00040  * This simplistic hashtable is designed as a 
00041  * replacement for the STL hashtable, which uses too much memory.
00042  * The hashtable implements algorithm L in Knuth, Vol.3, p.526 and
00043  * also uses Knuth's hash function.
00044  */
00045 template<class R>
00046 class SimpleHashTable
00047 {
00048 
00049  public:
00050   SimpleHashTable(uint32 size);
00051   uint32 IntHash(uint32 key);
00052   R Find(ptrdiff_t key);
00053   bool Insert(ptrdiff_t key, R value) throw (overflow_error);
00054   inline uint32 GetCount() { return count; };
00055   inline uint32 Size() { return size_; };
00056   void Clear();
00057 
00058  private:
00059   uint32 size_;
00060   uint32 count;
00061   SimpleHashPair<R> *table;
00062 
00063 };
00064 
00065 template<class R>
00066 SimpleHashTable<R> :: SimpleHashTable(uint32 size) {
00067   size_ = size;
00068   count = 0;
00069   table = new SimpleHashPair<R>[size_];
00070   memset(table, 0, sizeof(SimpleHashPair<R>) * size_);
00071 }
00072 
00073 template<class R>
00074 void SimpleHashTable<R> :: Clear() {
00075   count = 0;
00076   memset(table, 0, sizeof(SimpleHashPair<R>) * size_);
00077 }
00078 
00079 template<class R>
00080 R SimpleHashTable<R> :: Find(ptrdiff_t key) {
00081   uint32 j = IntHash((uint32)key);
00082   uint32 jj = j % size_;
00083   while( table[jj].value != (R)0 ) {
00084     if(table[jj].key == key) {
00085       return table[jj].value;
00086     }
00087     jj = (jj > 0) ? jj - 1 : size_ - 1;
00088   }
00089   return (R)0;
00090 }
00091 
00092 /// Inserts a key,value pair into the hash. Returns false if we 
00093 /// try to insert a duplicate key, and returns an exception 
00094 /// if hash is full
00095 template<class R>
00096 bool SimpleHashTable<R> :: Insert(ptrdiff_t key, R value) throw (overflow_error) {
00097 
00098   if( count < size_ ) {
00099     uint32 j = IntHash((uint32)key);
00100     uint32 jj = j % size_;
00101     while( table[jj].value != (R)0 ) {
00102       if(table[jj].key == key) 
00103         { return false; }
00104       jj = (jj > 0) ? jj - 1 : size_ - 1;
00105     }
00106     table[jj].key = key;
00107     table[jj].value = value;
00108     count++;
00109     return true;
00110   } else {
00111     cerr << "SimpleHashTable overflow" << endl;
00112     throw overflow_error("");
00113   }
00114 }
00115 
00116 template<class R>
00117 uint32 SimpleHashTable<R> :: IntHash(uint32 key) {
00118 // due to thomas wang, a simplification of bob jenkins' 96 DDJ hash
00119 //   key += ~(key << 15);
00120 //   key ^=  (key >>> 10);
00121 //   key +=  (key << 3);
00122 //   key ^=  (key >>> 6);
00123 //   key += ~(key << 11);
00124 //   key ^=  (key >>> 16);
00125 
00126 // knuth's golden ratio of 2^32
00127   key = (key >> 3) * 2654435761UL;
00128   return key;
00129 }
00130 
00131 #endif

Generated on Wed May 29 11:37:15 2002 for MarkovPR by doxygen1.2.15