18 #ifndef _DECAF_UTIL_HASHMAP_H_
19 #define _DECAF_UTIL_HASHMAP_H_
94 template<
typename K,
typename V,
typename HASHCODE = HashCode<K> >
98 class HashMapEntry :
public MapEntry<K, V> {
101 HashMapEntry(
const HashMapEntry&);
102 HashMapEntry& operator= (
const HashMapEntry&);
110 HashMapEntry(
const K& key,
const V& value,
int hash) :
MapEntry<K, V>(), origKeyHash(hash), next(
NULL) {
112 this->setValue(value);
113 this->origKeyHash = hash;
116 HashMapEntry(
const K& key,
const V& value) :
MapEntry<K, V>(key, value), origKeyHash(0), next(
NULL){
117 this->origKeyHash = HASHCODE()(key);
124 class AbstractMapIterator {
127 mutable int position;
128 int expectedModCount;
129 HashMapEntry* futureEntry;
130 HashMapEntry* currentEntry;
131 HashMapEntry* prevEntry;
137 AbstractMapIterator(
const AbstractMapIterator&);
138 AbstractMapIterator& operator= (
const AbstractMapIterator&);
142 AbstractMapIterator(
HashMap* parent) : position(0),
143 expectedModCount(parent->modCount),
147 associatedMap(parent) {
150 virtual ~AbstractMapIterator() {}
152 virtual bool checkHasNext()
const {
153 if (futureEntry !=
NULL) {
156 while (position < associatedMap->elementData.length()) {
157 if (associatedMap->elementData[position] ==
NULL) {
166 void checkConcurrentMod()
const {
167 if (expectedModCount != associatedMap->modCount) {
169 __FILE__, __LINE__,
"HashMap modified outside this iterator");
174 checkConcurrentMod();
176 if (!checkHasNext()) {
180 if (futureEntry ==
NULL) {
181 currentEntry = associatedMap->elementData[position++];
182 futureEntry = currentEntry->next;
185 if (currentEntry !=
NULL){
186 prevEntry = currentEntry;
188 currentEntry = futureEntry;
189 futureEntry = futureEntry->next;
193 virtual void doRemove() {
195 checkConcurrentMod();
197 if (currentEntry ==
NULL) {
199 __FILE__, __LINE__,
"Remove called before call to next()");
202 if (prevEntry ==
NULL){
203 int index = currentEntry->origKeyHash & (associatedMap->elementData.length() - 1);
204 associatedMap->elementData[index] = associatedMap->elementData[index]->next;
206 prevEntry->next = currentEntry->next;
213 associatedMap->modCount++;
214 associatedMap->elementCount--;
218 class EntryIterator :
public Iterator< MapEntry<K,V> >,
public AbstractMapIterator {
221 EntryIterator(
const EntryIterator&);
222 EntryIterator& operator= (
const EntryIterator&);
226 EntryIterator(
HashMap* parent) : AbstractMapIterator(parent) {
229 virtual ~EntryIterator() {}
231 virtual bool hasNext()
const {
232 return this->checkHasNext();
237 return *(this->currentEntry);
240 virtual void remove() {
245 class KeyIterator :
public Iterator<K>,
public AbstractMapIterator {
248 KeyIterator(
const KeyIterator&);
249 KeyIterator& operator= (
const KeyIterator&);
253 KeyIterator(
HashMap* parent) : AbstractMapIterator(parent) {
256 virtual ~KeyIterator() {}
258 virtual bool hasNext()
const {
259 return this->checkHasNext();
264 return this->currentEntry->getKey();
267 virtual void remove() {
272 class ValueIterator :
public Iterator<V>,
public AbstractMapIterator {
275 ValueIterator(
const ValueIterator&);
276 ValueIterator& operator= (
const ValueIterator&);
280 ValueIterator(
HashMap* parent) : AbstractMapIterator(parent) {
283 virtual ~ValueIterator() {}
285 virtual bool hasNext()
const {
286 return this->checkHasNext();
291 return this->currentEntry->getValue();
294 virtual void remove() {
301 class ConstAbstractMapIterator {
304 mutable int position;
305 int expectedModCount;
306 const HashMapEntry* futureEntry;
307 const HashMapEntry* currentEntry;
308 const HashMapEntry* prevEntry;
314 ConstAbstractMapIterator(
const ConstAbstractMapIterator&);
315 ConstAbstractMapIterator& operator= (
const ConstAbstractMapIterator&);
319 ConstAbstractMapIterator(
const HashMap* parent) : position(0),
320 expectedModCount(parent->modCount),
324 associatedMap(parent) {
327 virtual ~ConstAbstractMapIterator() {}
329 virtual bool checkHasNext()
const {
330 if (futureEntry !=
NULL) {
333 while (position < associatedMap->elementData.length()) {
334 if (associatedMap->elementData[position] ==
NULL) {
343 void checkConcurrentMod()
const {
344 if (expectedModCount != associatedMap->modCount) {
346 __FILE__, __LINE__,
"HashMap modified outside this iterator");
351 checkConcurrentMod();
353 if (!checkHasNext()) {
357 if (futureEntry ==
NULL) {
358 currentEntry = associatedMap->elementData[position++];
359 futureEntry = currentEntry->next;
362 if (currentEntry !=
NULL){
363 prevEntry = currentEntry;
365 currentEntry = futureEntry;
366 futureEntry = futureEntry->next;
371 class ConstEntryIterator :
public Iterator< MapEntry<K,V> >,
public ConstAbstractMapIterator {
374 ConstEntryIterator(
const ConstEntryIterator&);
375 ConstEntryIterator& operator= (
const ConstEntryIterator&);
379 ConstEntryIterator(
const HashMap* parent) : ConstAbstractMapIterator(parent) {
382 virtual ~ConstEntryIterator() {}
384 virtual bool hasNext()
const {
385 return this->checkHasNext();
390 return *(this->currentEntry);
393 virtual void remove() {
395 __FILE__, __LINE__,
"Cannot write to a const Iterator." );
399 class ConstKeyIterator :
public Iterator<K>,
public ConstAbstractMapIterator {
402 ConstKeyIterator(
const ConstKeyIterator&);
403 ConstKeyIterator& operator= (
const ConstKeyIterator&);
407 ConstKeyIterator(
const HashMap* parent) : ConstAbstractMapIterator(parent) {
410 virtual ~ConstKeyIterator() {}
412 virtual bool hasNext()
const {
413 return this->checkHasNext();
418 return this->currentEntry->getKey();
421 virtual void remove() {
423 __FILE__, __LINE__,
"Cannot write to a const Iterator." );
427 class ConstValueIterator :
public Iterator<V>,
public ConstAbstractMapIterator {
430 ConstValueIterator(
const ConstValueIterator&);
431 ConstValueIterator& operator= (
const ConstValueIterator&);
435 ConstValueIterator(
const HashMap* parent) : ConstAbstractMapIterator(parent) {
438 virtual ~ConstValueIterator() {}
440 virtual bool hasNext()
const {
441 return this->checkHasNext();
446 return this->currentEntry->getValue();
449 virtual void remove() {
451 __FILE__, __LINE__,
"Cannot write to a const Iterator." );
458 class HashMapEntrySet :
public AbstractSet< MapEntry<K, V> > {
465 HashMapEntrySet(
const HashMapEntrySet&);
466 HashMapEntrySet& operator= (
const HashMapEntrySet&);
473 virtual ~HashMapEntrySet() {}
475 virtual int size()
const {
476 return associatedMap->elementCount;
479 virtual void clear() {
480 associatedMap->clear();
484 HashMapEntry* result = associatedMap->getEntry(entry.getKey());
485 if (result !=
NULL && entry.getValue() == result->getValue()) {
486 associatedMap->removeEntry(result);
494 HashMapEntry* result = associatedMap->getEntry(entry.
getKey());
495 if (result !=
NULL && entry.
getValue() == result->getValue()) {
502 return new EntryIterator(associatedMap);
506 return new ConstEntryIterator(associatedMap);
511 class ConstHashMapEntrySet :
public AbstractSet< MapEntry<K, V> > {
518 ConstHashMapEntrySet(
const ConstHashMapEntrySet&);
519 ConstHashMapEntrySet& operator= (
const ConstHashMapEntrySet&);
526 virtual ~ConstHashMapEntrySet() {}
528 virtual int size()
const {
529 return associatedMap->elementCount;
532 virtual void clear() {
534 __FILE__, __LINE__,
"Can't clear a const collection");
539 __FILE__, __LINE__,
"Can't remove from const collection");
543 HashMapEntry* result = associatedMap->getEntry(entry.
getKey());
544 if (result !=
NULL && entry.
getValue() == result->getValue()) {
552 __FILE__, __LINE__,
"Can't return a non-const iterator for a const collection");
556 return new ConstEntryIterator(associatedMap);
569 HashMapKeySet(
const HashMapKeySet&);
570 HashMapKeySet& operator= (
const HashMapKeySet&);
577 virtual ~HashMapKeySet() {}
579 virtual bool contains(
const K& key)
const {
580 return this->associatedMap->containsKey(key);
583 virtual int size()
const {
584 return this->associatedMap->size();
587 virtual void clear() {
588 this->associatedMap->clear();
591 virtual bool remove(
const K& key) {
592 HashMapEntry* entry = this->associatedMap->removeEntry(key);
601 return new KeyIterator(this->associatedMap);
605 return new ConstKeyIterator(this->associatedMap);
616 ConstHashMapKeySet(
const ConstHashMapKeySet&);
617 ConstHashMapKeySet& operator= (
const ConstHashMapKeySet&);
624 virtual ~ConstHashMapKeySet() {}
626 virtual bool contains(
const K& key)
const {
627 return this->associatedMap->containsKey(key);
630 virtual int size()
const {
631 return this->associatedMap->size();
634 virtual void clear() {
636 __FILE__, __LINE__,
"Can't modify a const collection");
639 virtual bool remove(
const K& key) {
641 __FILE__, __LINE__,
"Can't modify a const collection");
646 __FILE__, __LINE__,
"Can't return a non-const iterator for a const collection");
650 return new ConstKeyIterator(this->associatedMap);
663 HashMapValueCollection(
const HashMapValueCollection&);
664 HashMapValueCollection& operator= (
const HashMapValueCollection&);
671 virtual ~HashMapValueCollection() {}
673 virtual bool contains(
const V& value)
const {
674 return this->associatedMap->containsValue(value);
677 virtual int size()
const {
678 return this->associatedMap->size();
681 virtual void clear() {
682 this->associatedMap->clear();
686 return new ValueIterator(this->associatedMap);
690 return new ConstValueIterator(this->associatedMap);
701 ConstHashMapValueCollection(
const ConstHashMapValueCollection&);
702 ConstHashMapValueCollection& operator= (
const ConstHashMapValueCollection&);
709 virtual ~ConstHashMapValueCollection() {}
711 virtual bool contains(
const V& value)
const {
712 return this->associatedMap->containsValue(value);
715 virtual int size()
const {
716 return this->associatedMap->size();
719 virtual void clear() {
721 __FILE__, __LINE__,
"Can't modify a const collection");
726 __FILE__, __LINE__,
"Can't return a non-const iterator for a const collection");
730 return new ConstValueIterator(this->associatedMap);
779 void computeThreshold() {
780 threshold = (int) ((
float) elementData.
length() * loadFactor);
783 static int calculateCapacity(
int x) {
806 modCount(0), loadFactor(0.75), threshold(0),
807 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
808 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
809 int capacity = calculateCapacity(12);
824 elementData(), modCount(0), loadFactor(0.75), threshold(0),
825 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
826 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
828 capacity = calculateCapacity(capacity);
834 __FILE__, __LINE__,
"Invalid capacity configuration");
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);
856 this->loadFactor = loadFactor;
860 __FILE__, __LINE__,
"Invalid configuration");
872 modCount(0), loadFactor(0.75), threshold(0),
873 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
874 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
875 int capacity = calculateCapacity(map.
size());
890 modCount(0), loadFactor(0.75), threshold(0),
891 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
892 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
893 int capacity = calculateCapacity(map.
size());
901 for (
int i = 0; i < elementData.
length(); i++) {
902 HashMapEntry* entry = elementData[i];
903 while (entry !=
NULL) {
904 HashMapEntry* temp = entry;
914 if (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;
930 return elementCount == 0;
938 const HashMapEntry* entry =
getEntry(key);
939 return entry !=
NULL;
943 for (
int i = 0; i < elementData.
length(); i++) {
944 const HashMapEntry* entry = elementData[i];
945 while (entry !=
NULL) {
946 if (value == entry->getValue()) {
955 virtual V&
get(
const K& key) {
956 HashMapEntry* entry =
getEntry(key);
958 return entry->getValue();
962 __FILE__, __LINE__,
"The specified key is not present in the Map");
965 virtual const V&
get(
const K& key)
const {
966 const HashMapEntry* entry =
getEntry(key);
968 return entry->getValue();
972 __FILE__, __LINE__,
"The specified key is not present in the Map");
975 virtual bool put(
const K& key,
const V& value) {
976 return this->
putImpl(key, value);
979 virtual bool put(
const K& key,
const V& value, V& oldValue) {
980 return this->
putImpl(key, value, oldValue);
989 virtual V
remove(
const K& key) {
992 V oldValue = entry->getValue();
998 __FILE__, __LINE__,
"Specified key not present in the Map.");
1002 if (this->cachedEntrySet ==
NULL) {
1003 this->cachedEntrySet.
reset(
new HashMapEntrySet(
this));
1005 return *(this->cachedEntrySet);
1009 if (this->cachedConstEntrySet ==
NULL) {
1010 this->cachedConstEntrySet.
reset(
new ConstHashMapEntrySet(
this));
1012 return *(this->cachedConstEntrySet);
1016 if (this->cachedKeySet ==
NULL) {
1017 this->cachedKeySet.
reset(
new HashMapKeySet(
this));
1019 return *(this->cachedKeySet);
1023 if (this->cachedConstKeySet ==
NULL) {
1024 this->cachedConstKeySet.
reset(
new ConstHashMapKeySet(
this));
1026 return *(this->cachedConstKeySet);
1030 if (this->cachedValueCollection ==
NULL) {
1031 this->cachedValueCollection.
reset(
new HashMapValueCollection(
this));
1033 return *(this->cachedValueCollection);
1037 if (this->cachedConstValueCollection ==
NULL) {
1038 this->cachedConstValueCollection.
reset(
new ConstHashMapValueCollection(
this));
1040 return *(this->cachedConstValueCollection);
1048 int capacity = calculateCapacity(source.
size());
1050 if (capacity > elementData.
length()) {
1064 HashMapEntry* result =
NULL;
1066 int hash = hashFunc(key);
1067 int index = hash & (elementData.
length() - 1);
1073 bool putImpl(
const K& key,
const V& value, V& oldValue) {
1074 bool replaced =
true;
1075 HashMapEntry* entry =
NULL;
1077 int hash = hashFunc(key);
1078 int index = hash & (elementData.
length() - 1);
1082 if (entry ==
NULL) {
1085 if (++elementCount > threshold) {
1090 oldValue = entry->getValue();
1093 entry->setValue(value);
1100 bool replaced =
true;
1101 HashMapEntry* entry =
NULL;
1103 int hash = hashFunc(key);
1104 int index = hash & (elementData.
length() - 1);
1108 if (entry ==
NULL) {
1111 if (++elementCount > threshold) {
1117 entry->setValue(value);
1123 int capacity = elementCount + map.
size();
1124 if (capacity > threshold) {
1129 while (iterator->hasNext()) {
1136 HashMapEntry* entry = elementData[index];
1137 while (entry !=
NULL && (entry->origKeyHash != keyHash || !(key == entry->getKey()))) {
1138 entry = entry->next;
1144 int length = calculateCapacity((capacity == 0 ? 1 : capacity << 1));
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;
1158 elementData = newData;
1167 HashMapEntry* entry =
new HashMapEntry(key, value);
1168 entry->next = elementData[index];
1169 elementData[index] = entry;
1174 HashMapEntry* entry =
new HashMapEntry(key, V(), hash);
1175 entry->next = elementData[index];
1176 elementData[index] = entry;
1182 int index = entry->origKeyHash & (elementData.
length() - 1);
1183 HashMapEntry* current = elementData[index];
1184 if (current == entry) {
1185 elementData[index] = entry->next;
1187 while (current->next != entry) {
1188 current = current->next;
1190 current->next = entry->next;
1201 HashMapEntry* current =
NULL;
1202 HashMapEntry* last =
NULL;
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())) {
1209 current = current->next;
1212 if (current ==
NULL) {
1217 elementData[index] = current->next;
1219 last->next = current->next;