00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _DECAF_UTIL_HASHMAP_H_
00019 #define _DECAF_UTIL_HASHMAP_H_
00020
00021 #include <decaf/util/Config.h>
00022
00023 #include <decaf/util/AbstractMap.h>
00024 #include <decaf/util/AbstractSet.h>
00025 #include <decaf/util/HashCode.h>
00026 #include <decaf/util/ConcurrentModificationException.h>
00027 #include <decaf/lang/exceptions/UnsupportedOperationException.h>
00028 #include <decaf/lang/Pointer.h>
00029 #include <decaf/lang/ArrayPointer.h>
00030
00031 namespace decaf {
00032 namespace util {
00033
00094 template<typename K, typename V, typename HASHCODE = HashCode<K> >
00095 class HashMap : public AbstractMap<K, V> {
00096 protected:
00097
00098 class HashMapEntry : public MapEntry<K, V> {
00099 private:
00100
00101 HashMapEntry(const HashMapEntry&);
00102 HashMapEntry& operator= (const HashMapEntry&);
00103
00104 public:
00105
00106 int origKeyHash;
00107
00108 HashMapEntry* next;
00109
00110 HashMapEntry(const K& key, const V& value, int hash) : MapEntry<K, V>(), origKeyHash(hash), next(NULL) {
00111 this->setKey(key);
00112 this->setValue(value);
00113 this->origKeyHash = hash;
00114 }
00115
00116 HashMapEntry(const K& key, const V& value) : MapEntry<K, V>(key, value), origKeyHash(0), next(NULL){
00117 this->origKeyHash = HASHCODE()(key);
00118 }
00119
00120 };
00121
00122 private:
00123
00124 class AbstractMapIterator {
00125 protected:
00126
00127 mutable int position;
00128 int expectedModCount;
00129 HashMapEntry* futureEntry;
00130 HashMapEntry* currentEntry;
00131 HashMapEntry* prevEntry;
00132
00133 HashMap* associatedMap;
00134
00135 private:
00136
00137 AbstractMapIterator(const AbstractMapIterator&);
00138 AbstractMapIterator& operator= (const AbstractMapIterator&);
00139
00140 public:
00141
00142 AbstractMapIterator(HashMap* parent) : position(0),
00143 expectedModCount(parent->modCount),
00144 futureEntry(NULL),
00145 currentEntry(NULL),
00146 prevEntry(NULL),
00147 associatedMap(parent) {
00148 }
00149
00150 virtual ~AbstractMapIterator() {}
00151
00152 virtual bool checkHasNext() const {
00153 if (futureEntry != NULL) {
00154 return true;
00155 }
00156 while (position < associatedMap->elementData.length()) {
00157 if (associatedMap->elementData[position] == NULL) {
00158 position++;
00159 } else {
00160 return true;
00161 }
00162 }
00163 return false;
00164 }
00165
00166 void checkConcurrentMod() const {
00167 if (expectedModCount != associatedMap->modCount) {
00168 throw ConcurrentModificationException(
00169 __FILE__, __LINE__, "HashMap modified outside this iterator");
00170 }
00171 }
00172
00173 void makeNext() {
00174 checkConcurrentMod();
00175
00176 if (!checkHasNext()) {
00177 throw NoSuchElementException(__FILE__, __LINE__, "No next element");
00178 }
00179
00180 if (futureEntry == NULL) {
00181 currentEntry = associatedMap->elementData[position++];
00182 futureEntry = currentEntry->next;
00183 prevEntry = NULL;
00184 } else {
00185 if (currentEntry != NULL){
00186 prevEntry = currentEntry;
00187 }
00188 currentEntry = futureEntry;
00189 futureEntry = futureEntry->next;
00190 }
00191 }
00192
00193 virtual void doRemove() {
00194
00195 checkConcurrentMod();
00196
00197 if (currentEntry == NULL) {
00198 throw decaf::lang::exceptions::IllegalStateException(
00199 __FILE__, __LINE__, "Remove called before call to next()");
00200 }
00201
00202 if (prevEntry == NULL){
00203 int index = currentEntry->origKeyHash & (associatedMap->elementData.length() - 1);
00204 associatedMap->elementData[index] = associatedMap->elementData[index]->next;
00205 } else {
00206 prevEntry->next = currentEntry->next;
00207 }
00208
00209 delete currentEntry;
00210 currentEntry = NULL;
00211
00212 expectedModCount++;
00213 associatedMap->modCount++;
00214 associatedMap->elementCount--;
00215 }
00216 };
00217
00218 class EntryIterator : public Iterator< MapEntry<K,V> >, public AbstractMapIterator {
00219 private:
00220
00221 EntryIterator(const EntryIterator&);
00222 EntryIterator& operator= (const EntryIterator&);
00223
00224 public:
00225
00226 EntryIterator(HashMap* parent) : AbstractMapIterator(parent) {
00227 }
00228
00229 virtual ~EntryIterator() {}
00230
00231 virtual bool hasNext() const {
00232 return this->checkHasNext();
00233 }
00234
00235 virtual MapEntry<K, V> next() {
00236 this->makeNext();
00237 return *(this->currentEntry);
00238 }
00239
00240 virtual void remove() {
00241 this->doRemove();
00242 }
00243 };
00244
00245 class KeyIterator : public Iterator<K>, public AbstractMapIterator {
00246 private:
00247
00248 KeyIterator(const KeyIterator&);
00249 KeyIterator& operator= (const KeyIterator&);
00250
00251 public:
00252
00253 KeyIterator(HashMap* parent) : AbstractMapIterator(parent) {
00254 }
00255
00256 virtual ~KeyIterator() {}
00257
00258 virtual bool hasNext() const {
00259 return this->checkHasNext();
00260 }
00261
00262 virtual K next() {
00263 this->makeNext();
00264 return this->currentEntry->getKey();
00265 }
00266
00267 virtual void remove() {
00268 this->doRemove();
00269 }
00270 };
00271
00272 class ValueIterator : public Iterator<V>, public AbstractMapIterator {
00273 private:
00274
00275 ValueIterator(const ValueIterator&);
00276 ValueIterator& operator= (const ValueIterator&);
00277
00278 public:
00279
00280 ValueIterator(HashMap* parent) : AbstractMapIterator(parent) {
00281 }
00282
00283 virtual ~ValueIterator() {}
00284
00285 virtual bool hasNext() const {
00286 return this->checkHasNext();
00287 }
00288
00289 virtual V next() {
00290 this->makeNext();
00291 return this->currentEntry->getValue();
00292 }
00293
00294 virtual void remove() {
00295 this->doRemove();
00296 }
00297 };
00298
00299 private:
00300
00301 class ConstAbstractMapIterator {
00302 protected:
00303
00304 mutable int position;
00305 int expectedModCount;
00306 const HashMapEntry* futureEntry;
00307 const HashMapEntry* currentEntry;
00308 const HashMapEntry* prevEntry;
00309
00310 const HashMap* associatedMap;
00311
00312 private:
00313
00314 ConstAbstractMapIterator(const ConstAbstractMapIterator&);
00315 ConstAbstractMapIterator& operator= (const ConstAbstractMapIterator&);
00316
00317 public:
00318
00319 ConstAbstractMapIterator(const HashMap* parent) : position(0),
00320 expectedModCount(parent->modCount),
00321 futureEntry(NULL),
00322 currentEntry(NULL),
00323 prevEntry(NULL),
00324 associatedMap(parent) {
00325 }
00326
00327 virtual ~ConstAbstractMapIterator() {}
00328
00329 virtual bool checkHasNext() const {
00330 if (futureEntry != NULL) {
00331 return true;
00332 }
00333 while (position < associatedMap->elementData.length()) {
00334 if (associatedMap->elementData[position] == NULL) {
00335 position++;
00336 } else {
00337 return true;
00338 }
00339 }
00340 return false;
00341 }
00342
00343 void checkConcurrentMod() const {
00344 if (expectedModCount != associatedMap->modCount) {
00345 throw ConcurrentModificationException(
00346 __FILE__, __LINE__, "HashMap modified outside this iterator");
00347 }
00348 }
00349
00350 void makeNext() {
00351 checkConcurrentMod();
00352
00353 if (!checkHasNext()) {
00354 throw NoSuchElementException(__FILE__, __LINE__, "No next element");
00355 }
00356
00357 if (futureEntry == NULL) {
00358 currentEntry = associatedMap->elementData[position++];
00359 futureEntry = currentEntry->next;
00360 prevEntry = NULL;
00361 } else {
00362 if (currentEntry != NULL){
00363 prevEntry = currentEntry;
00364 }
00365 currentEntry = futureEntry;
00366 futureEntry = futureEntry->next;
00367 }
00368 }
00369 };
00370
00371 class ConstEntryIterator : public Iterator< MapEntry<K,V> >, public ConstAbstractMapIterator {
00372 private:
00373
00374 ConstEntryIterator(const ConstEntryIterator&);
00375 ConstEntryIterator& operator= (const ConstEntryIterator&);
00376
00377 public:
00378
00379 ConstEntryIterator(const HashMap* parent) : ConstAbstractMapIterator(parent) {
00380 }
00381
00382 virtual ~ConstEntryIterator() {}
00383
00384 virtual bool hasNext() const {
00385 return this->checkHasNext();
00386 }
00387
00388 virtual MapEntry<K, V> next() {
00389 this->makeNext();
00390 return *(this->currentEntry);
00391 }
00392
00393 virtual void remove() {
00394 throw lang::exceptions::UnsupportedOperationException(
00395 __FILE__, __LINE__, "Cannot write to a const Iterator." );
00396 }
00397 };
00398
00399 class ConstKeyIterator : public Iterator<K>, public ConstAbstractMapIterator {
00400 private:
00401
00402 ConstKeyIterator(const ConstKeyIterator&);
00403 ConstKeyIterator& operator= (const ConstKeyIterator&);
00404
00405 public:
00406
00407 ConstKeyIterator(const HashMap* parent) : ConstAbstractMapIterator(parent) {
00408 }
00409
00410 virtual ~ConstKeyIterator() {}
00411
00412 virtual bool hasNext() const {
00413 return this->checkHasNext();
00414 }
00415
00416 virtual K next() {
00417 this->makeNext();
00418 return this->currentEntry->getKey();
00419 }
00420
00421 virtual void remove() {
00422 throw lang::exceptions::UnsupportedOperationException(
00423 __FILE__, __LINE__, "Cannot write to a const Iterator." );
00424 }
00425 };
00426
00427 class ConstValueIterator : public Iterator<V>, public ConstAbstractMapIterator {
00428 private:
00429
00430 ConstValueIterator(const ConstValueIterator&);
00431 ConstValueIterator& operator= (const ConstValueIterator&);
00432
00433 public:
00434
00435 ConstValueIterator(const HashMap* parent) : ConstAbstractMapIterator(parent) {
00436 }
00437
00438 virtual ~ConstValueIterator() {}
00439
00440 virtual bool hasNext() const {
00441 return this->checkHasNext();
00442 }
00443
00444 virtual V next() {
00445 this->makeNext();
00446 return this->currentEntry->getValue();
00447 }
00448
00449 virtual void remove() {
00450 throw lang::exceptions::UnsupportedOperationException(
00451 __FILE__, __LINE__, "Cannot write to a const Iterator." );
00452 }
00453 };
00454
00455 protected:
00456
00457
00458 class HashMapEntrySet : public AbstractSet< MapEntry<K, V> > {
00459 private:
00460
00461 HashMap* associatedMap;
00462
00463 private:
00464
00465 HashMapEntrySet(const HashMapEntrySet&);
00466 HashMapEntrySet& operator= (const HashMapEntrySet&);
00467
00468 public:
00469
00470 HashMapEntrySet(HashMap* parent) : AbstractSet< MapEntry<K,V> >(), associatedMap(parent) {
00471 }
00472
00473 virtual ~HashMapEntrySet() {}
00474
00475 virtual int size() const {
00476 return associatedMap->elementCount;
00477 }
00478
00479 virtual void clear() {
00480 associatedMap->clear();
00481 }
00482
00483 virtual bool remove(const MapEntry<K,V>& entry) {
00484 HashMapEntry* result = associatedMap->getEntry(entry.getKey());
00485 if (result != NULL && entry.getValue() == result->getValue()) {
00486 associatedMap->removeEntry(result);
00487 return true;
00488 }
00489
00490 return false;
00491 }
00492
00493 virtual bool contains(const MapEntry<K,V>& entry) {
00494 HashMapEntry* result = associatedMap->getEntry(entry.getKey());
00495 if (result != NULL && entry.getValue() == result->getValue()) {
00496 return true;
00497 }
00498 return false;
00499 }
00500
00501 virtual Iterator< MapEntry<K, V> >* iterator() {
00502 return new EntryIterator(associatedMap);
00503 }
00504
00505 virtual Iterator< MapEntry<K, V> >* iterator() const {
00506 return new ConstEntryIterator(associatedMap);
00507 }
00508 };
00509
00510
00511 class ConstHashMapEntrySet : public AbstractSet< MapEntry<K, V> > {
00512 private:
00513
00514 const HashMap* associatedMap;
00515
00516 private:
00517
00518 ConstHashMapEntrySet(const ConstHashMapEntrySet&);
00519 ConstHashMapEntrySet& operator= (const ConstHashMapEntrySet&);
00520
00521 public:
00522
00523 ConstHashMapEntrySet(const HashMap* parent) : AbstractSet< MapEntry<K,V> >(), associatedMap(parent) {
00524 }
00525
00526 virtual ~ConstHashMapEntrySet() {}
00527
00528 virtual int size() const {
00529 return associatedMap->elementCount;
00530 }
00531
00532 virtual void clear() {
00533 throw decaf::lang::exceptions::UnsupportedOperationException(
00534 __FILE__, __LINE__, "Can't clear a const collection");
00535 }
00536
00537 virtual bool remove(const MapEntry<K,V>& entry DECAF_UNUSED) {
00538 throw decaf::lang::exceptions::UnsupportedOperationException(
00539 __FILE__, __LINE__, "Can't remove from const collection");
00540 }
00541
00542 virtual bool contains(const MapEntry<K,V>& entry) {
00543 HashMapEntry* result = associatedMap->getEntry(entry.getKey());
00544 if (result != NULL && entry.getValue() == result->getValue()) {
00545 return true;
00546 }
00547 return false;
00548 }
00549
00550 virtual Iterator< MapEntry<K, V> >* iterator() {
00551 throw decaf::lang::exceptions::UnsupportedOperationException(
00552 __FILE__, __LINE__, "Can't return a non-const iterator for a const collection");
00553 }
00554
00555 virtual Iterator< MapEntry<K, V> >* iterator() const {
00556 return new ConstEntryIterator(associatedMap);
00557 }
00558 };
00559
00560 protected:
00561
00562 class HashMapKeySet : public AbstractSet<K> {
00563 private:
00564
00565 HashMap* associatedMap;
00566
00567 private:
00568
00569 HashMapKeySet(const HashMapKeySet&);
00570 HashMapKeySet& operator= (const HashMapKeySet&);
00571
00572 public:
00573
00574 HashMapKeySet(HashMap* parent) : AbstractSet<K>(), associatedMap(parent) {
00575 }
00576
00577 virtual ~HashMapKeySet() {}
00578
00579 virtual bool contains(const K& key) const {
00580 return this->associatedMap->containsKey(key);
00581 }
00582
00583 virtual int size() const {
00584 return this->associatedMap->size();
00585 }
00586
00587 virtual void clear() {
00588 this->associatedMap->clear();
00589 }
00590
00591 virtual bool remove(const K& key) {
00592 HashMapEntry* entry = this->associatedMap->removeEntry(key);
00593 if (entry != NULL) {
00594 delete entry;
00595 return true;
00596 }
00597 return false;
00598 }
00599
00600 virtual Iterator<K>* iterator() {
00601 return new KeyIterator(this->associatedMap);
00602 }
00603
00604 virtual Iterator<K>* iterator() const {
00605 return new ConstKeyIterator(this->associatedMap);
00606 }
00607 };
00608
00609 class ConstHashMapKeySet : public AbstractSet<K> {
00610 private:
00611
00612 const HashMap* associatedMap;
00613
00614 private:
00615
00616 ConstHashMapKeySet(const ConstHashMapKeySet&);
00617 ConstHashMapKeySet& operator= (const ConstHashMapKeySet&);
00618
00619 public:
00620
00621 ConstHashMapKeySet(const HashMap* parent) : AbstractSet<K>(), associatedMap(parent) {
00622 }
00623
00624 virtual ~ConstHashMapKeySet() {}
00625
00626 virtual bool contains(const K& key) const {
00627 return this->associatedMap->containsKey(key);
00628 }
00629
00630 virtual int size() const {
00631 return this->associatedMap->size();
00632 }
00633
00634 virtual void clear() {
00635 throw decaf::lang::exceptions::UnsupportedOperationException(
00636 __FILE__, __LINE__, "Can't modify a const collection");
00637 }
00638
00639 virtual bool remove(const K& key DECAF_UNUSED) {
00640 throw decaf::lang::exceptions::UnsupportedOperationException(
00641 __FILE__, __LINE__, "Can't modify a const collection");
00642 }
00643
00644 virtual Iterator<K>* iterator() {
00645 throw decaf::lang::exceptions::UnsupportedOperationException(
00646 __FILE__, __LINE__, "Can't return a non-const iterator for a const collection");
00647 }
00648
00649 virtual Iterator<K>* iterator() const {
00650 return new ConstKeyIterator(this->associatedMap);
00651 }
00652 };
00653
00654 protected:
00655
00656 class HashMapValueCollection : public AbstractCollection<V> {
00657 private:
00658
00659 HashMap* associatedMap;
00660
00661 private:
00662
00663 HashMapValueCollection(const HashMapValueCollection&);
00664 HashMapValueCollection& operator= (const HashMapValueCollection&);
00665
00666 public:
00667
00668 HashMapValueCollection(HashMap* parent) : AbstractCollection<V>(), associatedMap(parent) {
00669 }
00670
00671 virtual ~HashMapValueCollection() {}
00672
00673 virtual bool contains(const V& value) const {
00674 return this->associatedMap->containsValue(value);
00675 }
00676
00677 virtual int size() const {
00678 return this->associatedMap->size();
00679 }
00680
00681 virtual void clear() {
00682 this->associatedMap->clear();
00683 }
00684
00685 virtual Iterator<V>* iterator() {
00686 return new ValueIterator(this->associatedMap);
00687 }
00688
00689 virtual Iterator<V>* iterator() const {
00690 return new ConstValueIterator(this->associatedMap);
00691 }
00692 };
00693
00694 class ConstHashMapValueCollection : public AbstractCollection<V> {
00695 private:
00696
00697 const HashMap* associatedMap;
00698
00699 private:
00700
00701 ConstHashMapValueCollection(const ConstHashMapValueCollection&);
00702 ConstHashMapValueCollection& operator= (const ConstHashMapValueCollection&);
00703
00704 public:
00705
00706 ConstHashMapValueCollection(const HashMap* parent) : AbstractCollection<V>(), associatedMap(parent) {
00707 }
00708
00709 virtual ~ConstHashMapValueCollection() {}
00710
00711 virtual bool contains(const V& value) const {
00712 return this->associatedMap->containsValue(value);
00713 }
00714
00715 virtual int size() const {
00716 return this->associatedMap->size();
00717 }
00718
00719 virtual void clear() {
00720 throw decaf::lang::exceptions::UnsupportedOperationException(
00721 __FILE__, __LINE__, "Can't modify a const collection");
00722 }
00723
00724 virtual Iterator<V>* iterator() {
00725 throw decaf::lang::exceptions::UnsupportedOperationException(
00726 __FILE__, __LINE__, "Can't return a non-const iterator for a const collection");
00727 }
00728
00729 virtual Iterator<V>* iterator() const {
00730 return new ConstValueIterator(this->associatedMap);
00731 }
00732 };
00733
00734 protected:
00735
00739 HASHCODE hashFunc;
00740
00741
00742
00743
00744 int elementCount;
00745
00746
00747
00748
00749 decaf::lang::ArrayPointer<HashMapEntry*> elementData;
00750
00751
00752
00753
00754
00755 int modCount;
00756
00757
00758
00759
00760 float loadFactor;
00761
00762
00763
00764
00765 int threshold;
00766
00767
00768 decaf::lang::Pointer<HashMapEntrySet> cachedEntrySet;
00769 decaf::lang::Pointer<HashMapKeySet> cachedKeySet;
00770 decaf::lang::Pointer<HashMapValueCollection> cachedValueCollection;
00771
00772
00773 mutable decaf::lang::Pointer<ConstHashMapEntrySet> cachedConstEntrySet;
00774 mutable decaf::lang::Pointer<ConstHashMapKeySet> cachedConstKeySet;
00775 mutable decaf::lang::Pointer<ConstHashMapValueCollection> cachedConstValueCollection;
00776
00777 private:
00778
00779 void computeThreshold() {
00780 threshold = (int) ((float) elementData.length() * loadFactor);
00781 }
00782
00783 static int calculateCapacity(int x) {
00784 if (x >= 1 << 30) {
00785 return 1 << 30;
00786 }
00787
00788 if (x == 0) {
00789 return 16;
00790 }
00791 x = x - 1;
00792 x |= x >> 1;
00793 x |= x >> 2;
00794 x |= x >> 4;
00795 x |= x >> 8;
00796 x |= x >> 16;
00797 return x + 1;
00798 }
00799
00800 public:
00801
00805 HashMap() : AbstractMap<K,V>(), hashFunc(), elementCount(0), elementData(),
00806 modCount(0), loadFactor(0.75), threshold(0),
00807 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
00808 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
00809 int capacity = calculateCapacity(12);
00810 elementCount = 0;
00811 elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
00812 computeThreshold();
00813 }
00814
00823 HashMap(int capacity) : AbstractMap<K,V>(), hashFunc(), elementCount(0),
00824 elementData(), modCount(0), loadFactor(0.75), threshold(0),
00825 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
00826 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
00827 if (capacity >= 0) {
00828 capacity = calculateCapacity(capacity);
00829 elementCount = 0;
00830 elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
00831 computeThreshold();
00832 } else {
00833 throw decaf::lang::exceptions::IllegalArgumentException(
00834 __FILE__, __LINE__, "Invalid capacity configuration");
00835 }
00836 }
00837
00848 HashMap(int capacity, float loadFactor) : AbstractMap<K,V>(), hashFunc(), elementCount(0),
00849 elementData(), modCount(0), loadFactor(0.75), threshold(0),
00850 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
00851 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
00852 if (capacity >= 0 && loadFactor > 0) {
00853 capacity = calculateCapacity(capacity);
00854 elementCount = 0;
00855 elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
00856 this->loadFactor = loadFactor;
00857 computeThreshold();
00858 } else {
00859 throw decaf::lang::exceptions::IllegalArgumentException(
00860 __FILE__, __LINE__, "Invalid configuration");
00861 }
00862 }
00863
00871 HashMap(const HashMap<K,V>& map) : AbstractMap<K,V>(), hashFunc(), elementCount(0), elementData(),
00872 modCount(0), loadFactor(0.75), threshold(0),
00873 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
00874 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
00875 int capacity = calculateCapacity(map.size());
00876 elementCount = 0;
00877 elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
00878 computeThreshold();
00879 putAll(map);
00880 }
00881
00889 HashMap(const Map<K,V>& map) : AbstractMap<K,V>(), hashFunc(), elementCount(0), elementData(),
00890 modCount(0), loadFactor(0.75), threshold(0),
00891 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
00892 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
00893 int capacity = calculateCapacity(map.size());
00894 elementCount = 0;
00895 elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
00896 computeThreshold();
00897 putAll(map);
00898 }
00899
00900 virtual ~HashMap() {
00901 for (int i = 0; i < elementData.length(); i++) {
00902 HashMapEntry* entry = elementData[i];
00903 while (entry != NULL) {
00904 HashMapEntry* temp = entry;
00905 entry = entry->next;
00906 delete temp;
00907 }
00908 }
00909 }
00910
00911 public:
00912
00913 bool operator==(const Map<K, V>& other) const {
00914 return this->equals(other);
00915 }
00916
00917 bool operator!=(const Map<K, V>& other) const {
00918 return !this->equals(other);
00919 }
00920
00921 public:
00922
00923 virtual void clear() {
00924 if (elementCount > 0) {
00925 elementCount = 0;
00926 for (int i = 0; i < elementData.length(); ++i) {
00927 HashMapEntry* entry = elementData[i];
00928 elementData[i] = NULL;
00929 while (entry != NULL) {
00930 HashMapEntry* temp = entry;
00931 entry = entry->next;
00932 delete temp;
00933 }
00934 }
00935 modCount++;
00936 }
00937 }
00938
00939 virtual bool isEmpty() const {
00940 return elementCount == 0;
00941 }
00942
00943 virtual int size() const {
00944 return elementCount;
00945 }
00946
00947 virtual bool containsKey(const K& key) const {
00948 const HashMapEntry* entry = getEntry(key);
00949 return entry != NULL;
00950 }
00951
00952 virtual bool containsValue(const V& value) const {
00953 for (int i = 0; i < elementData.length(); i++) {
00954 const HashMapEntry* entry = elementData[i];
00955 while (entry != NULL) {
00956 if (value == entry->getValue()) {
00957 return true;
00958 }
00959 entry = entry->next;
00960 }
00961 }
00962 return false;
00963 }
00964
00965 virtual V& get(const K& key) {
00966 HashMapEntry* entry = getEntry(key);
00967 if (entry != NULL) {
00968 return entry->getValue();
00969 }
00970
00971 throw NoSuchElementException(
00972 __FILE__, __LINE__, "The specified key is not present in the Map");
00973 }
00974
00975 virtual const V& get(const K& key) const {
00976 const HashMapEntry* entry = getEntry(key);
00977 if (entry != NULL) {
00978 return entry->getValue();
00979 }
00980
00981 throw NoSuchElementException(
00982 __FILE__, __LINE__, "The specified key is not present in the Map");
00983 }
00984
00985 virtual bool put(const K& key, const V& value) {
00986 return this->putImpl(key, value);
00987 }
00988
00989 virtual bool put(const K& key, const V& value, V& oldValue) {
00990 return this->putImpl(key, value, oldValue);
00991 }
00992
00993 virtual void putAll(const Map<K, V>& map) {
00994 if (!map.isEmpty()) {
00995 putAllImpl(map);
00996 }
00997 }
00998
00999 virtual V remove(const K& key) {
01000 HashMapEntry* entry = removeEntry(key);
01001 if (entry != NULL) {
01002 V oldValue = entry->getValue();
01003 delete entry;
01004 return oldValue;
01005 }
01006
01007 throw NoSuchElementException(
01008 __FILE__, __LINE__, "Specified key not present in the Map.");
01009 }
01010
01011 virtual Set< MapEntry<K,V> >& entrySet() {
01012 if (this->cachedEntrySet == NULL) {
01013 this->cachedEntrySet.reset(new HashMapEntrySet(this));
01014 }
01015 return *(this->cachedEntrySet);
01016 }
01017
01018 virtual const Set< MapEntry<K,V> >& entrySet() const {
01019 if (this->cachedConstEntrySet == NULL) {
01020 this->cachedConstEntrySet.reset(new ConstHashMapEntrySet(this));
01021 }
01022 return *(this->cachedConstEntrySet);
01023 }
01024
01025 virtual Set<K>& keySet() {
01026 if (this->cachedKeySet == NULL) {
01027 this->cachedKeySet.reset(new HashMapKeySet(this));
01028 }
01029 return *(this->cachedKeySet);
01030 }
01031
01032 virtual const Set<K>& keySet() const {
01033 if (this->cachedConstKeySet == NULL) {
01034 this->cachedConstKeySet.reset(new ConstHashMapKeySet(this));
01035 }
01036 return *(this->cachedConstKeySet);
01037 }
01038
01039 virtual Collection<V>& values() {
01040 if (this->cachedValueCollection == NULL) {
01041 this->cachedValueCollection.reset(new HashMapValueCollection(this));
01042 }
01043 return *(this->cachedValueCollection);
01044 }
01045
01046 virtual const Collection<V>& values() const {
01047 if (this->cachedConstValueCollection == NULL) {
01048 this->cachedConstValueCollection.reset(new ConstHashMapValueCollection(this));
01049 }
01050 return *(this->cachedConstValueCollection);
01051 }
01052
01053 virtual bool equals(const Map<K, V>& source) const {
01054
01055 if (this == &source) {
01056 return true;
01057 }
01058
01059 if (size() != source.size()) {
01060 return false;
01061 }
01062
01063 try {
01064 decaf::lang::Pointer<Iterator<MapEntry<K, V> > > iter(entrySet().iterator());
01065 while (iter->hasNext() ) {
01066 MapEntry<K, V> entry = iter->next();
01067 K key = entry.getKey();
01068 V mine = entry.getValue();
01069
01070 if (!source.containsKey(key)) {
01071 return false;
01072 }
01073
01074 if (source.get(key) != mine) {
01075 return false;
01076 }
01077 }
01078 } catch (decaf::lang::exceptions::NullPointerException& ignored) {
01079 return false;
01080 } catch (decaf::lang::exceptions::ClassCastException& ignored) {
01081 return false;
01082 }
01083 return true;
01084 }
01085
01086 virtual void copy(const Map<K, V>& source) {
01087 int capacity = calculateCapacity(source.size());
01088 this->clear();
01089 if (capacity > elementData.length()) {
01090 elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
01091 }
01092 computeThreshold();
01093 putAll(source);
01094 }
01095
01096 virtual std::string toString() const {
01097 return "HashMap";
01098 }
01099
01100 protected:
01101
01102 virtual HashMapEntry* getEntry(const K& key) const {
01103 HashMapEntry* result = NULL;
01104
01105 int hash = hashFunc(key);
01106 int index = hash & (elementData.length() - 1);
01107 result = findKeyEntry(key, index, hash);
01108
01109 return result;
01110 }
01111
01112 virtual bool putImpl(const K& key, const V& value) {
01113 V oldValue;
01114 return putImpl(key, value, oldValue);
01115 }
01116
01117 virtual bool putImpl(const K& key, const V& value, V& oldValue) {
01118 bool replaced = true;
01119 HashMapEntry* entry = NULL;
01120
01121 int hash = hashFunc(key);
01122 int index = hash & (elementData.length() - 1);
01123
01124 entry = findKeyEntry(key, index, hash);
01125
01126 if (entry == NULL) {
01127 modCount++;
01128 entry = createHashedEntry(key, index, hash);
01129 if (++elementCount > threshold) {
01130 rehash();
01131 }
01132 replaced = false;
01133 } else {
01134 oldValue = entry->getValue();
01135 }
01136
01137 entry->setValue(value);
01138
01139 return replaced;
01140 }
01141
01142 virtual HashMapEntry* createEntry(const K& key, int index, const V& value) {
01143 HashMapEntry* entry = new HashMapEntry(key, value);
01144 entry->next = elementData[index];
01145 elementData[index] = entry;
01146 return entry;
01147 }
01148
01149 virtual HashMapEntry* createHashedEntry(const K& key, int index, int hash) {
01150 HashMapEntry* entry = new HashMapEntry(key, V(), hash);
01151 entry->next = elementData[index];
01152 elementData[index] = entry;
01153 return entry;
01154 }
01155
01156 protected:
01157
01158 void putAllImpl(const Map<K, V>& map) {
01159 int capacity = elementCount + map.size();
01160 if (capacity > threshold) {
01161 rehash(capacity);
01162 }
01163
01164 decaf::lang::Pointer<Iterator< MapEntry<K,V> > > iterator(map.entrySet().iterator());
01165 while (iterator->hasNext()) {
01166 MapEntry<K, V> entry = iterator->next();
01167 this->putImpl(entry.getKey(), entry.getValue());
01168 }
01169 }
01170
01171 HashMapEntry* findKeyEntry(const K& key, int index, int keyHash) const {
01172 HashMapEntry* entry = elementData[index];
01173 while (entry != NULL && (entry->origKeyHash != keyHash || !(key == entry->getKey()))) {
01174 entry = entry->next;
01175 }
01176 return entry;
01177 }
01178
01179 void rehash(int capacity) {
01180 int length = calculateCapacity((capacity == 0 ? 1 : capacity << 1));
01181
01182 decaf::lang::ArrayPointer<HashMapEntry*> newData(length);
01183 for (int i = 0; i < elementData.length(); i++) {
01184 HashMapEntry* entry = elementData[i];
01185 elementData[i] = NULL;
01186 while (entry != NULL) {
01187 int index = entry->origKeyHash & (length - 1);
01188 HashMapEntry* next = entry->next;
01189 entry->next = newData[index];
01190 newData[index] = entry;
01191 entry = next;
01192 }
01193 }
01194 elementData = newData;
01195 computeThreshold();
01196 }
01197
01198 void rehash() {
01199 rehash(elementData.length());
01200 }
01201
01202
01203 void removeEntry(HashMapEntry* entry) {
01204 int index = entry->origKeyHash & (elementData.length() - 1);
01205 HashMapEntry* current = elementData[index];
01206 if (current == entry) {
01207 elementData[index] = entry->next;
01208 } else {
01209 while (current->next != entry) {
01210 current = current->next;
01211 }
01212 current->next = entry->next;
01213 }
01214 delete entry;
01215 modCount++;
01216 elementCount--;
01217 }
01218
01219
01220 HashMapEntry* removeEntry(const K& key) {
01221
01222 int index = 0;
01223 HashMapEntry* current = NULL;
01224 HashMapEntry* last = NULL;
01225
01226 int hash = hashFunc(key);
01227 index = hash & (elementData.length() - 1);
01228 current = elementData[index];
01229 while (current != NULL && !(current->origKeyHash == hash && key == current->getKey())) {
01230 last = current;
01231 current = current->next;
01232 }
01233
01234 if (current == NULL) {
01235 return NULL;
01236 }
01237
01238 if (last == NULL) {
01239 elementData[index] = current->next;
01240 } else {
01241 last->next = current->next;
01242 }
01243
01244 modCount++;
01245 elementCount--;
01246 return current;
01247 }
01248
01249 };
01250
01251 }}
01252
01253 #endif