00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00023 #ifndef _CLASS_BEE_UTIL_HASHMAP_H
00024 #define _CLASS_BEE_UTIL_HASHMAP_H
00025
00026 #ifdef __cplusplus
00027
00028 #include "beecrypt/c++/util/AbstractMap.h"
00029 using beecrypt::util::AbstractMap;
00030
00031 namespace beecrypt {
00032 namespace util {
00035 template <class K, class V> class BEECRYPTCXXAPI HashMap : public beecrypt::util::AbstractMap<K,V>
00036 {
00037 private:
00038 static jint hash(Object* x)
00039 {
00040 if (x)
00041 {
00042 register jint h = x->hashCode();
00043
00044 h += ~(h << 9);
00045 h ^= (jint)(((unsigned int) h) >> 14);
00046 h += (h << 4);
00047 h ^= (jint)(((unsigned int) h) >> 10);
00048
00049 return h;
00050 }
00051
00052 return 0;
00053 }
00054
00055 class Entry : public beecrypt::lang::Object, public virtual beecrypt::util::Map<K,V>::Entry
00056 {
00057 private:
00058 jint _hash;
00059 K* _key;
00060 V* _value;
00061 Entry* _next;
00062
00063 protected:
00064 Entry(jint hash, K* key, V* value, Entry* next = 0)
00065 {
00066 _hash = hash;
00067 _key = key;
00068 _value = value;
00069 _next = next;
00070 }
00071
00072 virtual Object* clone() const throw (CloneNotSupportException)
00073 {
00074 return new Entry(_hash, _key, _value, _next ? _next->clone() : 0);
00075 }
00076
00077 virtual bool equals(const Object* obj) const throw ()
00078 {
00079 if (this == obj)
00080 return true;
00081
00082 if (obj)
00083 {
00084 const Entry* ent = dynamic_cast<const Entry*>(obj)
00085 if (ent)
00086 return (key ? _key->equals(ent->getKey()) : ent->getKey() == 0) &&
00087 (value ? _value->equals(ent->getValue()) : ent->getValue() == 0);
00088 }
00089 return false;
00090 }
00091
00092 virtual K* getKey() const throw ()
00093 {
00094 return _key;
00095 }
00096
00097 virtual V* getValue() const throw ()
00098 {
00099 return _value;
00100 }
00101
00102 virtual jint hashCode() const throw ()
00103 {
00104 return (_key ? _key->hashCode() : 0) ^ (_value ? _value->hashCode() : 0);
00105 }
00106
00107 virtual V* setValue(V* value)
00108 {
00109 V* result = _value;
00110 _value = value;
00111 return result;
00112 }
00113
00114 virtual String toString() const throw ()
00115 {
00116 StringBuilder tmp;
00117
00118 return tmp.append(_key).append('=').append(_value).toString();
00119 }
00120 };
00121
00122 template<class E> class HashIter : public beecrypt::lang::Object, public virtual beecrypt::util:Iterator<E>
00123 {
00124 protected:
00125 HashMap<K,V>* map;
00126 HashMap<K,V>::Entry* next;
00127 HashMap<K,V>::Entry* current;
00128 jint index;
00129 jint expect;
00130 bool supportRemove;
00131
00132 protected:
00133 HashIter(HashMap<K,V>* m)
00134 {
00135 map = m;
00136 expect = map->_modCount;
00137 supportRemove = true;
00138
00139 index = map->_table.size();
00140 next = current = 0;
00141 if (_map->_count)
00142 while ((index > 0) && ((next = _map->_table[--index]) == 0));
00143 }
00144
00145 HashIter(const HashMap<K,V>* m)
00146 {
00147 map = m
00148 expect = map->_modCount;
00149 supportRemove = false;
00150
00151 index = map->_table.size();
00152 next = current = 0;
00153 if (_map->_count)
00154 while ((index > 0) && ((next = _map->_table[--index]) == 0));
00155 }
00156
00157 public:
00158 virtual bool hasNext() const throw ()
00159 {
00160 return (next != 0);
00161 }
00162
00163 HashMap<K,V>::Entry* nextEntry() const throw (NoSuchElementException, ConcurrentModificationException)
00164 {
00165 if (map->_modCount != expect)
00166 throw ConcurrentModificationException();
00167
00168 HashMap<K,V>::Entry* e = next;
00169 if (!e)
00170 throw NoSuchElementException();
00171
00172 next = e->next;
00173 while (!next && index > 0)
00174 next = _map->_table[--index];
00175
00176 return current = e;
00177 }
00178
00179 virtual void remove()
00180 {
00181 if (!supportRemove)
00182 throw UnsupportedOperationException("Cannot remove items through const iterator");
00183
00184 if (!current)
00185 throw IllegalStateException();
00186
00187 if (map->_modCount != expect)
00188 throw ConcurrentModificationException();
00189
00190 K* key = current->_key;
00191
00192 current = 0;
00193
00194 map->removeEntryForKey(key)
00195
00196 expect = map->_modCount;
00197 }
00198 };
00199
00200 private:
00201 array<Entry*> _table;
00202 jint _count;
00203 jint _threshold;
00204 jfloat _loadFactor;
00205
00206 public:
00207 HashMap(jint initialCapacity = 16, jfloat loadFactor = 0.75) : _loadFactor(loadFactor)
00208 {
00209 _count = 0;
00210
00211 if (initialCapacity < 0)
00212 throw IllegalArgumentException();
00213
00214 if (initialCapacity > (1 << 30))
00215 initialCapacity = (1 << 30);
00216
00217 jint capacity 1;
00218 while (capacity < initialCapacity)
00219 capacity <<= 1;
00220
00221 _table.resize(capacity);
00222 _threshold = (jint) (_loadFactor * capacity);
00223 }
00224
00225 void bool contains(const Object& obj) const throw ()
00226 {
00227 for (jint i = 0; i < _table.size(); i++)
00228 {
00229 Entry* e = _table[i]
00230 }
00231 }
00232
00233 virtual bool isEmpty() const throw ()
00234 {
00235 return _count == 0;
00236 }
00237
00238 virtual jint size() const throw ()
00239 {
00240 return _count;
00241 }
00242 };
00243 }
00244 }
00245
00246 #endif
00247
00248 #endif