00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifndef __HASH_DIRECT_HASH_BASE_H__
00033 #define __HASH_DIRECT_HASH_BASE_H__
00034
00035 #include "hash.h"
00036
00037 template <typename KT, typename ST>
00038 class DHashBase : public zmm::Object
00039 {
00040 protected:
00041 int capacity;
00042 int count;
00043 ST *data;
00044 public:
00045 DHashBase(int capacity) : zmm::Object()
00046 {
00047 this->capacity = capacity;
00048 count = 0;
00049 data = (ST *)MALLOC(capacity * sizeof(ST));
00050 }
00051 virtual ~DHashBase()
00052 {
00053 FREE(data);
00054 }
00055 void zero()
00056 {
00057 count = 0;
00058 memset(data, 0, capacity * sizeof(ST));
00059 }
00060 inline int size()
00061 {
00062 return count;
00063 }
00064
00065
00066 virtual int hashCode(KT key) = 0;
00067 virtual bool match(KT key, ST *slot) = 0;
00068 virtual bool isEmptySlot(ST *slot) = 0;
00069 virtual bool isDeletedSlot(ST *slot)
00070 {
00071 return false;
00072 }
00073
00074 inline int baseTypeHashCode(unsigned int key)
00075 {
00076 return ((key * 0xd2d84a61) ^ 0x7832c9f4) % capacity;
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 int secondaryHashCode(int primary)
00104 {
00105 int h2 = (HASH_PRIME - (primary % HASH_PRIME));
00106 if (h2 == 0)
00107 h2 = HASH_PRIME;
00108 return h2;
00109 }
00110
00111
00112
00113 bool search(KT key, ST **retSlot)
00114 {
00115
00116 int h = hashCode(key);
00117
00118 int h2 = 0;
00119
00120 ST *deletedSlot = NULL;
00121
00122 for (int i = 0; i < HASH_MAX_ITERATIONS; i++)
00123 {
00124 ST *slot = data + h;
00125
00126
00127 if (isEmptySlot(slot))
00128 {
00129 if (deletedSlot)
00130 *retSlot = deletedSlot;
00131 else
00132 *retSlot = slot;
00133 return false;
00134 }
00135
00136 if (isDeletedSlot(slot))
00137 {
00138 deletedSlot = slot;
00139 }
00140 else if (match(key, slot))
00141 {
00142
00143 *retSlot = slot;
00144 return true;
00145 }
00146
00147
00148 if (! h2)
00149 h2 = secondaryHashCode(h);
00150 h = (h + h2) % capacity;
00151 }
00152 log_error("AbstractHash::search() failed, maximal number of iterations exceeded: h:%d h2:%d size:%d\n", h, h2, count);
00153 throw zmm::Exception(_("AbstractHash::search() failed, maximal number of iterations exceeded: h:") + h + " h2:"+ h2);
00154 }
00155 };
00156
00157 #endif // __HASH_DIRECT_HASH_BASE_H__