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_DBR_HASH_H__
00033 #define __HASH_DBR_HASH_H__
00034
00035 #include "direct_hash_base.h"
00036
00037 template <typename KT> struct dbr_hash_slot
00038 {
00039 KT key;
00040 int array_slot;
00041 };
00042
00043 template <typename KT> struct hash_data_array_t
00044 {
00045 int size;
00046 KT *data;
00047 };
00048
00051 template <typename KT>
00052 class DBRHash : public DHashBase<KT, struct dbr_hash_slot<KT> >
00053 {
00054 protected:
00055 KT emptyKey;
00056 KT deletedKey;
00057 KT *data_array;
00058 #ifdef TOMBDEBUG
00059 int realCapacity;
00060 #endif
00061 public:
00065 DBRHash(int hashCapacity, int realCapacity, KT emptyKey, KT deletedKey) : DHashBase<KT, struct dbr_hash_slot<KT> >(hashCapacity)
00066 {
00067 #ifdef TOMBDEBUG
00068 if (realCapacity <=0)
00069 throw zmm::Exception(_("illegal realCapacity (") + realCapacity + ")");
00070 this->realCapacity = realCapacity;
00071 if (realCapacity >= hashCapacity)
00072 throw zmm::Exception(_("realCapacity (") + realCapacity + ") MUST be < hashCapacity (" + hashCapacity + ")");
00073 #endif
00074 if (emptyKey == deletedKey)
00075 throw zmm::Exception(_("emptyKey and deletedKey must not be the same!"));
00076 this->emptyKey = emptyKey;
00077 this->deletedKey = deletedKey;
00078 data_array = (KT *)MALLOC(realCapacity * sizeof(KT));
00079 clear();
00080 }
00081
00082 virtual ~DBRHash()
00083 {
00084 FREE(data_array);
00085 }
00086
00087
00088 virtual int hashCode(KT key)
00089 {
00090 return this->baseTypeHashCode((unsigned int)key);
00091 }
00092
00093 virtual bool match(KT key, struct dbr_hash_slot<KT> *slot)
00094 {
00095 return (key == slot->key);
00096 }
00097
00098 virtual bool isEmptySlot(struct dbr_hash_slot<KT> *slot)
00099 {
00100 return (slot->key == emptyKey);
00101 }
00102
00103 virtual bool isDeletedSlot(struct dbr_hash_slot<KT> *slot)
00104 {
00105 return (slot->key == deletedKey);
00106 }
00107
00108 void clear()
00109 {
00110 if (! emptyKey)
00111 this->zero();
00112 else
00113 {
00114 struct dbr_hash_slot<KT> *slot;
00115 for (int i = 0; i < this->capacity; i++)
00116 {
00117 slot = this->data +i;
00118 slot->key = emptyKey;
00119 }
00120 this->count = 0;
00121 }
00122 }
00123
00124 inline bool remove(KT key)
00125 {
00126 struct dbr_hash_slot<KT> *slot;
00127 if (! search(key, &slot))
00128 return false;
00129 slot->key = deletedKey;
00130 int array_slot = slot->array_slot;
00131 if (this->count == 1 || this->count-1 == array_slot)
00132 {
00133 this->count--;
00134 return true;
00135 }
00136 data_array[array_slot] = data_array[--this->count];
00137 if (! search(data_array[array_slot], &slot))
00138 {
00139 log_debug("DBR-Hash-Error: (%d; array_slot=%d; count=%d)\n", data_array[array_slot], array_slot, this->count);
00140 throw zmm::Exception(_("DBR-Hash-Error: key in data_array not found in hashtable"));
00141 }
00142 slot->array_slot = array_slot;
00143 return true;
00144 }
00145
00146 inline void put(KT key)
00147 {
00148 struct dbr_hash_slot<KT> *slot;
00149 if (! search(key, &slot))
00150 {
00151 #ifdef TOMBDEBUG
00152 if (this->count >= realCapacity)
00153 throw zmm::Exception(_("count (") + this->count + ") reached realCapacity (" + realCapacity + ")!\n");
00154 #endif
00155 slot->key = key;
00156 slot->array_slot = this->count;
00157 data_array[this->count++] = key;
00158 }
00159 }
00160
00162 inline void getAll(hash_data_array_t<KT> *hash_data_array)
00163 {
00164 hash_data_array->size = this->count;
00165 hash_data_array->data = data_array;
00166 }
00167
00168 zmm::String debugGetAll()
00169 {
00170 zmm::Ref<zmm::StringBuffer> buf(new zmm::StringBuffer());
00171 if (this->count == 0)
00172 return _("");
00173 *buf << data_array[0];
00174 for (int i = 1; i < this->count; i++)
00175 {
00176 *buf << ", " << data_array[i];
00177 }
00178 return buf->toString();
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 inline bool exists(KT key)
00195 {
00196 struct dbr_hash_slot<KT> *slot;
00197 return search(key, &slot);
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 };
00209
00210 #endif // __HASH_DBR_HASH_H__