Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

HashMap.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Beeyond Software Holding BV
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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

Generated on Sun Apr 24 16:41:43 2005 for BeeCrypt C++ by  doxygen 1.3.9.1