18 #ifndef _DECAF_UTIL_CONCURRENTSTLMAP_H_
19 #define _DECAF_UTIL_CONCURRENTSTLMAP_H_
50 template <
typename K,
typename V,
typename COMPARATOR = std::less<K> >
54 std::map<K,V,COMPARATOR> valueMap;
60 class AbstractMapIterator {
65 typename std::map<K,V,COMPARATOR>::iterator futureEntry;
66 typename std::map<K,V,COMPARATOR>::iterator currentEntry;
72 AbstractMapIterator(
const AbstractMapIterator&);
73 AbstractMapIterator& operator= (
const AbstractMapIterator&);
78 expectedModCount(parent->modCount),
79 futureEntry(parent->valueMap.begin()),
80 currentEntry(parent->valueMap.end()),
81 associatedMap(parent) {
84 virtual ~AbstractMapIterator() {}
86 virtual bool checkHasNext()
const {
87 synchronized(&this->associatedMap->mutex) {
88 if (futureEntry != this->associatedMap->valueMap.end()) {
95 void checkConcurrentMod()
const {
96 if (expectedModCount != this->associatedMap->modCount) {
98 __FILE__, __LINE__,
"StlMap modified outside this iterator");
103 synchronized(&this->associatedMap->mutex) {
104 checkConcurrentMod();
106 if (!checkHasNext()) {
110 currentEntry = futureEntry;
115 virtual void doRemove() {
116 synchronized(&this->associatedMap->mutex) {
117 checkConcurrentMod();
119 if (currentEntry == this->associatedMap->valueMap.end()) {
121 __FILE__, __LINE__,
"Remove called before call to next()");
124 this->associatedMap->valueMap.erase(currentEntry);
125 currentEntry = this->associatedMap->valueMap.end();
128 associatedMap->modCount++;
133 class EntryIterator :
public Iterator< MapEntry<K,V> >,
public AbstractMapIterator {
136 EntryIterator(
const EntryIterator&);
137 EntryIterator& operator= (
const EntryIterator&);
144 virtual ~EntryIterator() {}
146 virtual bool hasNext()
const {
147 return this->checkHasNext();
151 synchronized(&this->associatedMap->mutex) {
153 return MapEntry<K, V>(this->currentEntry->first, this->currentEntry->second);
159 virtual void remove() {
164 class KeyIterator :
public Iterator<K>,
public AbstractMapIterator {
167 KeyIterator(
const KeyIterator&);
168 KeyIterator& operator= (
const KeyIterator&);
175 virtual ~KeyIterator() {}
177 virtual bool hasNext()
const {
178 return this->checkHasNext();
182 synchronized(&this->associatedMap->mutex) {
184 return this->currentEntry->first;
190 virtual void remove() {
195 class ValueIterator :
public Iterator<V>,
public AbstractMapIterator {
198 ValueIterator(
const ValueIterator&);
199 ValueIterator& operator= (
const ValueIterator&);
206 virtual ~ValueIterator() {}
208 virtual bool hasNext()
const {
209 return this->checkHasNext();
213 synchronized(&this->associatedMap->mutex) {
215 return this->currentEntry->second;
221 virtual void remove() {
228 class ConstAbstractMapIterator {
231 mutable int position;
232 int expectedModCount;
233 typename std::map<K,V,COMPARATOR>::const_iterator futureEntry;
234 typename std::map<K,V,COMPARATOR>::const_iterator currentEntry;
240 ConstAbstractMapIterator(
const ConstAbstractMapIterator&);
241 ConstAbstractMapIterator& operator= (
const ConstAbstractMapIterator&);
246 expectedModCount(parent->modCount),
247 futureEntry(parent->valueMap.begin()),
248 currentEntry(parent->valueMap.end()),
249 associatedMap(parent) {
252 virtual ~ConstAbstractMapIterator() {}
254 virtual bool checkHasNext()
const {
255 synchronized(&this->associatedMap->mutex) {
256 if (futureEntry != this->associatedMap->valueMap.end()) {
263 void checkConcurrentMod()
const {
264 synchronized(&this->associatedMap->mutex) {
265 if (expectedModCount != this->associatedMap->modCount) {
267 __FILE__, __LINE__,
"StlMap modified outside this iterator");
273 synchronized(&this->associatedMap->mutex) {
274 checkConcurrentMod();
276 if (!checkHasNext()) {
280 currentEntry = futureEntry;
286 class ConstEntryIterator :
public Iterator< MapEntry<K,V> >,
public ConstAbstractMapIterator {
289 ConstEntryIterator(
const ConstEntryIterator&);
290 ConstEntryIterator& operator= (
const ConstEntryIterator&);
294 ConstEntryIterator(
const ConcurrentStlMap* parent) : ConstAbstractMapIterator(parent) {
297 virtual ~ConstEntryIterator() {}
299 virtual bool hasNext()
const {
300 return this->checkHasNext();
304 synchronized(&this->associatedMap->mutex) {
306 return MapEntry<K, V>(this->currentEntry->first, this->currentEntry->second);
312 virtual void remove() {
314 __FILE__, __LINE__,
"Cannot write to a const Iterator." );
318 class ConstKeyIterator :
public Iterator<K>,
public ConstAbstractMapIterator {
321 ConstKeyIterator(
const ConstKeyIterator&);
322 ConstKeyIterator& operator= (
const ConstKeyIterator&);
326 ConstKeyIterator(
const ConcurrentStlMap* parent) : ConstAbstractMapIterator(parent) {
329 virtual ~ConstKeyIterator() {}
331 virtual bool hasNext()
const {
332 return this->checkHasNext();
336 synchronized(&this->associatedMap->mutex) {
338 return this->currentEntry->first;
344 virtual void remove() {
346 __FILE__, __LINE__,
"Cannot write to a const Iterator." );
350 class ConstValueIterator :
public Iterator<V>,
public ConstAbstractMapIterator {
353 ConstValueIterator(
const ConstValueIterator&);
354 ConstValueIterator& operator= (
const ConstValueIterator&);
358 ConstValueIterator(
const ConcurrentStlMap* parent) : ConstAbstractMapIterator(parent) {
361 virtual ~ConstValueIterator() {}
363 virtual bool hasNext()
const {
364 return this->checkHasNext();
368 synchronized(&this->associatedMap->mutex) {
370 return this->currentEntry->second;
376 virtual void remove() {
378 __FILE__, __LINE__,
"Cannot write to a const Iterator." );
385 class StlMapEntrySet :
public AbstractSet< MapEntry<K, V> > {
392 StlMapEntrySet(
const StlMapEntrySet&);
393 StlMapEntrySet& operator= (
const StlMapEntrySet&);
400 virtual ~StlMapEntrySet() {}
402 virtual int size()
const {
403 return associatedMap->size();
406 virtual void clear() {
407 associatedMap->clear();
411 synchronized(&this->associatedMap->mutex) {
412 if (this->associatedMap->containsKey(entry.getKey()) &&
413 this->associatedMap->get(entry.getKey()) == entry.getValue()) {
414 associatedMap->remove(entry.getKey());
423 synchronized(&this->associatedMap->mutex) {
424 if (this->associatedMap->containsKey(entry.
getKey()) &&
433 return new EntryIterator(associatedMap);
437 return new ConstEntryIterator(associatedMap);
442 class ConstStlMapEntrySet :
public AbstractSet< MapEntry<K, V> > {
449 ConstStlMapEntrySet(
const ConstStlMapEntrySet&);
450 ConstStlMapEntrySet& operator= (
const ConstStlMapEntrySet&);
457 virtual ~ConstStlMapEntrySet() {}
459 virtual int size()
const {
460 return associatedMap->size();
463 virtual void clear() {
465 __FILE__, __LINE__,
"Can't clear a const collection");
470 __FILE__, __LINE__,
"Can't remove from const collection");
474 synchronized(&this->associatedMap->mutex) {
475 if (this->associatedMap->containsKey(entry.
getKey()) &&
485 __FILE__, __LINE__,
"Can't return a non-const iterator for a const collection");
489 return new ConstEntryIterator(associatedMap);
502 StlMapKeySet(
const StlMapKeySet&);
503 StlMapKeySet& operator= (
const StlMapKeySet&);
510 virtual ~StlMapKeySet() {}
512 virtual bool contains(
const K& key)
const {
513 return this->associatedMap->containsKey(key);
516 virtual int size()
const {
517 return this->associatedMap->size();
520 virtual void clear() {
521 this->associatedMap->clear();
524 virtual bool remove(
const K& key) {
525 synchronized(&this->associatedMap->mutex) {
526 if (this->associatedMap->containsKey(key)) {
527 associatedMap->remove(key);
535 return new KeyIterator(this->associatedMap);
539 return new ConstKeyIterator(this->associatedMap);
550 ConstStlMapKeySet(
const ConstStlMapKeySet&);
551 ConstStlMapKeySet& operator= (
const ConstStlMapKeySet&);
558 virtual ~ConstStlMapKeySet() {}
560 virtual bool contains(
const K& key)
const {
561 return this->associatedMap->containsKey(key);
564 virtual int size()
const {
565 return this->associatedMap->size();
568 virtual void clear() {
570 __FILE__, __LINE__,
"Can't modify a const collection");
575 __FILE__, __LINE__,
"Can't modify a const collection");
580 __FILE__, __LINE__,
"Can't return a non-const iterator for a const collection");
584 return new ConstKeyIterator(this->associatedMap);
597 StlMapValueCollection(
const StlMapValueCollection&);
598 StlMapValueCollection& operator= (
const StlMapValueCollection&);
605 virtual ~StlMapValueCollection() {}
607 virtual bool contains(
const V& value)
const {
608 return this->associatedMap->containsValue(value);
611 virtual int size()
const {
612 return this->associatedMap->size();
615 virtual void clear() {
616 this->associatedMap->clear();
620 return new ValueIterator(this->associatedMap);
624 return new ConstValueIterator(this->associatedMap);
635 ConstStlMapValueCollection(
const ConstStlMapValueCollection&);
636 ConstStlMapValueCollection& operator= (
const ConstStlMapValueCollection&);
643 virtual ~ConstStlMapValueCollection() {}
645 virtual bool contains(
const V& value)
const {
646 return this->associatedMap->containsValue(value);
649 virtual int size()
const {
650 return this->associatedMap->size();
653 virtual void clear() {
655 __FILE__, __LINE__,
"Can't modify a const collection");
660 __FILE__, __LINE__,
"Can't return a non-const iterator for a const collection");
664 return new ConstValueIterator(this->associatedMap);
686 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
687 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
697 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
698 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
708 cachedEntrySet(), cachedKeySet(), cachedValueCollection(),
709 cachedConstEntrySet(), cachedConstKeySet(), cachedConstValueCollection() {
719 synchronized(&mutex) {
720 return this->valueMap == source.valueMap;
727 synchronized(&mutex) {
728 typename std::auto_ptr< Iterator<K> > iterator(this->
keySet().iterator());
729 while (iterator->hasNext()) {
730 K key = iterator->next();
735 if (!(this->
get(key) == source.
get(key))) {
748 synchronized(&mutex) {
749 this->valueMap.clear();
750 this->valueMap.insert(source.valueMap.begin(), source.valueMap.end());
755 synchronized( &mutex ) {
765 synchronized(&mutex) {
774 typename std::map<K, V, COMPARATOR>::const_iterator iter;
776 synchronized(&mutex) {
777 iter = valueMap.find(key);
778 return iter != valueMap.end();
788 synchronized(&mutex) {
789 if (valueMap.empty()) {
793 typename std::map<K, V, COMPARATOR>::const_iterator iter = valueMap.begin();
794 for (; iter != valueMap.end(); ++iter) {
795 if ((*iter).second == value) {
808 synchronized(&mutex) {
809 return valueMap.empty();
819 synchronized(&mutex) {
820 return (
int)valueMap.size();
829 virtual V&
get(
const K& key) {
830 typename std::map<K,V,COMPARATOR>::iterator iter;
831 synchronized(&mutex) {
832 iter = valueMap.find(key);
833 if (iter != valueMap.end()) {
839 __FILE__, __LINE__,
"Key does not exist in map");
845 virtual const V&
get(
const K& key)
const {
846 typename std::map<K,V,COMPARATOR>::const_iterator iter;
847 synchronized(&mutex) {
848 iter = valueMap.find(key);
849 if (iter != valueMap.end()) {
855 __FILE__, __LINE__,
"Key does not exist in map");
861 virtual bool put(
const K& key,
const V& value) {
863 synchronized(&mutex) {
868 valueMap[key] = value;
876 virtual bool put(
const K& key,
const V& value, V& oldValue) {
878 synchronized(&mutex) {
881 oldValue = valueMap[key];
884 valueMap[key] = value;
893 synchronized(&mutex) {
894 this->valueMap.insert(other.valueMap.begin(), other.valueMap.end());
903 synchronized(&mutex) {
904 typename std::auto_ptr< Iterator<K> > iterator(other.
keySet().iterator());
905 while (iterator->hasNext()) {
906 K key = iterator->next();
907 this->
put(key, other.
get(key));
916 virtual V
remove(
const K& key) {
918 synchronized(&mutex) {
919 typename std::map<K, V, COMPARATOR>::iterator iter = valueMap.find(key);
920 if (iter == valueMap.end()) {
923 result = iter->second;
924 valueMap.erase(iter);
955 synchronized(&mutex) {
957 this->
put(key, value);
983 bool remove(
const K& key,
const V& value) {
984 synchronized(&mutex) {
985 if( this->
containsKey( key ) && ( this->
get( key ) == value ) ) {
1013 bool replace(
const K& key,
const V& oldValue,
const V& newValue) {
1014 synchronized(&mutex) {
1015 if (this->
containsKey(key) && (this->
get(key) == oldValue)) {
1016 this->
put(key, newValue);
1045 synchronized(&mutex) {
1047 V result = this->
get(key);
1048 this->
put(key, value);
1054 __FILE__, __LINE__,
"Value to Replace was not in the Map." );
1058 synchronized(&mutex) {
1059 if (this->cachedEntrySet ==
NULL) {
1060 this->cachedEntrySet.
reset(
new StlMapEntrySet(
this));
1063 return *(this->cachedEntrySet);
1066 synchronized(&mutex) {
1067 if (this->cachedConstEntrySet ==
NULL) {
1068 this->cachedConstEntrySet.
reset(
new ConstStlMapEntrySet(
this));
1071 return *(this->cachedConstEntrySet);
1075 synchronized(&mutex) {
1076 if (this->cachedKeySet ==
NULL) {
1077 this->cachedKeySet.
reset(
new StlMapKeySet(
this));
1080 return *(this->cachedKeySet);
1084 synchronized(&mutex) {
1085 if (this->cachedConstKeySet ==
NULL) {
1086 this->cachedConstKeySet.
reset(
new ConstStlMapKeySet(
this));
1089 return *(this->cachedConstKeySet);
1093 synchronized(&mutex) {
1094 if (this->cachedValueCollection ==
NULL) {
1095 this->cachedValueCollection.
reset(
new StlMapValueCollection(
this));
1098 return *(this->cachedValueCollection);
1102 synchronized(&mutex) {
1103 if (this->cachedConstValueCollection ==
NULL) {
1104 this->cachedConstValueCollection.
reset(
new ConstStlMapValueCollection(
this));
1107 return *(this->cachedConstValueCollection);
1128 virtual void wait(
long long millisecs ) {
1129 mutex.
wait( millisecs );
1132 virtual void wait(
long long millisecs,
int nanos ) {
1133 mutex.
wait( millisecs, nanos );