00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00023 #ifndef _CLASS_BEE_UTIL_HASHTABLE_H
00024 #define _CLASS_BEE_UTIL_HASHTABLE_H
00025
00026 #ifdef __cplusplus
00027
00028 #include "beecrypt/c++/lang/Cloneable.h"
00029 using beecrypt::lang::Cloneable;
00030 #include "beecrypt/c++/lang/Integer.h"
00031 using beecrypt::lang::Integer;
00032 #include "beecrypt/c++/lang/IllegalStateException.h"
00033 using beecrypt::lang::IllegalStateException;
00034 #include "beecrypt/c++/lang/NullPointerException.h"
00035 using beecrypt::lang::NullPointerException;
00036 #include "beecrypt/c++/lang/OutOfMemoryError.h"
00037 using beecrypt::lang::OutOfMemoryError;
00038 #include "beecrypt/c++/lang/UnsupportedOperationException.h"
00039 using beecrypt::lang::UnsupportedOperationException;
00040 #include "beecrypt/c++/util/Map.h"
00041 using beecrypt::util::Map;
00042 #include "beecrypt/c++/util/AbstractSet.h"
00043 using beecrypt::util::AbstractSet;
00044 #include "beecrypt/c++/util/ConcurrentModificationException.h"
00045 using beecrypt::util::ConcurrentModificationException;
00046
00047 namespace beecrypt {
00048 namespace util {
00051 template<class K, class V> class Hashtable : public Object, public virtual Map<K,V>, public virtual Cloneable
00052 {
00053 private:
00054 class Entry : public Object, public virtual Map<K,V>::Entry, public virtual Cloneable
00055 {
00056 public:
00057 jint hash;
00058 K* key;
00059 V* value;
00060 Entry* next;
00061
00062 Entry(jint hash, K* key, V* value, Entry* next = 0) : hash(hash), key(key), value(value), next(next)
00063 {
00064 }
00065 Entry(const Entry& copy) : hash(copy.hash), key(copy.key), value(copy.value), next(copy.next ? new Entry(*copy.next) : 0)
00066 {
00067 }
00068 virtual ~Entry() {}
00069
00070 virtual Entry* clone() const throw (CloneNotSupportedException)
00071 {
00072 return new Entry(*this);
00073 }
00074 virtual bool equals(const class Map<K,V>::Entry* e) const throw ()
00075 {
00076 if (this == e)
00077 return true;
00078
00079 return (key ? key->equals(e->getKey()) : (e->getKey() == 0)) &&
00080 (value ? value->equals(e->getValue()) : (e->getValue() == 0));
00081 }
00082 virtual bool equals(const Object* obj) const throw ()
00083 {
00084 if (this == obj)
00085 return true;
00086
00087 if (obj)
00088 {
00089 const class Map<K,V>::Entry* e = dynamic_cast<const class Map<K,V>::Entry*>(obj);
00090 if (e)
00091 return (key ? key->equals(e->getKey()) : (e->getKey() == 0)) &&
00092 (value ? value->equals(e->getValue()) : (e->getValue() == 0));
00093 }
00094 return false;
00095 }
00096 virtual K* getKey() const
00097 {
00098 return key;
00099 }
00100 virtual V* getValue() const
00101 {
00102 return value;
00103 }
00104 virtual jint hashCode() const throw ()
00105 {
00106 return hash ^ (value ? value->hashCode() : 0);
00107 }
00108 virtual V* setValue(V* val)
00109 {
00110 if (val)
00111 {
00112 V* result = value;
00113
00114 value = val;
00115
00116 return result;
00117 }
00118 else
00119 throw NullPointerException();
00120 }
00121 virtual String toString() const throw ()
00122 {
00123 StringBuilder tmp;
00124
00125 return tmp.append(key).append('=').append(value).toString();
00126 }
00127 };
00128
00129 class HashIter : public Object
00130 {
00131 private:
00132 Hashtable* _ht;
00133 const Hashtable* _const_ht;
00134
00135 protected:
00136 Entry* next;
00137 Entry* current;
00138 jint index;
00139 jint expect;
00140
00141 protected:
00142 HashIter(Hashtable* h) : _ht(h), _const_ht(h)
00143 {
00144 expect = _const_ht->_modCount;
00145 index = _const_ht->_table.size();
00146 next = current = 0;
00147 if (_const_ht->_count)
00148 while ((index > 0) && ((next = _const_ht->_table[--index]) == 0));
00149 }
00150 HashIter(const Hashtable* h) : _ht(0), _const_ht(h)
00151 {
00152 expect = _const_ht->_modCount;
00153 index = _const_ht->_table.size();
00154 next = current = 0;
00155 if (_const_ht->_count)
00156 while ((index > 0) && ((next = _const_ht->_table[--index]) == 0));
00157 }
00158
00159 public:
00160 virtual ~HashIter() {}
00161
00162 virtual bool hasNext() throw ()
00163 {
00164 return (next != 0);
00165 }
00166 Entry* nextEntry() throw (NoSuchElementException, ConcurrentModificationException)
00167 {
00168 if (_const_ht->_modCount != expect)
00169 throw ConcurrentModificationException();
00170
00171 Entry* e = next;
00172 if (!e)
00173 throw NoSuchElementException();
00174
00175 next = e->next;
00176 while (!next && index > 0)
00177 next = _const_ht->_table[--index];
00178
00179 return current = e;
00180 }
00181 virtual void remove()
00182 {
00183 if (!_ht)
00184 throw UnsupportedOperationException("Cannot remove items through const iterator");
00185
00186 if (!current)
00187 throw IllegalStateException();
00188
00189 if (_ht->_modCount != expect)
00190 throw ConcurrentModificationException();
00191
00192 K* key = current->key;
00193
00194 current = 0;
00195
00196 Entry* e = _ht->removeEntryForKey(key);
00197 if (e)
00198 {
00199 collection_remove(e->key);
00200 collection_remove(e->value);
00201
00202 delete e;
00203 }
00204
00205 expect = _ht->_modCount;
00206 }
00207 };
00208
00209 class EntryIter : public HashIter, public virtual Iterator<class Map<K,V>::Entry>
00210 {
00211 public:
00212 EntryIter(Hashtable* h) : HashIter(h)
00213 {
00214 }
00215 EntryIter(const Hashtable* h) : HashIter(h)
00216 {
00217 }
00218 virtual ~EntryIter() {}
00219
00220 virtual bool hasNext() throw ()
00221 {
00222 return HashIter::hasNext();
00223 }
00224 virtual class Map<K,V>::Entry* next() throw (NoSuchElementException)
00225 {
00226 return this->nextEntry();
00227 }
00228 virtual void remove()
00229 {
00230 HashIter::remove();
00231 }
00232 };
00233
00234 class KeyIter : public HashIter, public virtual Iterator<K>
00235 {
00236 public:
00237 KeyIter(Hashtable* h) : HashIter(h)
00238 {
00239 }
00240 KeyIter(const Hashtable* h) : HashIter(h)
00241 {
00242 }
00243 virtual ~KeyIter() {}
00244
00245 virtual bool hasNext() throw ()
00246 {
00247 return HashIter::hasNext();
00248 }
00249 virtual K* next() throw (NoSuchElementException)
00250 {
00251 return this->nextEntry()->key;
00252 }
00253 virtual void remove()
00254 {
00255 HashIter::remove();
00256 }
00257 };
00258
00259 class ValueIter : public HashIter, public virtual Iterator<V>
00260 {
00261 public:
00262 ValueIter(Hashtable* h) : HashIter(h)
00263 {
00264 }
00265 ValueIter(const Hashtable* h) : HashIter(h)
00266 {
00267 }
00268 virtual ~ValueIter() {}
00269
00270 virtual bool hasNext() throw ()
00271 {
00272 return HashIter::hasNext();
00273 }
00274 virtual V* next() throw (NoSuchElementException)
00275 {
00276 return this->nextEntry()->value;
00277 }
00278 virtual void remove()
00279 {
00280 HashIter::remove();
00281 }
00282 };
00283
00284 class EntrySet : public AbstractSet<class Map<K,V>::Entry>
00285 {
00286 private:
00287 Hashtable*_ht;
00288
00289 public:
00290 EntrySet(Hashtable* h) : _ht(h)
00291 {
00292 }
00293 virtual ~EntrySet() {}
00294
00295 virtual jint size() const throw ()
00296 {
00297 return _ht->size();
00298 }
00299 virtual Iterator<class Map<K,V>::Entry>* iterator()
00300 {
00301 return new EntryIter(_ht);
00302 }
00303 virtual Iterator<class Map<K,V>::Entry>* iterator() const
00304 {
00305 return new EntryIter(_ht);
00306 }
00307 };
00308
00309 class KeySet : public AbstractSet<K>
00310 {
00311 private:
00312 Hashtable* _ht;
00313
00314 public:
00315 KeySet(Hashtable* h) : _ht(h)
00316 {
00317 }
00318 virtual ~KeySet() {}
00319
00320 virtual jint size() const throw ()
00321 {
00322 return _ht->size();
00323 }
00324 virtual Iterator<K>* iterator()
00325 {
00326 return new KeyIter(_ht);
00327 }
00328 virtual Iterator<K>* iterator() const
00329 {
00330 return new KeyIter(_ht);
00331 }
00332 };
00333
00334 class ValueCollection : public AbstractCollection<V>
00335 {
00336 private:
00337 Hashtable* _ht;
00338
00339 public:
00340 ValueCollection(Hashtable* h) : _ht(h)
00341 {
00342 }
00343 virtual ~ValueCollection() {}
00344
00345 virtual jint size() const throw ()
00346 {
00347 return _ht->size();
00348 }
00349 virtual Iterator<V>* iterator()
00350 {
00351 return new ValueIter(_ht);
00352 }
00353 virtual Iterator<V>* iterator() const
00354 {
00355 return new ValueIter(_ht);
00356 }
00357 };
00358
00359 private:
00360 array<Entry*> _table;
00361 jint _count;
00362 jint _threshold;
00363 jfloat _loadFactor;
00364 jint _modCount;
00365
00366 mutable bool _hashing;
00367 mutable Set<class Map<K,V>::Entry>* _entries;
00368 mutable Set<K>* _keys;
00369 mutable Collection<V>* _values;
00370
00371 protected:
00372 Entry* removeEntryForKey(const K* key)
00373 {
00374 jint hash = key->hashCode();
00375 jint index = (hash & Integer::MAX_VALUE) % _table.size();
00376 Entry* prev = 0;
00377 for (Entry* e = _table[index]; e; prev = e, e = e->next)
00378 if (hash == e->hash && key->equals(e->key))
00379 {
00380 _modCount++;
00381
00382 if (prev)
00383 prev->next = e->next;
00384 else
00385 _table[index] = e->next;
00386
00387 _count--;
00388
00389 return e;
00390 }
00391 return 0;
00392 }
00393
00394 public:
00395 Hashtable(jint initialCapacity = 15, jfloat loadFactor = 0.75)
00396 {
00397 if (initialCapacity < 0 || loadFactor <= 0.0)
00398 throw IllegalArgumentException();
00399
00400 if (initialCapacity == 0)
00401 initialCapacity = 1;
00402
00403 _table.resize(initialCapacity);
00404 _threshold = (jint)(initialCapacity * (_loadFactor = loadFactor));
00405
00406 _count = 0;
00407 _modCount = 0;
00408
00409 _entries = 0;
00410 _keys = 0;
00411 _values = 0;
00412
00413 _hashing = false;
00414 }
00415 Hashtable(const Hashtable& copy) : _table(copy._table.size())
00416 {
00417 _loadFactor = copy._loadFactor;
00418 _threshold = copy._threshold;
00419
00420 _count = 0;
00421 _modCount = 0;
00422
00423 _entries = 0;
00424 _keys = 0;
00425 _values = 0;
00426
00427 _hashing = false;
00428
00429 putAll(copy);
00430 }
00431 virtual ~Hashtable()
00432 {
00433 clear();
00434
00435 delete _entries;
00436 delete _keys;
00437 delete _values;
00438 }
00439
00440 virtual void clear()
00441 {
00442 synchronized (this)
00443 {
00444 _modCount++;
00445
00446 for (jint index = _table.size(); index-- > 0; )
00447 {
00448 for (Entry* e = _table[index]; e; )
00449 {
00450 Entry *tmp = e->next;
00451
00452 collection_remove(e->key);
00453 collection_remove(e->value);
00454
00455 delete e;
00456
00457 e = tmp;
00458 }
00459 _table[index] = 0;
00460 }
00461 _count = 0;
00462 }
00463 }
00464 virtual Object* clone() const throw (CloneNotSupportedException)
00465 {
00466 Object* result = 0;
00467
00468 synchronized (this)
00469 {
00470 result = new Hashtable(*this);
00471 }
00472 return result;
00473 }
00474 virtual bool contains(const Object* obj) const
00475 {
00476 const V* value = dynamic_cast<const V*>(obj);
00477 if (value)
00478 return containsValue(value);
00479 else
00480 return false;
00481 }
00482 virtual bool containsKey(const K* key) const
00483 {
00484 if (!key)
00485 throw NullPointerException();
00486
00487 synchronized (this)
00488 {
00489 jint index = (key->hashCode() & Integer::MAX_VALUE) % _table.size();
00490 for (Entry* e = _table[index]; e; e = e->next)
00491 if (e->key->equals(key))
00492 return true;
00493 }
00494 return false;
00495 }
00496 virtual bool containsValue(const V* value) const
00497 {
00498 if (!value)
00499 throw NullPointerException();
00500
00501 synchronized (this)
00502 {
00503 for (jint i = 0; i < _table.size(); i++)
00504 for (Entry* e = _table[i]; e; e = e->next)
00505 if (e->value->equals(value))
00506 return true;
00507 }
00508 return false;
00509 }
00510 virtual Set<class Map<K,V>::Entry>& entrySet()
00511 {
00512 if (!_entries)
00513 {
00514 synchronized (this)
00515 {
00516 if (!_entries)
00517 _entries = new EntrySet(this);
00518 }
00519 }
00520 return *_entries;
00521 }
00522 virtual const Set<class Map<K,V>::Entry>& entrySet() const
00523 {
00524 if (!_entries)
00525 {
00526 synchronized (this)
00527 {
00528 if (!_entries)
00529 _entries = new EntrySet(const_cast<Hashtable*>(this));
00530 }
00531 }
00532 return *_entries;
00533 }
00534 virtual bool equals(const Object* obj) const throw ()
00535 {
00536 if (this == obj)
00537 return true;
00538
00539 if (obj)
00540 {
00541 const Map<K,V>* map = dynamic_cast<const Map<K,V>*>(obj);
00542 if (map)
00543 {
00544 synchronized (this)
00545 {
00546 if (_count != map->size())
00547 return false;
00548
00549 try
00550 {
00551 bool result = true;
00552 Iterator<class Map<K,V>::Entry>* mit = map->entrySet().iterator();
00553 assert(mit != 0);
00554 while (mit->hasNext())
00555 {
00556 class Map<K,V>::Entry* me = mit->next();
00557 K* key = me->getKey();
00558 V* value = me->getValue();
00559 if (value)
00560 {
00561 if (!(map->get(key) == 0 && map->containsKey(key)))
00562 {
00563 result = false;
00564 break;
00565 }
00566 }
00567 else
00568 {
00569 if (!value->equals(map->get(key)))
00570 {
00571 result = false;
00572 break;
00573 }
00574 }
00575 }
00576 delete mit;
00577 return result;
00578 }
00579 catch (Exception&)
00580 {
00581 }
00582 }
00583 }
00584 }
00585 return false;
00586 }
00587 virtual V* get(const K* key) const
00588 {
00589 if (key)
00590 {
00591 synchronized (this)
00592 {
00593 jint index = (key->hashCode() & Integer::MAX_VALUE) % _table.size();
00594 for (Entry* e = _table[index]; e; e = e->next)
00595 if (e->key->equals(key))
00596 return e->value;
00597 }
00598 return 0;
00599 }
00600 else
00601 throw NullPointerException();
00602 }
00603 virtual jint hashCode() const throw ()
00604 {
00605 jint result = 0;
00606
00607 synchronized (this)
00608 {
00609 if (_count == 0 || _hashing)
00610 return 0;
00611
00612 _hashing = true;
00613
00614 for (jint i = 0; i < _table.size(); i++)
00615 for (Entry* e = _table[i]; e; e = e->next)
00616 result += e->key->hashCode() ^ e->value->hashCode();
00617
00618 _hashing = false;
00619 }
00620
00621 return result;
00622 }
00623 virtual bool isEmpty() const throw ()
00624 {
00625 bool result = true;
00626
00627 synchronized (this)
00628 {
00629 result = (_count == 0);
00630 }
00631 return result;
00632 }
00633 virtual Set<K>& keySet()
00634 {
00635 if (_keys)
00636 {
00637 synchronized (this)
00638 {
00639 if (!_keys)
00640 _keys = new KeySet(this);
00641 }
00642 }
00643 return *_keys;
00644 }
00645 virtual const Set<K>& keySet() const
00646 {
00647 if (_keys)
00648 {
00649 synchronized (this)
00650 {
00651 if (!_keys)
00652 _keys = new KeySet(const_cast<Hashtable*>(this));
00653 }
00654 }
00655 return *_keys;
00656 }
00657 virtual V* put(K* key, V* value)
00658 {
00659 if (key && value)
00660 {
00661 jint hash = key->hashCode();
00662
00663 synchronized (this)
00664 {
00665 jint index = (hash & Integer::MAX_VALUE) % _table.size();
00666
00667 for (Entry* e = _table[index]; e != 0; e = e->next)
00668 {
00669 if (key->equals(e->key))
00670 {
00671
00672 V* result = e->value;
00673 e->value = value;
00674
00675 collection_attach(value);
00676 collection_detach(result);
00677
00678 return result;
00679 }
00680 }
00681
00682
00683 _modCount++;
00684
00685 if (_count >= _threshold)
00686 {
00687
00688 jint oldsize = _table.size();
00689
00690 if (oldsize == Integer::MAX_VALUE)
00691 throw OutOfMemoryError();
00692
00693 jint newsize = (_table.size() << 1) + 1;
00694
00695
00696 if (newsize < oldsize)
00697 newsize = Integer::MAX_VALUE;
00698
00699 array<Entry*> retable(newsize);
00700
00701 for (jint i = oldsize; i-- > 0; )
00702 {
00703 for (Entry* e = _table[i]; e != 0; )
00704 {
00705 Entry* tmp = e->next;
00706
00707 index = (e->hash & Integer::MAX_VALUE) % newsize;
00708 e->next = retable[index];
00709 retable[index] = e;
00710 e = tmp;
00711 }
00712 }
00713
00714
00715 _table.swap(retable);
00716
00717 _threshold = (jint)(newsize * _loadFactor);
00718
00719 index = (hash & Integer::MAX_VALUE) % _table.size();
00720 }
00721
00722 Entry* tmp = _table[index];
00723 _table[index] = new Entry(hash, key, value, tmp);
00724 _count++;
00725 collection_attach(key);
00726 collection_attach(value);
00727 }
00728 return 0;
00729 }
00730 else
00731 throw NullPointerException();
00732 }
00733 virtual void putAll(const Map<K,V>& m)
00734 {
00735 Iterator<class Map<K,V>::Entry>* mit = m.entrySet().iterator();
00736 assert(mit != 0);
00737 while (mit->hasNext())
00738 {
00739 class Map<K,V>::Entry* e = mit->next();
00740 V* tmp = put(e->getKey(), e->getValue());
00741 collection_rcheck(tmp);
00742 }
00743 delete mit;
00744 }
00745 virtual V* remove(const K* key)
00746 {
00747 if (key)
00748 {
00749 Entry* e = removeEntryForKey(key);
00750 if (e)
00751 {
00752 V* result = e->value;
00753
00754 collection_remove(e->key);
00755 collection_detach(result);
00756
00757 delete e;
00758
00759 return result;
00760 }
00761 return 0;
00762 }
00763 else
00764 throw NullPointerException();
00765 }
00766 virtual jint size() const throw ()
00767 {
00768 jint result = 0;
00769
00770 synchronized (this)
00771 {
00772 result = _count;
00773 }
00774 return result;
00775 }
00776 virtual Collection<V>& values()
00777 {
00778 if (!_values)
00779 {
00780 synchronized (this)
00781 {
00782 if (!_values)
00783 _values = new ValueCollection(this);
00784 }
00785 }
00786 return *_values;
00787 }
00788 virtual const Collection<V>& values() const
00789 {
00790 if (!_values)
00791 {
00792 synchronized (this)
00793 {
00794 if (!_values)
00795 _values = new ValueCollection(const_cast<Hashtable*>(this));
00796 }
00797 }
00798 return *_values;
00799 }
00800 };
00801 }
00802 }
00803
00804 #endif
00805
00806 #endif