activemq-cpp-3.6.0
HashMap.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef _DECAF_UTIL_HASHMAP_H_
19 #define _DECAF_UTIL_HASHMAP_H_
20 
21 #include <decaf/util/Config.h>
22 
23 #include <decaf/util/AbstractMap.h>
24 #include <decaf/util/AbstractSet.h>
25 #include <decaf/util/HashCode.h>
28 #include <decaf/lang/Pointer.h>
30 
31 namespace decaf {
32 namespace util {
33 
94  template<typename K, typename V, typename HASHCODE = HashCode<K> >
95  class HashMap : public AbstractMap<K, V> {
96  private:
97 
98  class HashMapEntry : public MapEntry<K, V> {
99  private:
100 
101  HashMapEntry(const HashMapEntry&);
102  HashMapEntry& operator= (const HashMapEntry&);
103 
104  public:
105 
106  int origKeyHash;
107 
108  HashMapEntry* next;
109 
110  HashMapEntry(const K& key, const V& value, int hash) : MapEntry<K, V>(), origKeyHash(hash), next(NULL) {
111  this->setKey(key);
112  this->setValue(value);
113  this->origKeyHash = hash;
114  }
115 
116  HashMapEntry(const K& key, const V& value) : MapEntry<K, V>(key, value), origKeyHash(0), next(NULL){
117  this->origKeyHash = HASHCODE()(key);
118  }
119 
120  };
121 
122  private:
123 
124  class AbstractMapIterator {
125  protected:
126 
127  mutable int position;
128  int expectedModCount;
129  HashMapEntry* futureEntry;
130  HashMapEntry* currentEntry;
131  HashMapEntry* prevEntry;
132 
133  HashMap* associatedMap;
134 
135  private:
136 
137  AbstractMapIterator(const AbstractMapIterator&);
138  AbstractMapIterator& operator= (const AbstractMapIterator&);
139 
140  public:
141 
142  AbstractMapIterator(HashMap* parent) : position(0),
143  expectedModCount(parent->modCount),
144  futureEntry(NULL),
145  currentEntry(NULL),
146  prevEntry(NULL),
147  associatedMap(parent) {
148  }
149 
150  virtual ~AbstractMapIterator() {}
151 
152  virtual bool checkHasNext() const {
153  if (futureEntry != NULL) {
154  return true;
155  }
156  while (position < associatedMap->elementData.length()) {
157  if (associatedMap->elementData[position] == NULL) {
158  position++;
159  } else {
160  return true;
161  }
162  }
163  return false;
164  }
165 
166  void checkConcurrentMod() const {
167  if (expectedModCount != associatedMap->modCount) {
169  __FILE__, __LINE__, "HashMap modified outside this iterator");
170  }
171  }
172 
173  void makeNext() {
174  checkConcurrentMod();
175 
176  if (!checkHasNext()) {
177  throw NoSuchElementException(__FILE__, __LINE__, "No next element");
178  }
179 
180  if (futureEntry == NULL) {
181  currentEntry = associatedMap->elementData[position++];
182  futureEntry = currentEntry->next;
183  prevEntry = NULL;
184  } else {
185  if (currentEntry != NULL){
186  prevEntry = currentEntry;
187  }
188  currentEntry = futureEntry;
189  futureEntry = futureEntry->next;
190  }
191  }
192 
193  virtual void doRemove() {
194 
195  checkConcurrentMod();
196 
197  if (currentEntry == NULL) {
199  __FILE__, __LINE__, "Remove called before call to next()");
200  }
201 
202  if (prevEntry == NULL){
203  int index = currentEntry->origKeyHash & (associatedMap->elementData.length() - 1);
204  associatedMap->elementData[index] = associatedMap->elementData[index]->next;
205  } else {
206  prevEntry->next = currentEntry->next;
207  }
208 
209  delete currentEntry;
210  currentEntry = NULL;
211 
212  expectedModCount++;
213  associatedMap->modCount++;
214  associatedMap->elementCount--;
215  }
216  };
217 
218  class EntryIterator : public Iterator< MapEntry<K,V> >, public AbstractMapIterator {
219  private:
220 
221  EntryIterator(const EntryIterator&);
222  EntryIterator& operator= (const EntryIterator&);
223 
224  public:
225 
226  EntryIterator(HashMap* parent) : AbstractMapIterator(parent) {
227  }
228 
229  virtual ~EntryIterator() {}
230 
231  virtual bool hasNext() const {
232  return this->checkHasNext();
233  }
234 
235  virtual MapEntry<K, V> next() {
236  this->makeNext();
237  return *(this->currentEntry);
238  }
239 
240  virtual void remove() {
241  this->doRemove();
242  }
243  };
244 
245  class KeyIterator : public Iterator<K>, public AbstractMapIterator {
246  private:
247 
248  KeyIterator(const KeyIterator&);
249  KeyIterator& operator= (const KeyIterator&);
250 
251  public:
252 
253  KeyIterator(HashMap* parent) : AbstractMapIterator(parent) {
254  }
255 
256  virtual ~KeyIterator() {}
257 
258  virtual bool hasNext() const {
259  return this->checkHasNext();
260  }
261 
262  virtual K next() {
263  this->makeNext();
264  return this->currentEntry->getKey();
265  }
266 
267  virtual void remove() {
268  this->doRemove();
269  }
270  };
271 
272  class ValueIterator : public Iterator<V>, public AbstractMapIterator {
273  private:
274 
275  ValueIterator(const ValueIterator&);
276  ValueIterator& operator= (const ValueIterator&);
277 
278  public:
279 
280  ValueIterator(HashMap* parent) : AbstractMapIterator(parent) {
281  }
282 
283  virtual ~ValueIterator() {}
284 
285  virtual bool hasNext() const {
286  return this->checkHasNext();
287  }
288 
289  virtual V next() {
290  this->makeNext();
291  return this->currentEntry->getValue();
292  }
293 
294  virtual void remove() {
295  this->doRemove();
296  }
297  };
298 
299  private:
300 
301  class ConstAbstractMapIterator {
302  protected:
303 
304  mutable int position;
305  int expectedModCount;
306  const HashMapEntry* futureEntry;
307  const HashMapEntry* currentEntry;
308  const HashMapEntry* prevEntry;
309 
310  const HashMap* associatedMap;
311 
312  private:
313 
314  ConstAbstractMapIterator(const ConstAbstractMapIterator&);
315  ConstAbstractMapIterator& operator= (const ConstAbstractMapIterator&);
316 
317  public:
318 
319  ConstAbstractMapIterator(const HashMap* parent) : position(0),
320  expectedModCount(parent->modCount),
321  futureEntry(NULL),
322  currentEntry(NULL),
323  prevEntry(NULL),
324  associatedMap(parent) {
325  }
326 
327  virtual ~ConstAbstractMapIterator() {}
328 
329  virtual bool checkHasNext() const {
330  if (futureEntry != NULL) {
331  return true;
332  }
333  while (position < associatedMap->elementData.length()) {
334  if (associatedMap->elementData[position] == NULL) {
335  position++;
336  } else {
337  return true;
338  }
339  }
340  return false;
341  }
342 
343  void checkConcurrentMod() const {
344  if (expectedModCount != associatedMap->modCount) {
346  __FILE__, __LINE__, "HashMap modified outside this iterator");
347  }
348  }
349 
350  void makeNext() {
351  checkConcurrentMod();
352 
353  if (!checkHasNext()) {
354  throw NoSuchElementException(__FILE__, __LINE__, "No next element");
355  }
356 
357  if (futureEntry == NULL) {
358  currentEntry = associatedMap->elementData[position++];
359  futureEntry = currentEntry->next;
360  prevEntry = NULL;
361  } else {
362  if (currentEntry != NULL){
363  prevEntry = currentEntry;
364  }
365  currentEntry = futureEntry;
366  futureEntry = futureEntry->next;
367  }
368  }
369  };
370 
371  class ConstEntryIterator : public Iterator< MapEntry<K,V> >, public ConstAbstractMapIterator {
372  private:
373 
374  ConstEntryIterator(const ConstEntryIterator&);
375  ConstEntryIterator& operator= (const ConstEntryIterator&);
376 
377  public:
378 
379  ConstEntryIterator(const HashMap* parent) : ConstAbstractMapIterator(parent) {
380  }
381 
382  virtual ~ConstEntryIterator() {}
383 
384  virtual bool hasNext() const {
385  return this->checkHasNext();
386  }
387 
388  virtual MapEntry<K, V> next() {
389  this->makeNext();
390  return *(this->currentEntry);
391  }
392 
393  virtual void remove() {
395  __FILE__, __LINE__, "Cannot write to a const Iterator." );
396  }
397  };
398 
399  class ConstKeyIterator : public Iterator<K>, public ConstAbstractMapIterator {
400  private:
401 
402  ConstKeyIterator(const ConstKeyIterator&);
403  ConstKeyIterator& operator= (const ConstKeyIterator&);
404 
405  public:
406 
407  ConstKeyIterator(const HashMap* parent) : ConstAbstractMapIterator(parent) {
408  }
409 
410  virtual ~ConstKeyIterator() {}
411 
412  virtual bool hasNext() const {
413  return this->checkHasNext();
414  }
415 
416  virtual K next() {
417  this->makeNext();
418  return this->currentEntry->getKey();
419  }
420 
421  virtual void remove() {
423  __FILE__, __LINE__, "Cannot write to a const Iterator." );
424  }
425  };
426 
427  class ConstValueIterator : public Iterator<V>, public ConstAbstractMapIterator {
428  private:
429 
430  ConstValueIterator(const ConstValueIterator&);
431  ConstValueIterator& operator= (const ConstValueIterator&);
432 
433  public:
434 
435  ConstValueIterator(const HashMap* parent) : ConstAbstractMapIterator(parent) {
436  }
437 
438  virtual ~ConstValueIterator() {}
439 
440  virtual bool hasNext() const {
441  return this->checkHasNext();
442  }
443 
444  virtual V next() {
445  this->makeNext();
446  return this->currentEntry->getValue();
447  }
448 
449  virtual void remove() {
451  __FILE__, __LINE__, "Cannot write to a const Iterator." );
452  }
453  };
454 
455  private:
456 
457  // Special Set implementation that is backed by this HashMap
458  class HashMapEntrySet : public AbstractSet< MapEntry<K, V> > {
459  private:
460 
461  HashMap* associatedMap;
462 
463  private:
464 
465  HashMapEntrySet(const HashMapEntrySet&);
466  HashMapEntrySet& operator= (const HashMapEntrySet&);
467 
468  public:
469 
470  HashMapEntrySet(HashMap* parent) : AbstractSet< MapEntry<K,V> >(), associatedMap(parent) {
471  }
472 
473  virtual ~HashMapEntrySet() {}
474 
475  virtual int size() const {
476  return associatedMap->elementCount;
477  }
478 
479  virtual void clear() {
480  associatedMap->clear();
481  }
482 
483  virtual bool remove(const MapEntry<K,V>& entry) {
484  HashMapEntry* result = associatedMap->getEntry(entry.getKey());
485  if (result != NULL && entry.getValue() == result->getValue()) {
486  associatedMap->removeEntry(result);
487  return true;
488  }
489 
490  return false;
491  }
492 
493  virtual bool contains(const MapEntry<K,V>& entry) {
494  HashMapEntry* result = associatedMap->getEntry(entry.getKey());
495  if (result != NULL && entry.getValue() == result->getValue()) {
496  return true;
497  }
498  return false;
499  }
500 
501  virtual Iterator< MapEntry<K, V> >* iterator() {
502  return new EntryIterator(associatedMap);
503  }
504 
505  virtual Iterator< MapEntry<K, V> >* iterator() const {
506  return new ConstEntryIterator(associatedMap);
507  }
508  };
509 
510  // Special Set implementation that is backed by this HashMap
511  class ConstHashMapEntrySet : public AbstractSet< MapEntry<K, V> > {
512  private:
513 
514  const HashMap* associatedMap;
515 
516  private:
517 
518  ConstHashMapEntrySet(const ConstHashMapEntrySet&);
519  ConstHashMapEntrySet& operator= (const ConstHashMapEntrySet&);
520 
521  public:
522 
523  ConstHashMapEntrySet(const HashMap* parent) : AbstractSet< MapEntry<K,V> >(), associatedMap(parent) {
524  }
525 
526  virtual ~ConstHashMapEntrySet() {}
527 
528  virtual int size() const {
529  return associatedMap->elementCount;
530  }
531 
532  virtual void clear() {
534  __FILE__, __LINE__, "Can't clear a const collection");
535  }
536 
537  virtual bool remove(const MapEntry<K,V>& entry) {
539  __FILE__, __LINE__, "Can't remove from const collection");
540  }
541 
542  virtual bool contains(const MapEntry<K,V>& entry) {
543  HashMapEntry* result = associatedMap->getEntry(entry.getKey());
544  if (result != NULL && entry.getValue() == result->getValue()) {
545  return true;
546  }
547  return false;
548  }
549 
550  virtual Iterator< MapEntry<K, V> >* iterator() {
552  __FILE__, __LINE__, "Can't return a non-const iterator for a const collection");
553  }
554 
555  virtual Iterator< MapEntry<K, V> >* iterator() const {
556  return new ConstEntryIterator(associatedMap);
557  }
558  };
559 
560  private:
561 
562  class HashMapKeySet : public AbstractSet<K> {
563  private:
564 
565  HashMap* associatedMap;
566 
567  private:
568 
569  HashMapKeySet(const HashMapKeySet&);
570  HashMapKeySet& operator= (const HashMapKeySet&);
571 
572  public:
573 
574  HashMapKeySet(HashMap* parent) : AbstractSet<K>(), associatedMap(parent) {
575  }
576 
577  virtual ~HashMapKeySet() {}
578 
579  virtual bool contains(const K& key) const {
580  return this->associatedMap->containsKey(key);
581  }
582 
583  virtual int size() const {
584  return this->associatedMap->size();
585  }
586 
587  virtual void clear() {
588  this->associatedMap->clear();
589  }
590 
591  virtual bool remove(const K& key) {
592  HashMapEntry* entry = this->associatedMap->removeEntry(key);
593  if (entry != NULL) {
594  delete entry;
595  return true;
596  }
597  return false;
598  }
599 
600  virtual Iterator<K>* iterator() {
601  return new KeyIterator(this->associatedMap);
602  }
603 
604  virtual Iterator<K>* iterator() const {
605  return new ConstKeyIterator(this->associatedMap);
606  }
607  };
608 
609  class ConstHashMapKeySet : public AbstractSet<K> {
610  private:
611 
612  const HashMap* associatedMap;
613 
614  private:
615 
616  ConstHashMapKeySet(const ConstHashMapKeySet&);
617  ConstHashMapKeySet& operator= (const ConstHashMapKeySet&);
618 
619  public:
620 
621  ConstHashMapKeySet(const HashMap* parent) : AbstractSet<K>(), associatedMap(parent) {
622  }
623 
624  virtual ~ConstHashMapKeySet() {}
625 
626  virtual bool contains(const K& key) const {
627  return this->associatedMap->containsKey(key);
628  }
629 
630  virtual int size() const {
631  return this->associatedMap->size();
632  }
633 
634  virtual void clear() {
636  __FILE__, __LINE__, "Can't modify a const collection");
637  }
638 
639  virtual bool remove(const K& key) {
641  __FILE__, __LINE__, "Can't modify a const collection");
642  }
643 
644  virtual Iterator<K>* iterator() {
646  __FILE__, __LINE__, "Can't return a non-const iterator for a const collection");
647  }
648 
649  virtual Iterator<K>* iterator() const {
650  return new ConstKeyIterator(this->associatedMap);
651  }
652  };
653 
654  private:
655 
656  class HashMapValueCollection : public AbstractCollection<V> {
657  private:
658 
659  HashMap* associatedMap;
660 
661  private:
662 
663  HashMapValueCollection(const HashMapValueCollection&);
664  HashMapValueCollection& operator= (const HashMapValueCollection&);
665 
666  public:
667 
668  HashMapValueCollection(HashMap* parent) : AbstractCollection<V>(), associatedMap(parent) {
669  }
670 
671  virtual ~HashMapValueCollection() {}
672 
673  virtual bool contains(const V& value) const {
674  return this->associatedMap->containsValue(value);
675  }
676 
677  virtual int size() const {
678  return this->associatedMap->size();
679  }
680 
681  virtual void clear() {
682  this->associatedMap->clear();
683  }
684 
685  virtual Iterator<V>* iterator() {
686  return new ValueIterator(this->associatedMap);
687  }
688 
689  virtual Iterator<V>* iterator() const {
690  return new ConstValueIterator(this->associatedMap);
691  }
692  };
693 
694  class ConstHashMapValueCollection : public AbstractCollection<V> {
695  private:
696 
697  const HashMap* associatedMap;
698 
699  private:
700 
701  ConstHashMapValueCollection(const ConstHashMapValueCollection&);
702  ConstHashMapValueCollection& operator= (const ConstHashMapValueCollection&);
703 
704  public:
705 
706  ConstHashMapValueCollection(const HashMap* parent) : AbstractCollection<V>(), associatedMap(parent) {
707  }
708 
709  virtual ~ConstHashMapValueCollection() {}
710 
711  virtual bool contains(const V& value) const {
712  return this->associatedMap->containsValue(value);
713  }
714 
715  virtual int size() const {
716  return this->associatedMap->size();
717  }
718 
719  virtual void clear() {
721  __FILE__, __LINE__, "Can't modify a const collection");
722  }
723 
724  virtual Iterator<V>* iterator() {
726  __FILE__, __LINE__, "Can't return a non-const iterator for a const collection");
727  }
728 
729  virtual Iterator<V>* iterator() const {
730  return new ConstValueIterator(this->associatedMap);
731  }
732  };
733 
734  private:
735 
739  HASHCODE hashFunc;
740 
741  /*
742  * Actual count of entries
743  */
744  int elementCount;
745 
746  /*
747  * The internal data structure to hold Entries, Array of MapEntry pointers.
748  */
750 
751  /*
752  * modification count, to keep track of structural modifications between the
753  * HashMap and the iterator
754  */
755  int modCount;
756 
757  /*
758  * maximum ratio of (stored elements)/(storage size) which does not lead to rehash
759  */
760  float loadFactor;
761 
762  /*
763  * maximum number of elements that can be put in this map before having to rehash
764  */
765  int threshold;
766 
767  // Cached values that are only initialized once a request for them is made.
770  decaf::lang::Pointer<HashMapValueCollection> cachedValueCollection;
771 
772  // Cached values that are only initialized once a request for them is made.
773  mutable decaf::lang::Pointer<ConstHashMapEntrySet> cachedConstEntrySet;
774  mutable decaf::lang::Pointer<ConstHashMapKeySet> cachedConstKeySet;
775  mutable decaf::lang::Pointer<ConstHashMapValueCollection> cachedConstValueCollection;
776 
777  private:
778 
779  void computeThreshold() {
780  threshold = (int) ((float) elementData.length() * loadFactor);
781  }
782 
783  static int calculateCapacity(int x) {
784  if (x >= 1 << 30) {
785  return 1 << 30;
786  }
787 
788  if (x == 0) {
789  return 16;
790  }
791  x = x - 1;
792  x |= x >> 1;
793  x |= x >> 2;
794  x |= x >> 4;
795  x |= x >> 8;
796  x |= x >> 16;
797  return x + 1;
798  }
799 
800  public:
801 
805  HashMap() : AbstractMap<K,V>(), hashFunc(), elementCount(0), elementData(),
806  modCount(0), loadFactor(0.75), threshold(0),
807  cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
808  cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
809  int capacity = calculateCapacity(12);
810  elementCount = 0;
811  elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
812  computeThreshold();
813  }
814 
823  HashMap(int capacity) : AbstractMap<K,V>(), hashFunc(), elementCount(0),
824  elementData(), modCount(0), loadFactor(0.75), threshold(0),
825  cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
826  cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
827  if (capacity >= 0) {
828  capacity = calculateCapacity(capacity);
829  elementCount = 0;
830  elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
831  computeThreshold();
832  } else {
834  __FILE__, __LINE__, "Invalid capacity configuration");
835  }
836  }
837 
848  HashMap(int capacity, float loadFactor) : AbstractMap<K,V>(), hashFunc(), elementCount(0),
849  elementData(), modCount(0), loadFactor(0.75), threshold(0),
850  cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
851  cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
852  if (capacity >= 0 && loadFactor > 0) {
853  capacity = calculateCapacity(capacity);
854  elementCount = 0;
855  elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
856  this->loadFactor = loadFactor;
857  computeThreshold();
858  } else {
860  __FILE__, __LINE__, "Invalid configuration");
861  }
862  }
863 
871  HashMap(const HashMap<K,V>& map) : AbstractMap<K,V>(), hashFunc(), elementCount(0), elementData(),
872  modCount(0), loadFactor(0.75), threshold(0),
873  cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
874  cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
875  int capacity = calculateCapacity(map.size());
876  elementCount = 0;
877  elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
878  computeThreshold();
879  putAll(map);
880  }
881 
889  HashMap(const Map<K,V>& map) : AbstractMap<K,V>(), hashFunc(), elementCount(0), elementData(),
890  modCount(0), loadFactor(0.75), threshold(0),
891  cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
892  cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
893  int capacity = calculateCapacity(map.size());
894  elementCount = 0;
895  elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
896  computeThreshold();
897  putAll(map);
898  }
899 
900  virtual ~HashMap() {
901  for (int i = 0; i < elementData.length(); i++) {
902  HashMapEntry* entry = elementData[i];
903  while (entry != NULL) {
904  HashMapEntry* temp = entry;
905  entry = entry->next;
906  delete temp;
907  }
908  }
909  }
910 
911  public:
912 
913  virtual void clear() {
914  if (elementCount > 0) {
915  elementCount = 0;
916  for (int i = 0; i < elementData.length(); ++i) {
917  HashMapEntry* entry = elementData[i];
918  elementData[i] = NULL;
919  while (entry != NULL) {
920  HashMapEntry* temp = entry;
921  entry = entry->next;
922  delete temp;
923  }
924  }
925  modCount++;
926  }
927  }
928 
929  virtual bool isEmpty() const {
930  return elementCount == 0;
931  }
932 
933  virtual int size() const {
934  return elementCount;
935  }
936 
937  virtual bool containsKey(const K& key) const {
938  const HashMapEntry* entry = getEntry(key);
939  return entry != NULL;
940  }
941 
942  virtual bool containsValue(const V& value) const {
943  for (int i = 0; i < elementData.length(); i++) {
944  const HashMapEntry* entry = elementData[i];
945  while (entry != NULL) {
946  if (value == entry->getValue()) {
947  return true;
948  }
949  entry = entry->next;
950  }
951  }
952  return false;
953  }
954 
955  virtual V& get(const K& key) {
956  HashMapEntry* entry = getEntry(key);
957  if (entry != NULL) {
958  return entry->getValue();
959  }
960 
962  __FILE__, __LINE__, "The specified key is not present in the Map");
963  }
964 
965  virtual const V& get(const K& key) const {
966  const HashMapEntry* entry = getEntry(key);
967  if (entry != NULL) {
968  return entry->getValue();
969  }
970 
972  __FILE__, __LINE__, "The specified key is not present in the Map");
973  }
974 
975  virtual bool put(const K& key, const V& value) {
976  return this->putImpl(key, value);
977  }
978 
979  virtual bool put(const K& key, const V& value, V& oldValue) {
980  return this->putImpl(key, value, oldValue);
981  }
982 
983  virtual void putAll(const Map<K, V>& map) {
984  if (!map.isEmpty()) {
985  putAllImpl(map);
986  }
987  }
988 
989  virtual V remove(const K& key) {
990  HashMapEntry* entry = removeEntry(key);
991  if (entry != NULL) {
992  V oldValue = entry->getValue();
993  delete entry;
994  return oldValue;
995  }
996 
998  __FILE__, __LINE__, "Specified key not present in the Map.");
999  }
1000 
1002  if (this->cachedEntrySet == NULL) {
1003  this->cachedEntrySet.reset(new HashMapEntrySet(this));
1004  }
1005  return *(this->cachedEntrySet);
1006  }
1007 
1008  virtual const Set< MapEntry<K,V> >& entrySet() const {
1009  if (this->cachedConstEntrySet == NULL) {
1010  this->cachedConstEntrySet.reset(new ConstHashMapEntrySet(this));
1011  }
1012  return *(this->cachedConstEntrySet);
1013  }
1014 
1015  virtual Set<K>& keySet() {
1016  if (this->cachedKeySet == NULL) {
1017  this->cachedKeySet.reset(new HashMapKeySet(this));
1018  }
1019  return *(this->cachedKeySet);
1020  }
1021 
1022  virtual const Set<K>& keySet() const {
1023  if (this->cachedConstKeySet == NULL) {
1024  this->cachedConstKeySet.reset(new ConstHashMapKeySet(this));
1025  }
1026  return *(this->cachedConstKeySet);
1027  }
1028 
1029  virtual Collection<V>& values() {
1030  if (this->cachedValueCollection == NULL) {
1031  this->cachedValueCollection.reset(new HashMapValueCollection(this));
1032  }
1033  return *(this->cachedValueCollection);
1034  }
1035 
1036  virtual const Collection<V>& values() const {
1037  if (this->cachedConstValueCollection == NULL) {
1038  this->cachedConstValueCollection.reset(new ConstHashMapValueCollection(this));
1039  }
1040  return *(this->cachedConstValueCollection);
1041  }
1042 
1043  virtual bool equals(const Map<K, V>& source) const {
1044  return false;
1045  }
1046 
1047  virtual void copy(const Map<K, V>& source) {
1048  int capacity = calculateCapacity(source.size());
1049  this->clear();
1050  if (capacity > elementData.length()) {
1051  elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
1052  }
1053  computeThreshold();
1054  putAll(source);
1055  }
1056 
1057  virtual std::string toString() const {
1058  return "HashMap";
1059  }
1060 
1061  protected:
1062 
1063  HashMapEntry* getEntry(const K& key) const {
1064  HashMapEntry* result = NULL;
1065 
1066  int hash = hashFunc(key);
1067  int index = hash & (elementData.length() - 1);
1068  result = findKeyEntry(key, index, hash);
1069 
1070  return result;
1071  }
1072 
1073  bool putImpl(const K& key, const V& value, V& oldValue) {
1074  bool replaced = true;
1075  HashMapEntry* entry = NULL;
1076 
1077  int hash = hashFunc(key);
1078  int index = hash & (elementData.length() - 1);
1079 
1080  entry = findKeyEntry(key, index, hash);
1081 
1082  if (entry == NULL) {
1083  modCount++;
1084  entry = createHashedEntry(key, index, hash);
1085  if (++elementCount > threshold) {
1086  rehash();
1087  }
1088  replaced = false;
1089  } else {
1090  oldValue = entry->getValue();
1091  }
1092 
1093  entry->setValue(value);
1094 
1095  return replaced;
1096  }
1097 
1098  bool putImpl(const K& key, const V& value) {
1099 
1100  bool replaced = true;
1101  HashMapEntry* entry = NULL;
1102 
1103  int hash = hashFunc(key);
1104  int index = hash & (elementData.length() - 1);
1105 
1106  entry = findKeyEntry(key, index, hash);
1107 
1108  if (entry == NULL) {
1109  modCount++;
1110  entry = createHashedEntry(key, index, hash);
1111  if (++elementCount > threshold) {
1112  rehash();
1113  }
1114  replaced = false;
1115  }
1116 
1117  entry->setValue(value);
1118 
1119  return replaced;
1120  }
1121 
1122  void putAllImpl(const Map<K, V>& map) {
1123  int capacity = elementCount + map.size();
1124  if (capacity > threshold) {
1125  rehash(capacity);
1126  }
1127 
1128  decaf::lang::Pointer<Iterator< MapEntry<K,V> > > iterator(map.entrySet().iterator());
1129  while (iterator->hasNext()) {
1130  MapEntry<K, V> entry = iterator->next();
1131  this->putImpl(entry.getKey(), entry.getValue());
1132  }
1133  }
1134 
1135  HashMapEntry* findKeyEntry(const K& key, int index, int keyHash) const {
1136  HashMapEntry* entry = elementData[index];
1137  while (entry != NULL && (entry->origKeyHash != keyHash || !(key == entry->getKey()))) {
1138  entry = entry->next;
1139  }
1140  return entry;
1141  }
1142 
1143  void rehash(int capacity) {
1144  int length = calculateCapacity((capacity == 0 ? 1 : capacity << 1));
1145 
1147  for (int i = 0; i < elementData.length(); i++) {
1148  HashMapEntry* entry = elementData[i];
1149  elementData[i] = NULL;
1150  while (entry != NULL) {
1151  int index = entry->origKeyHash & (length - 1);
1152  HashMapEntry* next = entry->next;
1153  entry->next = newData[index];
1154  newData[index] = entry;
1155  entry = next;
1156  }
1157  }
1158  elementData = newData;
1159  computeThreshold();
1160  }
1161 
1162  void rehash() {
1163  rehash(elementData.length());
1164  }
1165 
1166  HashMapEntry* createEntry(const K& key, int index, const V& value) {
1167  HashMapEntry* entry = new HashMapEntry(key, value);
1168  entry->next = elementData[index];
1169  elementData[index] = entry;
1170  return entry;
1171  }
1172 
1173  HashMapEntry* createHashedEntry(const K& key, int index, int hash) {
1174  HashMapEntry* entry = new HashMapEntry(key, V(), hash);
1175  entry->next = elementData[index];
1176  elementData[index] = entry;
1177  return entry;
1178  }
1179 
1180  // Removes the given entry from the map and deletes it
1181  void removeEntry(HashMapEntry* entry) {
1182  int index = entry->origKeyHash & (elementData.length() - 1);
1183  HashMapEntry* current = elementData[index];
1184  if (current == entry) {
1185  elementData[index] = entry->next;
1186  } else {
1187  while (current->next != entry) {
1188  current = current->next;
1189  }
1190  current->next = entry->next;
1191  }
1192  delete entry;
1193  modCount++;
1194  elementCount--;
1195  }
1196 
1197  // Removes but doesn't delete the entry in the map with the given key.
1198  HashMapEntry* removeEntry(const K& key) {
1199 
1200  int index = 0;
1201  HashMapEntry* current = NULL;
1202  HashMapEntry* last = NULL;
1203 
1204  int hash = hashFunc(key);
1205  index = hash & (elementData.length() - 1);
1206  current = elementData[index];
1207  while (current != NULL && !(current->origKeyHash == hash && key == current->getKey())) {
1208  last = current;
1209  current = current->next;
1210  }
1211 
1212  if (current == NULL) {
1213  return NULL;
1214  }
1215 
1216  if (last == NULL) {
1217  elementData[index] = current->next;
1218  } else {
1219  last->next = current->next;
1220  }
1221 
1222  modCount++;
1223  elementCount--;
1224  return current;
1225  }
1226 
1227  };
1228 
1229 }}
1230 
1231 #endif /* _DECAF_UTIL_HASHMAP_H_ */