00001 #ifndef MMANN_HASH_ALGORITHMS_H 00002 #define MMANN_HASH_ALGORITHMS_H 00003 00011 00012 #include "MD5Hash.h" 00013 00015 template <class Key> 00016 class AHashAlgorithm 00017 { 00018 public: 00022 virtual int Hash(const Key* key) = 0; 00023 }; 00024 00028 template <class Key> 00029 class SimpleHashAlgorithm : public AHashAlgorithm<Key> 00030 { 00031 public: 00033 SimpleHashAlgorithm(Key Capacity); 00034 00038 virtual int Hash(const Key* key); 00039 00040 private: 00042 Key m_Capacity; 00043 }; 00044 00045 template <class Key> 00046 SimpleHashAlgorithm<Key>::SimpleHashAlgorithm(Key Capacity) 00047 { 00048 m_Capacity = Capacity; 00049 } 00050 00051 template <class Key> 00052 int SimpleHashAlgorithm<Key>::Hash(const Key* key) 00053 { 00054 return key%m_Capacity; 00055 } 00056 00060 template <class Key> 00061 class MD5HashAlgorithm : public AHashAlgorithm<Key> 00062 { 00063 public: 00067 virtual int Hash(const Key* key); 00068 00069 protected: 00071 MD5Hash m_MD5Hash; 00072 }; 00073 00074 template <class Key> 00075 int MD5HashAlgorithm<Key>::Hash(const Key* key) 00076 { 00077 unsigned char HashValue[MD5_HASHBYTES]; 00078 int RealHashValue; 00079 00080 m_MD5Hash.Init(); 00081 m_MD5Hash.Update((unsigned char*)key, sizeof(Key)); 00082 m_MD5Hash.Final(HashValue); 00083 00084 RealHashValue = (*(int*)HashValue); 00085 if (RealHashValue < 0) 00086 { 00087 // This is a bit mask that nullifies the sign bit of the 00088 // number so it will always be positive 00089 RealHashValue &= (~(1<<((sizeof(RealHashValue)<<3)-1))); 00090 } 00091 00092 return RealHashValue; 00093 } 00094 00098 template <class Key> 00099 class PerlHashAlgorithm : public AHashAlgorithm<Key> 00100 { 00101 public: 00105 virtual int Hash(const Key* key); 00106 }; 00107 00108 template <class Key> 00109 int PerlHashAlgorithm<Key>::Hash(const Key* key) 00110 { 00111 int HashValue = 0; 00112 00113 // Calculate the hash value for the stack 00114 // This hash function was ripped from the Perl source code. 00115 const char * Ptr = (char*)key; 00116 const char * End = Ptr+key[0]+1; 00117 00118 while (Ptr < End) 00119 HashValue += (HashValue << 5) + *(Ptr++); 00120 00121 HashValue += (HashValue >> 5); 00122 00123 return HashValue; 00124 } 00125 00127 template <class Key, class ConfigData> 00128 class AProcessHashAlgorithm 00129 { 00130 public: 00135 virtual int ProcessHash(Key* key, ConfigData* config) = 0; 00136 }; 00137 00142 template <class Key, class ConfigData> 00143 class RemoveHashAlgorithm : public AProcessHashAlgorithm<Key, ConfigData> 00144 { 00145 public: 00150 virtual int ProcessHash(Key* key, ConfigData* config) {return 0;} 00151 }; 00152 00153 #endif