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_DBO_HASH_H__
00033 #define __HASH_DBO_HASH_H__
00034
00035 #include "direct_hash_base.h"
00036 #include <assert.h>
00037
00038 template <typename KT, typename VT> struct dbo_hash_slot
00039 {
00040 KT key;
00041 VT *value;
00042 };
00043
00045 template <typename KT, typename VT>
00046 class DBOHash : public DHashBase<KT, struct dbo_hash_slot<KT, VT> >
00047 {
00048 protected:
00049 KT emptyKey;
00050 KT deletedKey;
00051 public:
00052 DBOHash(int capacity, KT emptyKey, KT deletedKey) : DHashBase<KT, struct dbo_hash_slot<KT, VT> >(capacity)
00053 {
00054
00055 assert(emptyKey != deletedKey);
00056 this->emptyKey = emptyKey;
00057 this->deletedKey = deletedKey;
00058 init();
00059 }
00060 virtual ~DBOHash()
00061 {
00062 releaseData();
00063 }
00064 protected:
00065 void init()
00066 {
00067 if (! emptyKey)
00068 this->zero();
00069 else
00070 {
00071 for (int i = 0; i < this->capacity; i++)
00072 this->data[i].key = emptyKey;
00073 this->count = 0;
00074 }
00075 }
00076 void releaseData()
00077 {
00078 dbo_hash_slot<KT, VT> *slot;
00079 for (int i = 0; i < this->capacity; i++)
00080 {
00081 slot = this->data + i;
00082 if (slot->key != emptyKey && slot->key != deletedKey)
00083 slot->value->release();
00084 }
00085 }
00086 public:
00087 void clear()
00088 {
00089 dbo_hash_slot<KT, VT> *slot;
00090 for (int i = 0; i < this->capacity; i++)
00091 {
00092 slot = this->data + i;
00093 if (slot->key != emptyKey && slot->key != deletedKey)
00094 {
00095 slot->key = emptyKey;
00096 slot->value->release();
00097 }
00098 else if (slot->key == deletedKey)
00099 {
00100 slot->key = emptyKey;
00101 }
00102 }
00103 this->count = 0;
00104 }
00105
00106 inline bool remove(KT key)
00107 {
00108 struct dbo_hash_slot<KT, VT> *slot;
00109 if (! search(key, &slot))
00110 return false;
00111 slot->key = deletedKey;
00112 slot->value->release();
00113 this->count--;
00114 return true;
00115 }
00116
00117
00118 virtual int hashCode(KT key)
00119 {
00120 return this->baseTypeHashCode((unsigned int)key);
00121 }
00122 virtual bool match(KT key, struct dbo_hash_slot<KT, VT> *slot)
00123 {
00124 return (key == slot->key);
00125 }
00126 virtual bool isEmptySlot(struct dbo_hash_slot<KT, VT> *slot)
00127 {
00128 return (slot->key == emptyKey);
00129 }
00130
00131 virtual bool isDeletedSlot(struct dbo_hash_slot<KT, VT> *slot)
00132 {
00133 return (slot->key == deletedKey);
00134 }
00135
00136 inline void put(KT key, zmm::Ref<VT> value)
00137 {
00138 struct dbo_hash_slot<KT, VT> *slot;
00139 search(key, &slot);
00140 put(key, (hash_slot_t)slot, value);
00141 }
00142 void put(KT key, hash_slot_t destSlot, zmm::Ref<VT> value)
00143 {
00144 struct dbo_hash_slot<KT, VT> *slot = (struct dbo_hash_slot<KT, VT> *)destSlot;
00145 if (slot->key != emptyKey && slot->key != deletedKey)
00146 {
00147 VT *valuePtr = value.getPtr();
00148 valuePtr->retain();
00149 slot->value->release();
00150 slot->value = valuePtr;
00151 }
00152 else
00153 {
00154 this->count++;
00155 slot->key = key;
00156 VT *valuePtr = value.getPtr();
00157 valuePtr->retain();
00158 slot->value = valuePtr;
00159 }
00160 }
00161
00162 inline zmm::Ref<VT> get(KT key)
00163 {
00164 struct dbo_hash_slot<KT, VT> *slot;
00165 bool found = search(key, &slot);
00166 if (found)
00167 return zmm::Ref<VT>(slot->value);
00168 else
00169 return nil;
00170
00171 hash_slot_t destSlot;
00172 return get(key, &destSlot);
00173 }
00174 inline zmm::Ref<VT> get(KT key, hash_slot_t *destSlot)
00175 {
00176 struct dbo_hash_slot<KT, VT> **slot = (struct dbo_hash_slot<KT, VT> **)destSlot;
00177 bool found = search(key, slot);
00178 if (found)
00179 return zmm::Ref<VT>((*slot)->value);
00180 else
00181 return nil;
00182 }
00183 };
00184
00185 #endif // __HASH_DBO_HASH_H__