You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2012/07/24 00:01:19 UTC

svn commit: r1364819 [1/2] - in /activemq/activemq-cpp/trunk/activemq-cpp/src: main/decaf/lang/ main/decaf/util/ main/decaf/util/concurrent/ test/ test/decaf/util/

Author: tabish
Date: Mon Jul 23 22:01:19 2012
New Revision: 1364819

URL: http://svn.apache.org/viewvc?rev=1364819&view=rev
Log:
A more complete HashMap implementation with Unit tests, and some API updates 

Modified:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/AbstractMap.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashCode.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashMap.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Map.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/MapEntry.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/StlMap.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/ConcurrentStlMap.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/StlMapTest.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/test/testRegistry.cpp

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/lang/ArrayPointer.h Mon Jul 23 22:01:19 2012
@@ -118,6 +118,7 @@ namespace lang {
             try {
                 T* value = new T[size];
                 this->array = new ArrayData(value, size);
+                decaf::util::Arrays::fill(value, size, 0, size, T());
             } catch (std::exception& ex) {
                 throw ex;
             } catch (...) {

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/AbstractMap.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/AbstractMap.h?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/AbstractMap.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/AbstractMap.h Mon Jul 23 22:01:19 2012
@@ -22,6 +22,8 @@
 #include <decaf/lang/exceptions/UnsupportedOperationException.h>
 #include <decaf/lang/exceptions/NullPointerException.h>
 #include <decaf/lang/exceptions/IllegalArgumentException.h>
+#include <decaf/util/concurrent/Synchronizable.h>
+#include <decaf/util/concurrent/Mutex.h>
 #include <decaf/util/Iterator.h>
 #include <decaf/util/Map.h>
 #include <decaf/util/Set.h>
@@ -55,10 +57,57 @@ namespace util {
      */
     template< typename K, typename V>
     class AbstractMap : public decaf::util::Map<K, V> {
+    protected:
+
+        mutable util::concurrent::Mutex mutex;
+
     public:
 
+        AbstractMap() : Map<K, V>(), mutex() {
+        }
+
+        AbstractMap(const Map<K, V>& map) : Map<K, V>(), mutex() {
+        }
+
+        AbstractMap(const AbstractMap<K, V>& map) : Map<K, V>(), mutex() {
+        }
+
         virtual ~AbstractMap() {}
 
+    public:
+
+        virtual void lock() {
+            mutex.lock();
+        }
+
+        virtual bool tryLock() {
+            return mutex.tryLock();
+        }
+
+        virtual void unlock() {
+            mutex.unlock();
+        }
+
+        virtual void wait()  {
+            mutex.wait();
+        }
+
+        virtual void wait( long long millisecs ) {
+            mutex.wait( millisecs );
+        }
+
+        virtual void wait( long long millisecs, int nanos ) {
+            mutex.wait( millisecs, nanos );
+        }
+
+        virtual void notify() {
+            mutex.notify();
+        }
+
+        virtual void notifyAll() {
+            mutex.notifyAll();
+        }
+
     };
 
 }}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashCode.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashCode.h?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashCode.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashCode.h Mon Jul 23 22:01:19 2012
@@ -39,103 +39,103 @@ namespace util {
     template<typename T>
     struct HashCode : public std::unary_function<T, int> {
     public:
-        int operator()(T arg);
+        int operator()(T arg) const;
     };
 
     template<typename T>
     struct HashCode<T*> : public std::unary_function<T*, int> {
-        int operator()(T* arg) {
+        int operator()(T* arg)  const {
             return reinterpret_cast<int>(arg);
         }
     };
 
     template<typename T>
     struct HashCode<const T&> : public std::unary_function<const T&, int> {
-        int operator()(const T& arg) {
+        int operator()(const T& arg) const {
             return HashCode<const T*>(&arg);
         }
     };
 
     template<>
     struct HashCode<bool> : public std::unary_function<bool, int> {
-        int operator()(bool arg) {
+        int operator()(bool arg) const {
             return arg ? 1231 : 1237;
         }
     };
 
     template<>
     struct HashCode<unsigned char> : public std::unary_function<unsigned char, int> {
-        int operator()(unsigned char arg) {
+        int operator()(unsigned char arg) const {
             return (int) arg;
         }
     };
 
     template<>
     struct HashCode<char> : public std::unary_function<char, int> {
-        int operator()(char arg) {
+        int operator()(char arg) const {
             return (int) arg;
         }
     };
 
     template<>
     struct HashCode<wchar_t> : public std::unary_function<wchar_t, int> {
-        int operator()(wchar_t arg) {
+        int operator()(wchar_t arg) const {
             return (int) arg;
         }
     };
 
     template<>
     struct HashCode<unsigned short> : public std::unary_function<unsigned short, int> {
-        int operator()(unsigned short arg) {
+        int operator()(unsigned short arg) const {
             return (int) arg;
         }
     };
 
     template<>
     struct HashCode<short> : public std::unary_function<short, int> {
-        int operator()(short arg) {
+        int operator()(short arg) const {
             return (int) arg;
         }
     };
 
     template<>
     struct HashCode<unsigned int> : public std::unary_function<unsigned int, int> {
-        int operator()(unsigned int arg) {
+        int operator()(unsigned int arg) const {
             return (int) arg;
         }
     };
 
     template<>
     struct HashCode<int> : public std::unary_function<int, int> {
-        int operator()(int arg) {
+        int operator()(int arg) const {
             return arg;
         }
     };
 
     template<>
     struct HashCode<unsigned long long> : public std::unary_function<unsigned long long, int> {
-        int operator()(unsigned long long arg) {
+        int operator()(unsigned long long arg) const {
             return (int) (arg ^ (arg >> 32));
         }
     };
 
     template<>
     struct HashCode<long long> : public std::unary_function<long long, int> {
-        int operator()(long long arg) {
+        int operator()(long long arg) const {
             return (int) (arg ^ ((unsigned long long) arg >> 32));
         }
     };
 
     template<>
     struct HashCode<float> : public std::unary_function<float, int> {
-        int operator()(float arg) {
+        int operator()(float arg) const {
             return decaf::lang::Float::floatToIntBits(arg);
         }
     };
 
     template<>
     struct HashCode<double> : public std::unary_function<double, int> {
-        int operator()(double arg) {
+        int operator()(double arg) const {
             long long value = decaf::lang::Double::doubleToLongBits(arg);
             return (int) (value ^ ((unsigned long long) value >> 32));
         }
@@ -143,7 +143,7 @@ namespace util {
 
     template<>
     struct HashCode<std::string> : public std::unary_function<const std::string&, int> {
-        int operator()(const std::string& arg) {
+        int operator()(const std::string& arg) const {
             int h = 0;
             if (h == 0 && arg.length() > 0) {
                 std::string::const_iterator iter = arg.begin();
@@ -157,7 +157,7 @@ namespace util {
 
     template<typename T>
     struct HashCode< decaf::lang::Pointer<T> > : public std::unary_function<decaf::lang::Pointer<T>, int> {
-        int operator()(decaf::lang::Pointer<T> arg) {
+        int operator()(decaf::lang::Pointer<T> arg) const {
             if (arg != NULL) {
                 return HashCode<T>()(*arg);
             }

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashMap.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashMap.h?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashMap.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/HashMap.h Mon Jul 23 22:01:19 2012
@@ -21,7 +21,11 @@
 #include <decaf/util/Config.h>
 
 #include <decaf/util/AbstractMap.h>
+#include <decaf/util/AbstractSet.h>
 #include <decaf/util/HashCode.h>
+#include <decaf/util/ConcurrentModificationException.h>
+#include <decaf/lang/exceptions/UnsupportedOperationException.h>
+#include <decaf/lang/Pointer.h>
 #include <decaf/lang/ArrayPointer.h>
 
 namespace decaf {
@@ -92,14 +96,20 @@ namespace util {
     private:
 
         class HashMapEntry : public MapEntry<K, V> {
+        private:
+
+            HashMapEntry(const HashMapEntry&);
+            HashMapEntry& operator= (const HashMapEntry&);
+
         public:
 
             int origKeyHash;
 
             HashMapEntry* next;
 
-            HashMapEntry(const K& key, int hash) : MapEntry<K, V>(), origKeyHash(hash), next(NULL) {
+            HashMapEntry(const K& key, const V& value, int hash) : MapEntry<K, V>(), origKeyHash(hash), next(NULL) {
                 this->setKey(key);
+                this->setValue(value);
                 this->origKeyHash = hash;
             }
 
@@ -111,6 +121,528 @@ namespace util {
 
     private:
 
+        class AbstractMapIterator {
+        protected:
+
+            mutable int position;
+            int expectedModCount;
+            HashMapEntry* futureEntry;
+            HashMapEntry* currentEntry;
+            HashMapEntry* prevEntry;
+
+            HashMap* associatedMap;
+
+        public:
+
+            AbstractMapIterator(HashMap* parent) : position(0),
+                                                   expectedModCount(parent->modCount),
+                                                   futureEntry(NULL),
+                                                   currentEntry(NULL),
+                                                   prevEntry(NULL),
+                                                   associatedMap(parent) {
+            }
+
+            virtual ~AbstractMapIterator() {}
+
+            virtual bool checkHasNext() const {
+                if (futureEntry != NULL) {
+                    return true;
+                }
+                while (position < associatedMap->elementData.length()) {
+                    if (associatedMap->elementData[position] == NULL) {
+                        position++;
+                    } else {
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            void checkConcurrentMod() const {
+                if (expectedModCount != associatedMap->modCount) {
+                    throw ConcurrentModificationException(
+                        __FILE__, __LINE__, "HashMap modified outside this iterator");
+                }
+            }
+
+            void makeNext() {
+                checkConcurrentMod();
+
+                if (!checkHasNext()) {
+                    throw NoSuchElementException(__FILE__, __LINE__, "No next element");
+                }
+
+                if (futureEntry == NULL) {
+                    currentEntry = associatedMap->elementData[position++];
+                    futureEntry = currentEntry->next;
+                    prevEntry = NULL;
+                } else {
+                    if (currentEntry != NULL){
+                        prevEntry = currentEntry;
+                    }
+                    currentEntry = futureEntry;
+                    futureEntry = futureEntry->next;
+                }
+            }
+
+            virtual void doRemove() {
+
+                checkConcurrentMod();
+
+                if (currentEntry == NULL) {
+                    throw decaf::lang::exceptions::IllegalStateException(
+                        __FILE__, __LINE__, "Remove called before call to next()");
+                }
+
+                if (prevEntry == NULL){
+                    int index = currentEntry->origKeyHash & (associatedMap->elementData.length() - 1);
+                    associatedMap->elementData[index] = associatedMap->elementData[index]->next;
+                } else {
+                    prevEntry->next = currentEntry->next;
+                }
+
+                currentEntry = NULL;
+                expectedModCount++;
+                associatedMap->modCount++;
+                associatedMap->elementCount--;
+            }
+        };
+
+        class EntryIterator : public Iterator< MapEntry<K,V> >, public AbstractMapIterator {
+        private:
+
+            EntryIterator(const EntryIterator&);
+            EntryIterator& operator= (const EntryIterator&);
+
+        public:
+
+            EntryIterator(HashMap* parent) : AbstractMapIterator(parent) {
+            }
+
+            virtual ~EntryIterator() {}
+
+            virtual bool hasNext() const {
+                return this->checkHasNext();
+            }
+
+            virtual MapEntry<K, V> next() {
+                this->makeNext();
+                return *(this->currentEntry);
+            }
+
+            virtual void remove() {
+                this->doRemove();
+            }
+        };
+
+        class KeyIterator : public Iterator<K>, public AbstractMapIterator {
+        private:
+
+            KeyIterator(const KeyIterator&);
+            KeyIterator& operator= (const KeyIterator&);
+
+        public:
+
+            KeyIterator(HashMap* parent) : AbstractMapIterator(parent) {
+            }
+
+            virtual ~KeyIterator() {}
+
+            virtual bool hasNext() const {
+                return this->checkHasNext();
+            }
+
+            virtual K next() {
+                this->makeNext();
+                return this->currentEntry->getKey();
+            }
+
+            virtual void remove() {
+                this->doRemove();
+            }
+        };
+
+        class ValueIterator : public Iterator<V>, public AbstractMapIterator {
+        private:
+
+            ValueIterator(const ValueIterator&);
+            ValueIterator& operator= (const ValueIterator&);
+
+        public:
+
+            ValueIterator(HashMap* parent) : AbstractMapIterator(parent) {
+            }
+
+            virtual ~ValueIterator() {}
+
+            virtual bool hasNext() const {
+                return this->checkHasNext();
+            }
+
+            virtual V next() {
+                this->makeNext();
+                return this->currentEntry->getValue();
+            }
+
+            virtual void remove() {
+                this->doRemove();
+            }
+        };
+
+        private:
+
+            class ConstAbstractMapIterator {
+            protected:
+
+                mutable int position;
+                int expectedModCount;
+                const HashMapEntry* futureEntry;
+                const HashMapEntry* currentEntry;
+                const HashMapEntry* prevEntry;
+
+                const HashMap* associatedMap;
+
+            public:
+
+                ConstAbstractMapIterator(const HashMap* parent) : position(0),
+                                                                  expectedModCount(parent->modCount),
+                                                                  futureEntry(NULL),
+                                                                  currentEntry(NULL),
+                                                                  prevEntry(NULL),
+                                                                  associatedMap(parent) {
+                }
+
+                virtual ~ConstAbstractMapIterator() {}
+
+                virtual bool checkHasNext() const {
+                    if (futureEntry != NULL) {
+                        return true;
+                    }
+                    while (position < associatedMap->elementData.length()) {
+                        if (associatedMap->elementData[position] == NULL) {
+                            position++;
+                        } else {
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+
+                void checkConcurrentMod() const {
+                    if (expectedModCount != associatedMap->modCount) {
+                        throw ConcurrentModificationException(
+                            __FILE__, __LINE__, "HashMap modified outside this iterator");
+                    }
+                }
+
+                void makeNext() {
+                    checkConcurrentMod();
+
+                    if (!checkHasNext()) {
+                        throw NoSuchElementException(__FILE__, __LINE__, "No next element");
+                    }
+
+                    if (futureEntry == NULL) {
+                        currentEntry = associatedMap->elementData[position++];
+                        futureEntry = currentEntry->next;
+                        prevEntry = NULL;
+                    } else {
+                        if (currentEntry != NULL){
+                            prevEntry = currentEntry;
+                        }
+                        currentEntry = futureEntry;
+                        futureEntry = futureEntry->next;
+                    }
+                }
+            };
+
+            class ConstEntryIterator : public Iterator< MapEntry<K,V> >, public ConstAbstractMapIterator {
+            private:
+
+                ConstEntryIterator(const ConstEntryIterator&);
+                ConstEntryIterator& operator= (const ConstEntryIterator&);
+
+            public:
+
+                ConstEntryIterator(const HashMap* parent) : ConstAbstractMapIterator(parent) {
+                }
+
+                virtual ~ConstEntryIterator() {}
+
+                virtual bool hasNext() const {
+                    return this->checkHasNext();
+                }
+
+                virtual MapEntry<K, V> next() {
+                    this->makeNext();
+                    return *(this->currentEntry);
+                }
+
+                virtual void remove() {
+                    throw lang::exceptions::UnsupportedOperationException(
+                        __FILE__, __LINE__, "Cannot write to a const Iterator." );
+                }
+            };
+
+            class ConstKeyIterator : public Iterator<K>, public ConstAbstractMapIterator {
+            private:
+
+                ConstKeyIterator(const ConstKeyIterator&);
+                ConstKeyIterator& operator= (const ConstKeyIterator&);
+
+            public:
+
+                ConstKeyIterator(const HashMap* parent) : ConstAbstractMapIterator(parent) {
+                }
+
+                virtual ~ConstKeyIterator() {}
+
+                virtual bool hasNext() const {
+                    return this->checkHasNext();
+                }
+
+                virtual K next() {
+                    this->makeNext();
+                    return this->currentEntry->getKey();
+                }
+
+                virtual void remove() {
+                    throw lang::exceptions::UnsupportedOperationException(
+                        __FILE__, __LINE__, "Cannot write to a const Iterator." );
+                }
+            };
+
+            class ConstValueIterator : public Iterator<V>, public ConstAbstractMapIterator {
+            private:
+
+                ConstValueIterator(const ConstValueIterator&);
+                ConstValueIterator& operator= (const ConstValueIterator&);
+
+            public:
+
+                ConstValueIterator(const HashMap* parent) : ConstAbstractMapIterator(parent) {
+                }
+
+                virtual ~ConstValueIterator() {}
+
+                virtual bool hasNext() const {
+                    return this->checkHasNext();
+                }
+
+                virtual V next() {
+                    this->makeNext();
+                    return this->currentEntry->getValue();
+                }
+
+                virtual void remove() {
+                    throw lang::exceptions::UnsupportedOperationException(
+                        __FILE__, __LINE__, "Cannot write to a const Iterator." );
+                }
+            };
+
+    private:
+
+        // Special Set implementation that is backed by this HashMap
+        class HashMapEntrySet : public AbstractSet< MapEntry<K, V> > {
+        private:
+
+            HashMap* associatedMap;
+
+        private:
+
+            HashMapEntrySet(const HashMapEntrySet&);
+            HashMapEntrySet& operator= (const HashMapEntrySet&);
+
+        public:
+
+            HashMapEntrySet(HashMap* parent) : AbstractSet< MapEntry<K,V> >(), associatedMap(parent) {
+            }
+
+            virtual ~HashMapEntrySet() {}
+
+            HashMap* hashMap() {
+                return this->associatedMap;
+            }
+
+            virtual int size() const {
+                return associatedMap->elementCount;
+            }
+
+            virtual void clear() {
+                associatedMap->clear();
+            }
+
+            virtual bool remove(const MapEntry<K,V>& entry) {
+                HashMapEntry* result = associatedMap->getEntry(entry.getKey());
+                if (result != NULL && entry.getValue() == result->getValue()) {
+                    associatedMap->removeEntry(result);
+                    return true;
+                }
+
+                return false;
+            }
+
+            virtual bool contains(const MapEntry<K,V>& entry) {
+                HashMapEntry* result = associatedMap->getEntry(entry.getKey());
+                if (result != NULL && entry.getValue() == result->getValue()) {
+                    return true;
+                }
+                return false;
+            }
+
+            virtual Iterator< MapEntry<K, V> >* iterator() {
+                return new EntryIterator(associatedMap);
+            }
+
+            virtual Iterator< MapEntry<K, V> >* iterator() const {
+                return new ConstEntryIterator(associatedMap);
+            }
+        };
+
+        // Special Set implementation that is backed by this HashMap
+        class ConstHashMapEntrySet : public AbstractSet< MapEntry<K, V> > {
+        private:
+
+            const HashMap* associatedMap;
+
+        private:
+
+            ConstHashMapEntrySet(const ConstHashMapEntrySet&);
+            ConstHashMapEntrySet& operator= (const ConstHashMapEntrySet&);
+
+        public:
+
+            ConstHashMapEntrySet(const HashMap* parent) : AbstractSet< MapEntry<K,V> >(), associatedMap(parent) {
+            }
+
+            virtual ~ConstHashMapEntrySet() {}
+
+            HashMap* hashMap() {
+                return this->associatedMap;
+            }
+
+            virtual int size() const {
+                return associatedMap->elementCount;
+            }
+
+            virtual void clear() {
+                throw decaf::lang::exceptions::UnsupportedOperationException(
+                        __FILE__, __LINE__, "Can't clear a const collection");
+            }
+
+            virtual bool remove(const MapEntry<K,V>& entry) {
+                throw decaf::lang::exceptions::UnsupportedOperationException(
+                        __FILE__, __LINE__, "Can't remove from const collection");
+            }
+
+            virtual bool contains(const MapEntry<K,V>& entry) {
+                HashMapEntry* result = associatedMap->getEntry(entry.getKey());
+                if (result != NULL && entry.getValue() == result->getValue()) {
+                    return true;
+                }
+                return false;
+            }
+
+            virtual Iterator< MapEntry<K, V> >* iterator() {
+                return new ConstEntryIterator(associatedMap);
+            }
+
+            virtual Iterator< MapEntry<K, V> >* iterator() const {
+                return new ConstEntryIterator(associatedMap);
+            }
+        };
+
+    private:
+
+        class HashMapKeySet : public AbstractSet<K> {
+        private:
+
+            HashMap* associatedMap;
+
+        private:
+
+            HashMapKeySet(const HashMapKeySet&);
+            HashMapKeySet& operator= (const HashMapKeySet&);
+
+        public:
+
+            HashMapKeySet(HashMap* parent) : AbstractSet<K>(), associatedMap(parent) {
+            }
+
+            virtual ~HashMapKeySet() {}
+
+            virtual bool contains(const K& key) const {
+                return this->associatedMap->containsKey(key);
+            }
+
+            virtual int size() const {
+                return this->associatedMap->size();
+            }
+
+            virtual void clear() {
+                this->associatedMap->clear();
+            }
+
+            virtual bool remove(const K& key) {
+                HashMapEntry* entry = this->associatedMap->removeEntry(key);
+                if (entry != NULL) {
+                    delete entry;
+                    return true;
+                }
+                return false;
+            }
+
+            virtual Iterator<K>* iterator() {
+                return new KeyIterator(this->associatedMap);
+            }
+
+            virtual Iterator<K>* iterator() const {
+                return new ConstKeyIterator(this->associatedMap);
+            }
+        };
+
+        private:
+
+            class HashMapValueCollection : public AbstractCollection<V> {
+            private:
+
+                HashMap* associatedMap;
+
+            private:
+
+                HashMapValueCollection(const HashMapValueCollection&);
+                HashMapValueCollection& operator= (const HashMapValueCollection&);
+
+            public:
+
+                HashMapValueCollection(HashMap* parent) : AbstractCollection<V>(), associatedMap(parent) {
+                }
+
+                virtual ~HashMapValueCollection() {}
+
+                virtual bool contains(const V& value) const {
+                    return this->associatedMap->containsValue(value);
+                }
+
+                virtual int size() const {
+                    return this->associatedMap->size();
+                }
+
+                virtual void clear() {
+                    this->associatedMap->clear();
+                }
+
+                virtual Iterator<V>* iterator() {
+                    return new ValueIterator(this->associatedMap);
+                }
+
+                virtual Iterator<V>* iterator() const {
+                    return new ConstValueIterator(this->associatedMap);
+                }
+            };
+
+    private:
+
         /**
          * The Hash Code generator for this map's keys.
          */
@@ -145,7 +677,7 @@ namespace util {
     private:
 
         void computeThreshold() {
-            threshold = (int) (elementData.length() * loadFactor);
+            threshold = (int) ((float) elementData.length() * loadFactor);
         }
 
         static int calculateCapacity(int x) {
@@ -156,7 +688,7 @@ namespace util {
             if (x == 0) {
                 return 16;
             }
-            x = x -1;
+            x = x - 1;
             x |= x >> 1;
             x |= x >> 2;
             x |= x >> 4;
@@ -173,7 +705,7 @@ namespace util {
         HashMap() : AbstractMap<K,V>(), hashFunc(), elementCount(0), elementData(), modCount(0), loadFactor(0.75), threshold(0) {
             int capacity = calculateCapacity(12);
             elementCount = 0;
-            elementData.reset(NULL, capacity);
+            elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
             computeThreshold();
         }
 
@@ -189,7 +721,7 @@ namespace util {
             if (capacity >= 0) {
                 capacity = calculateCapacity(capacity);
                 elementCount = 0;
-                elementData.reset(NULL, capacity);
+                elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
                 computeThreshold();
             } else {
                 throw decaf::lang::exceptions::IllegalArgumentException(
@@ -211,7 +743,7 @@ namespace util {
             if (capacity >= 0 && loadFactor > 0) {
                 capacity = calculateCapacity(capacity);
                 elementCount = 0;
-                elementData.reset(NULL, capacity);
+                elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
                 this->loadFactor = loadFactor;
                 computeThreshold();
             } else {
@@ -225,17 +757,41 @@ namespace util {
          * of the given source Map instance.
          *
          * @param map
+         *      The Map instance whose elements are copied into this HashMap instance.
+         */
+        HashMap(const HashMap<K,V>& map) : AbstractMap<K,V>(), hashFunc(), elementCount(0), elementData(), modCount(0), loadFactor(0.75), threshold(0) {
+            int capacity = calculateCapacity(map.size());
+            elementCount = 0;
+            elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
+            computeThreshold();
+            putAll(map);
+        }
+
+        /**
+         * Creates a new HashMap with default configuration settings and fills it with the contents
+         * of the given source Map instance.
+         *
+         * @param map
          * 		The Map instance whose elements are copied into this HashMap instance.
          */
         HashMap(const Map<K,V>& map) : AbstractMap<K,V>(), hashFunc(), elementCount(0), elementData(), modCount(0), loadFactor(0.75), threshold(0) {
             int capacity = calculateCapacity(map.size());
             elementCount = 0;
-            elementData.reset(NULL, capacity);
+            elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
             computeThreshold();
             putAll(map);
         }
 
-        virtual ~HashMap() {}
+        virtual ~HashMap() {
+            for (int i = 0; i < elementData.length(); i++) {
+                HashMapEntry* entry = elementData[i];
+                while (entry != NULL) {
+                    HashMapEntry* temp = entry;
+                    entry = entry->next;
+                    delete temp;
+                }
+            }
+        }
 
     public:
 
@@ -243,8 +799,13 @@ namespace util {
             if (elementCount > 0) {
                 elementCount = 0;
                 for (int i = 0; i < elementData.length(); ++i) {
-                    delete elementData[i];
+                    HashMapEntry* entry = elementData[i];
                     elementData[i] = NULL;
+                    while (entry != NULL) {
+                        HashMapEntry* temp = entry;
+                        entry = entry->next;
+                        delete temp;
+                    }
                 }
                 modCount++;
             }
@@ -258,9 +819,14 @@ namespace util {
             return elementCount;
         }
 
+        virtual bool containsKey(const K& key) const {
+            const HashMapEntry* entry = getEntry(key);
+            return entry != NULL;
+        }
+
         virtual bool containsValue(const V& value) const {
             for (int i = 0; i < elementData.length(); i++) {
-                HashMapEntry* entry = elementData[i];
+                const HashMapEntry* entry = elementData[i];
                 while (entry != NULL) {
                     if (value == entry->getValue()) {
                         return true;
@@ -271,8 +837,144 @@ namespace util {
             return false;
         }
 
+        virtual V& get(const K& key) {
+            HashMapEntry* entry = getEntry(key);
+            if (entry != NULL) {
+                return entry->getValue();
+            }
+
+            throw NoSuchElementException(
+                    __FILE__, __LINE__, "The specified key is not present in the Map");
+        }
+
+        virtual const V& get(const K& key) const {
+            const HashMapEntry* entry = getEntry(key);
+            if (entry != NULL) {
+                return entry->getValue();
+            }
+
+            throw NoSuchElementException(
+                    __FILE__, __LINE__, "The specified key is not present in the Map");
+        }
+
+        virtual void put(const K& key, const V& value) {
+            this->putImpl(key, value);
+        }
+
+        virtual void putAll(const Map<K, V>& map) {
+            if (!map.isEmpty()) {
+                putAllImpl(map);
+            }
+        }
+
+        virtual V remove(const K& key) {
+            HashMapEntry* entry = removeEntry(key);
+            if (entry != NULL) {
+                V oldValue = entry->getValue();
+                delete entry;
+                return oldValue;
+            }
+
+            throw NoSuchElementException(
+                __FILE__, __LINE__, "Specified key not present in the Map.");
+        }
+
+        virtual Set< MapEntry<K,V> >* entrySet() {
+            return new HashMapEntrySet(this);
+        }
+
+        virtual Set< MapEntry<K,V> >* entrySet() const {
+            return new ConstHashMapEntrySet(this);
+        }
+
+        virtual std::vector<K> keySet() const {
+            return std::vector<K>();
+        }
+
+        virtual Set<K>* keySet() {
+            return new HashMapKeySet(this);
+        }
+
+        virtual Collection<V>* values() {
+            return new HashMapValueCollection(this);
+        }
+
+        virtual std::vector<V> values() const {
+            return std::vector<V>();
+        }
+
+        virtual bool equals(const Map<K, V>& source) const {
+            return false;
+        }
+
+        virtual void copy(const Map<K, V>& source) {
+            int capacity = calculateCapacity(source.size());
+            this->clear();
+            if (capacity > elementData.length()) {
+                elementData = decaf::lang::ArrayPointer<HashMapEntry*>(capacity);
+            }
+            computeThreshold();
+            putAll(source);
+        }
+
+        virtual std::string toString() const {
+            return "HashMap";
+        }
+
     protected:
 
+        HashMapEntry* getEntry(const K& key) const {
+            HashMapEntry* result = NULL;
+
+            int hash = hashFunc(key);
+            int index = hash & (elementData.length() - 1);
+            result = findKeyEntry(key, index, hash);
+
+            return result;
+        }
+
+        void putImpl(const K& key, const V& value) {
+
+            HashMapEntry* entry = NULL;
+
+            int hash = hashFunc(key);
+            int index = hash & (elementData.length() - 1);
+
+            entry = findKeyEntry(key, index, hash);
+
+            if (entry == NULL) {
+                modCount++;
+                entry = createHashedEntry(key, index, hash);
+                if (++elementCount > threshold) {
+                    rehash();
+                }
+            }
+
+            entry->setValue(value);
+        }
+
+        void putAllImpl(const Map<K, V>& map) {
+            int capacity = elementCount + map.size();
+            if (capacity > threshold) {
+                rehash(capacity);
+            }
+
+            decaf::lang::Pointer<Set< MapEntry<K,V> > > entries(map.entrySet());
+            decaf::lang::Pointer<Iterator< MapEntry<K,V> > > iterator(entries->iterator());
+            while (iterator->hasNext()) {
+                MapEntry<K, V> entry = iterator->next();
+                this->putImpl(entry.getKey(), entry.getValue());
+            }
+        }
+
+        HashMapEntry* findKeyEntry(const K& key, int index, int keyHash) const {
+            HashMapEntry* entry = elementData[index];
+            while (entry != NULL && (entry->origKeyHash != keyHash || !(key == entry->getKey()))) {
+                entry = entry->next;
+            }
+            return entry;
+        }
+
         void rehash(int capacity) {
             int length = calculateCapacity((capacity == 0 ? 1 : capacity << 1));
 
@@ -296,6 +998,67 @@ namespace util {
             rehash(elementData.length());
         }
 
+        HashMapEntry* createEntry(const K& key, int index, const V& value) {
+            HashMapEntry* entry = new HashMapEntry(key, value);
+            entry->next = elementData[index];
+            elementData[index] = entry;
+            return entry;
+        }
+
+        HashMapEntry* createHashedEntry(const K& key, int index, int hash) {
+            HashMapEntry* entry = new HashMapEntry(key, V(), hash);
+            entry->next = elementData[index];
+            elementData[index] = entry;
+            return entry;
+        }
+
+        // Removes the given entry from the map and deletes it
+        void removeEntry(HashMapEntry* entry) {
+            int index = entry->origKeyHash & (elementData.length() - 1);
+            HashMapEntry* current = elementData[index];
+            if (current == entry) {
+                elementData[index] = entry->next;
+            } else {
+                while (current->next != entry) {
+                    current = current->next;
+                }
+                current->next = entry->next;
+            }
+            delete entry;
+            modCount++;
+            elementCount--;
+        }
+
+        // Removes but doesn't delete the entry in the map with the given key.
+        HashMapEntry* removeEntry(const K& key) {
+
+            int index = 0;
+            HashMapEntry* current = NULL;
+            HashMapEntry* last = NULL;
+
+            int hash = hashFunc(key);
+            index = hash & (elementData.length() - 1);
+            current = elementData[index];
+            while (current != NULL && !(current->origKeyHash == hash && key == current->getKey())) {
+                last = current;
+                current = current->next;
+            }
+
+            if (current == NULL) {
+                return NULL;
+            }
+
+            if (last == NULL) {
+                elementData[index] = current->next;
+            } else {
+                last->next = current->next;
+            }
+
+            modCount++;
+            elementCount--;
+            return current;
+        }
+
     };
 
 }}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Map.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Map.h?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Map.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Map.h Mon Jul 23 22:01:19 2012
@@ -131,7 +131,7 @@ namespace util{
          * @param value The Value to look up.
          * @return true if this map contains the value, otherwise false.
          */
-        virtual bool containsValue( const V& value ) const = 0;
+        virtual bool containsValue(const V& value) const = 0;
 
         /**
          * @return if the Map contains any element or not, TRUE or FALSE
@@ -213,6 +213,7 @@ namespace util{
          *          pointer is owned by the caller.
          */
         virtual Set< MapEntry<K,V> >* entrySet() = 0;
+        virtual Set< MapEntry<K,V> >* entrySet() const = 0;
 
         /**
          * @return the entire set of keys in this map as a std::vector.

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/MapEntry.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/MapEntry.h?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/MapEntry.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/MapEntry.h Mon Jul 23 22:01:19 2012
@@ -32,23 +32,32 @@ namespace util {
 
     public:
 
-        MapEntry();
+        MapEntry() : key(), value() {
+        }
 
-        virtual ~MapEntry();
+        virtual ~MapEntry() {};
 
         virtual void setKey(K key) {
             this->key = key;
         }
 
-        virtual K getKey() const {
+        virtual K& getKey() {
+            return this->key;
+        }
+
+        virtual const K& getKey() const {
             return this->key;
         }
 
-        virtual void setValue(V value) {
+        virtual void setValue(const V& value) {
             this->value = value;
         }
 
-        virtual V getValue() const {
+        virtual V& getValue() {
+            return this->value;
+        }
+
+        virtual const V& getValue() const {
             return this->value;
         }
 
@@ -57,17 +66,20 @@ namespace util {
                 return true;
             }
 
-            if (this->key != entry.getKey()) {
+            if (!(this->key == entry.getKey())) {
                 return false;
             }
 
-            if (this->value != entry.getValue()) {
+            if (!(this->value != entry.getValue())) {
                 return false;
             }
 
             return true;
         }
 
+        virtual bool operator==(const MapEntry<K, V>& other) const {
+            return this->equals(other);
+        }
     };
 
 }}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/StlMap.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/StlMap.h?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/StlMap.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/StlMap.h Mon Jul 23 22:01:19 2012
@@ -269,6 +269,10 @@ namespace util{
             throw decaf::lang::exceptions::UnsupportedOperationException();
         }
 
+        virtual Set< MapEntry<K, V> >* entrySet() const {
+            throw decaf::lang::exceptions::UnsupportedOperationException();
+        }
+
     public:
 
         virtual void lock() {

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/ConcurrentStlMap.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/ConcurrentStlMap.h?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/ConcurrentStlMap.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/concurrent/ConcurrentStlMap.h Mon Jul 23 22:01:19 2012
@@ -453,6 +453,10 @@ namespace concurrent{
             throw decaf::lang::exceptions::UnsupportedOperationException();
         }
 
+        virtual Set< MapEntry<K, V> >* entrySet() const {
+            throw decaf::lang::exceptions::UnsupportedOperationException();
+        }
+
     public:
 
         virtual void lock() {

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.cpp?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.cpp Mon Jul 23 22:01:19 2012
@@ -17,9 +17,31 @@
 
 #include "HashMapTest.h"
 
+#include <decaf/util/Set.h>
+#include <decaf/util/Iterator.h>
+#include <decaf/util/HashMap.h>
+#include <decaf/util/StlMap.h>
+#include <decaf/util/ArrayList.h>
+#include <decaf/lang/Integer.h>
+#include <decaf/lang/exceptions/IllegalArgumentException.h>
+
 using namespace std;
 using namespace decaf;
 using namespace decaf::util;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    const int MAP_SIZE = 1000;
+
+    void populateMap(HashMap<int, std::string>& hashMap) {
+        for (int i = 0; i < MAP_SIZE; ++i) {
+            hashMap.put(i, Integer::toString(i));
+        }
+    }
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 HashMapTest::HashMapTest() {
@@ -30,6 +52,518 @@ HashMapTest::~HashMapTest() {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::setUp() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
 void HashMapTest::testConstructor() {
 
+    HashMap<int, std::string> map;
+    CPPUNIT_ASSERT(map.isEmpty());
+    CPPUNIT_ASSERT_EQUAL(0, map.size());
+    CPPUNIT_ASSERT_EQUAL(false, map.containsKey(1));
+    CPPUNIT_ASSERT_EQUAL(false, map.containsValue("test"));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testConstructorI() {
+
+    HashMap<int, std::string> map(5);
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Created incorrect HashMap", 0, map.size());
+
+    try {
+        HashMap<int, std::string> map(-1);
+        CPPUNIT_FAIL("Should have thrown IllegalArgumentException for negative arg.");
+    } catch (IllegalArgumentException& e) {
+    }
+
+    HashMap<int, std::string> empty(0);
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown NoSuchElementException",
+        empty.get(1),
+        NoSuchElementException);
+    empty.put(1, "here");
+    CPPUNIT_ASSERT_MESSAGE("cannot get element", empty.get(1) == std::string("here"));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testConstructorIF() {
+
+    HashMap<int, std::string> map(5, 0.5f);
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Created incorrect HashMap", 0, map.size());
+
+    try {
+        HashMap<int, std::string> map(0, 0);
+        CPPUNIT_FAIL("Should have thrown IllegalArgumentException for negative arg.");
+    } catch (IllegalArgumentException& e) {
+    }
+
+    HashMap<int, std::string> empty(0, 0.25f);
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+        "Should have thrown NoSuchElementException",
+        empty.get(1),
+        NoSuchElementException);
+    empty.put(1, "here");
+    CPPUNIT_ASSERT_MESSAGE("cannot get element", empty.get(1) == std::string("here"));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testConstructorMap() {
+
+    HashMap<int, int> myMap;
+    for (int counter = 0; counter < 125; counter++) {
+        myMap.put(counter, counter);
+    }
+
+    HashMap<int, int> hashMap(myMap);
+    for (int counter = 0; counter < 125; counter++) {
+        CPPUNIT_ASSERT_MESSAGE("Failed to construct correct HashMap",
+            myMap.get(counter) == hashMap.get(counter));
+    }
+
+//    try {
+//        Map mockMap = new MockMap();
+//        hm = new HashMap(mockMap);
+//        fail("Should throw NullPointerException");
+//    } catch (NullPointerException e) {
+//        //empty
+//    }
+//
+//    HashMap map = new HashMap();
+//    map.put("a", "a");
+//    SubMap map2 = new SubMap(map);
+//    assertTrue(map2.containsKey("a"));
+//    assertTrue(map2.containsValue("a"));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testClear() {
+
+    HashMap<int, std::string> hashMap;
+    hashMap.put(1, "one");
+    hashMap.put(3, "three");
+    hashMap.put(2, "two");
+
+    hashMap.clear();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Clear failed to reset size", 0, hashMap.size());
+    for (int i = 0; i < 125; i++) {
+        CPPUNIT_ASSERT_THROW_MESSAGE(
+            "Failed to clear all elements",
+            hashMap.get(i),
+            NoSuchElementException);
+    }
+
+    // Check clear on a large loaded map of Integer keys
+    HashMap<int, std::string> map;
+    for (int i = -32767; i < 32768; i++) {
+        map.put(i, "foobar");
+    }
+    map.clear();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to reset size on large integer map", 0, map.size());
+    for (int i = -32767; i < 32768; i++) {
+        CPPUNIT_ASSERT_THROW_MESSAGE(
+            "Failed to clear all elements",
+            map.get(i),
+            NoSuchElementException);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testContainsKey() {
+
+    HashMap<int, std::string> hashMap;
+
+    hashMap.put(876, "test");
+
+    CPPUNIT_ASSERT_MESSAGE("Returned false for valid key", hashMap.containsKey(876));
+    CPPUNIT_ASSERT_MESSAGE("Returned true for invalid key", !hashMap.containsKey(1));
+
+    HashMap<int, std::string> hashMap2;
+    hashMap2.put(0, "test");
+    CPPUNIT_ASSERT_MESSAGE("Failed with key", hashMap2.containsKey(0));
+    CPPUNIT_ASSERT_MESSAGE("Failed with missing key matching hash", !hashMap2.containsKey(1));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testContainsValue() {
+
+    HashMap<int, std::string> hashMap;
+
+    hashMap.put(876, "test");
+
+    CPPUNIT_ASSERT_MESSAGE("Returned false for valid value", hashMap.containsValue("test"));
+    CPPUNIT_ASSERT_MESSAGE("Returned true for invalid valie", !hashMap.containsValue(""));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testEntrySet() {
+
+    HashMap<int, std::string> hashMap;
+
+    for (int i = 0; i < 50; i++) {
+        hashMap.put(i, Integer::toString(i));
+    }
+
+    Pointer< Set<MapEntry<int, std::string> > > set(hashMap.entrySet());
+    Pointer< Iterator<MapEntry<int, std::string> > > iterator(set->iterator());
+
+    CPPUNIT_ASSERT_MESSAGE("Returned set of incorrect size", hashMap.size() == set->size());
+    while (iterator->hasNext()) {
+        MapEntry<int, std::string> entry = iterator->next();
+        CPPUNIT_ASSERT_MESSAGE("Returned incorrect entry set",
+                               hashMap.containsKey(entry.getKey()) && hashMap.containsValue(entry.getValue()));
+    }
+
+    iterator.reset(set->iterator());
+    set->remove(iterator->next());
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Remove on set didn't take", 49, set->size());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testGet() {
+
+    HashMap<int, std::string> hashMap;
+
+    CPPUNIT_ASSERT_THROW_MESSAGE(
+            "Should have thrown NoSuchElementException",
+            hashMap.get(1),
+            NoSuchElementException);
+    hashMap.put(22, "HELLO");
+    CPPUNIT_ASSERT_EQUAL_MESSAGE("Get returned incorrect value for existing key",
+                                 std::string("HELLO"), hashMap.get(22));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testIsEmpty() {
+
+    HashMap<int, std::string> hashMap;
+
+    CPPUNIT_ASSERT_MESSAGE("Returned false for new map", hashMap.isEmpty());
+    hashMap.put(1, "1");
+    CPPUNIT_ASSERT_MESSAGE("Returned true for non-empty", !hashMap.isEmpty());
+    hashMap.clear();
+    CPPUNIT_ASSERT_MESSAGE("Returned false for cleared map", hashMap.isEmpty());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testKeySet() {
+
+    HashMap<int, std::string> hashMap;
+    populateMap(hashMap);
+    Pointer< Set<int> > set(hashMap.keySet());
+    CPPUNIT_ASSERT_MESSAGE("Returned set of incorrect size()", set->size() == hashMap.size());
+    for (int i = 0; i < MAP_SIZE; i++) {
+        CPPUNIT_ASSERT_MESSAGE("Returned set does not contain all keys", set->contains(i));
+    }
+
+    {
+        HashMap<int, std::string> localMap;
+        localMap.put(0, "test");
+        Pointer< Set<int> > intSet(localMap.keySet());
+        CPPUNIT_ASSERT_MESSAGE("Failed with zero key", intSet->contains(0));
+    }
+    {
+        HashMap<int, std::string> localMap;
+        localMap.put(1, "1");
+        localMap.put(102, "102");
+        localMap.put(203, "203");
+
+        Pointer< Set<int> > intSet(localMap.keySet());
+        Pointer< Iterator<int> > it(intSet->iterator());
+        int remove1 = it->next();
+        it->hasNext();
+        it->remove();
+        int remove2 = it->next();
+        it->remove();
+
+        ArrayList<int> list;
+        list.add(1);
+        list.add(102);
+        list.add(203);
+
+        list.remove(remove1);
+        list.remove(remove2);
+
+        CPPUNIT_ASSERT_MESSAGE("Wrong result", it->next() == list.get(0));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong size", 1, localMap.size());
+        it.reset(intSet->iterator());
+        CPPUNIT_ASSERT_MESSAGE("Wrong contents", it->next() == list.get(0));
+    }
+    {
+        HashMap<int, std::string> map2(101);
+        map2.put(1, "1");
+        map2.put(4, "4");
+
+        Pointer< Set<int> > intSet(map2.keySet());
+        Pointer< Iterator<int> > it2(intSet->iterator());
+
+        int remove3 = it2->next();
+        int next;
+
+        if (remove3 == 1) {
+            next = 4;
+        } else {
+            next = 1;
+        }
+        it2->hasNext();
+        it2->remove();
+        CPPUNIT_ASSERT_MESSAGE("Wrong result 2", it2->next() == next);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("Wrong size 2", 1, map2.size());
+        it2.reset(intSet->iterator());
+        CPPUNIT_ASSERT_MESSAGE("Wrong contents 2", it2->next() == next);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace {
+
+    class MyKey {
+    private:
+
+        static int COUNTER;
+
+        int id;
+
+    public:
+
+        MyKey() : id(++COUNTER) {
+        }
+
+        int hashCode() const {
+            return 0;
+        }
+
+        bool operator==(const MyKey& key) const {
+            return this->id == key.id;
+        }
+
+        friend std::ostream& operator<<(std::ostream& stream, const MyKey& key);
+    };
+
+    std::ostream& operator<<(std::ostream& stream, const MyKey& key) {
+        stream << "MyKey: " << key.id;
+        return stream;
+    }
+
+    int MyKey::COUNTER = 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+namespace decaf {
+namespace util {
+
+    template<>
+    struct HashCode<MyKey> : public std::unary_function<const MyKey&, int> {
+        int operator()(const MyKey& arg) const {
+            return arg.hashCode();
+        }
+    };
+
+}}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testPut() {
+
+    {
+        HashMap<std::string, std::string> hashMap(101);
+        hashMap.put("KEY", "VALUE");
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("Failed to install key/value pair",
+                                     std::string("VALUE"), hashMap.get("KEY"));
+    }
+    {
+        // Check my actual key instance is returned
+        HashMap<int, std::string> map;
+        for (int i = -32767; i < 32768; i++) {
+            map.put(i, "foobar");
+        }
+        int myKey = 0;
+        // Put a new value at the old key position
+        map.put(myKey, "myValue");
+        CPPUNIT_ASSERT(map.containsKey(myKey));
+        CPPUNIT_ASSERT_EQUAL(std::string("myValue"), map.get(myKey));
+        bool found = false;
+        Pointer< Set<int> > intSet(map.keySet());
+        Pointer< Iterator<int> > itr(intSet->iterator());
+        while (itr->hasNext()) {
+            int key = itr->next();
+            if ((found = key) == myKey) {
+                break;
+            }
+        }
+        CPPUNIT_ASSERT_MESSAGE("Should not find new key instance in hashashMap", !found);
+
+        // Add a new key instance and check it is returned
+        CPPUNIT_ASSERT_NO_THROW(map.remove(myKey));
+        map.put(myKey, "myValue");
+        CPPUNIT_ASSERT(map.containsKey(myKey));
+        CPPUNIT_ASSERT_EQUAL(std::string("myValue"), map.get(myKey));
+        itr.reset(intSet->iterator());
+        while (itr->hasNext()) {
+            int key = itr->next();
+            if ((found = (key == myKey))) {
+                break;
+            }
+        }
+        CPPUNIT_ASSERT_MESSAGE("Did not find new key instance in hashashMap", found);
+    }
+    {
+        // Ensure keys with identical hashcode are stored separately
+        HashMap<MyKey, std::string> map;
+
+        // Put non-equal object with same hashcode
+        MyKey aKey;
+        CPPUNIT_ASSERT(!map.containsKey(aKey));
+        map.put(aKey, "value");
+        MyKey aKey2;
+        CPPUNIT_ASSERT_THROW_MESSAGE(
+                "Should have thrown NoSuchElementException",
+                map.remove(aKey2),
+                NoSuchElementException);
+        MyKey aKey3;
+        map.put(aKey3, "foobar");
+        CPPUNIT_ASSERT_EQUAL(std::string("foobar"), map.get(aKey3));
+        CPPUNIT_ASSERT_EQUAL(std::string("value"), map.get(aKey));
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testPutAll() {
+
+    HashMap<int, std::string> hashMap;
+    populateMap(hashMap);
+
+    HashMap<int, std::string> hashMap2;
+    hashMap2.putAll(hashMap);
+    for (int i = 0; i < 1000; i++) {
+        CPPUNIT_ASSERT_MESSAGE("Failed to put all elements into new Map",
+                               hashMap2.get(i) == Integer::toString(i));
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testRemove() {
+
+    {
+        HashMap<int, std::string> hashMap;
+        populateMap(hashMap);
+
+        int size = hashMap.size();
+        CPPUNIT_ASSERT_NO_THROW_MESSAGE("Remove returned incorrect value", hashMap.remove(9));
+        CPPUNIT_ASSERT_THROW_MESSAGE(
+            "Should have thrown a NoSuchElementException on get of non-existent key.",
+            hashMap.get(9),
+            NoSuchElementException);
+
+        CPPUNIT_ASSERT_MESSAGE("Failed to decrement size", hashMap.size() == (size - 1));
+        CPPUNIT_ASSERT_THROW_MESSAGE(
+            "Should have thrown a NoSuchElementException on remove of non-existent key.",
+            hashMap.remove(9),
+            NoSuchElementException);
+    }
+    {
+        HashMap<int, std::string> hashMap;
+        for (int i = 0; i < 8192; i++) {
+            hashMap.put(i, "const");
+        }
+        for (int i = 0; i < 8192; i++) {
+            hashMap.put(i, Integer::toString(i));
+        }
+        for (int i = 8191; i >= 0; i--) {
+            std::string iValue = Integer::toString(i);
+            CPPUNIT_ASSERT_MESSAGE(std::string("Failed to replace value: ") + iValue,
+                                   hashMap.containsValue(iValue));
+            hashMap.remove(i);
+            CPPUNIT_ASSERT_MESSAGE(std::string("Failed to remove same value: ") + iValue,
+                                   !hashMap.containsValue(iValue));
+        }
+    }
+
+    {
+        // Ensure keys with identical hashcode are stored separately and removed correctly.
+        HashMap<MyKey, std::string> map;
+
+        // Put non-equal object with same hashcode
+        MyKey aKey;
+        CPPUNIT_ASSERT(!map.containsKey(aKey));
+        map.put(aKey, "value");
+        MyKey aKey2;
+        CPPUNIT_ASSERT_THROW_MESSAGE(
+                "Should have thrown NoSuchElementException",
+                map.remove(aKey2),
+                NoSuchElementException);
+        MyKey aKey3;
+        map.put(aKey3, "foobar");
+        CPPUNIT_ASSERT_EQUAL(std::string("foobar"), map.get(aKey3));
+        CPPUNIT_ASSERT_EQUAL(std::string("value"), map.get(aKey));
+        map.remove(aKey);
+        map.remove(aKey3);
+        CPPUNIT_ASSERT(!map.containsKey(aKey));
+        CPPUNIT_ASSERT(map.isEmpty());
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testRehash() {
+    // This map should rehash on adding the ninth element.
+    HashMap<MyKey, int> hashMap(10, 0.5f);
+
+    // Ordered set of keys.
+    MyKey keyOrder[9];
+
+    // Store eight elements
+    for (int i = 0; i < 8; i++) {
+        hashMap.put(keyOrder[i], i);
+    }
+
+    // Check expected ordering (inverse of adding order)
+    Pointer< Set<MyKey> > keySet(hashMap.keySet());
+    std::vector<MyKey> returnedKeys = keySet->toArray();
+    for (int i = 0; i < 8; i++) {
+        CPPUNIT_ASSERT_EQUAL(keyOrder[i], returnedKeys[7 - i]);
+    }
+
+    // The next put causes a rehash
+    hashMap.put(keyOrder[8], 8);
+    // Check expected new ordering (adding order)
+    returnedKeys = keySet->toArray();
+    for (int i = 0; i < 9; i++) {
+        CPPUNIT_ASSERT_EQUAL(keyOrder[i], returnedKeys[i]);
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testSize() {
+    HashMap<int, std::string> hashMap;
+    populateMap(hashMap);
+
+    CPPUNIT_ASSERT_MESSAGE("Returned incorrect size", hashMap.size() == MAP_SIZE);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testValues() {
+
+    HashMap<int, std::string> hashMap;
+    populateMap(hashMap);
+
+    Pointer< Collection<std::string> > c(hashMap.values());
+    CPPUNIT_ASSERT_MESSAGE("Returned collection of incorrect size()", c->size() == hashMap.size());
+    for (int i = 0; i < MAP_SIZE; i++) {
+        CPPUNIT_ASSERT_MESSAGE("Returned collection does not contain all keys",
+                               c->contains(Integer::toString(i)));
+    }
+
+    c->remove("10");
+    CPPUNIT_ASSERT_MESSAGE("Removing from collection should alter Map",
+                           !hashMap.containsKey(10));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void HashMapTest::testToString() {
+
+    HashMap<int, std::string> hashMap;
+    populateMap(hashMap);
+    std::string result = hashMap.toString();
+    CPPUNIT_ASSERT_MESSAGE("should return something", result != "");
 }

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.h?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/HashMapTest.h Mon Jul 23 22:01:19 2012
@@ -28,6 +28,23 @@ namespace util {
 
         CPPUNIT_TEST_SUITE( HashMapTest );
         CPPUNIT_TEST( testConstructor );
+        CPPUNIT_TEST( testConstructorI );
+        CPPUNIT_TEST( testConstructorIF );
+        CPPUNIT_TEST( testConstructorMap );
+        CPPUNIT_TEST( testClear );
+        CPPUNIT_TEST( testContainsKey );
+        CPPUNIT_TEST( testContainsValue );
+        CPPUNIT_TEST( testEntrySet );
+        CPPUNIT_TEST( testGet );
+        CPPUNIT_TEST( testPut );
+        CPPUNIT_TEST( testRemove );
+        CPPUNIT_TEST( testIsEmpty );
+        CPPUNIT_TEST( testKeySet );
+        CPPUNIT_TEST( testPutAll );
+        CPPUNIT_TEST( testRehash );
+        CPPUNIT_TEST( testSize );
+        CPPUNIT_TEST( testValues );
+        CPPUNIT_TEST( testToString );
         CPPUNIT_TEST_SUITE_END();
 
     public:
@@ -35,7 +52,26 @@ namespace util {
         HashMapTest();
         virtual ~HashMapTest();
 
+        virtual void setUp();
+
         void testConstructor();
+        void testConstructorI();
+        void testConstructorIF();
+        void testConstructorMap();
+        void testClear();
+        void testContainsKey();
+        void testContainsValue();
+        void testEntrySet();
+        void testGet();
+        void testPut();
+        void testRemove();
+        void testIsEmpty();
+        void testKeySet();
+        void testPutAll();
+        void testRehash();
+        void testSize();
+        void testValues();
+        void testToString();
 
     };
 

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/StlMapTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/StlMapTest.cpp?rev=1364819&r1=1364818&r2=1364819&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/StlMapTest.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test/decaf/util/StlMapTest.cpp Mon Jul 23 22:01:19 2012
@@ -246,6 +246,10 @@ public:
         throw decaf::lang::exceptions::UnsupportedOperationException();
     }
 
+    virtual Set< MapEntry<K, V> >* entrySet() const {
+        throw decaf::lang::exceptions::UnsupportedOperationException();
+    }
+
 public:
 
     virtual void lock() {