You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@etch.apache.org by ve...@apache.org on 2012/01/12 11:10:09 UTC

svn commit: r1230469 - in /incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu: ./ include/capu/ include/capu/container/ test/container/

Author: veithm
Date: Thu Jan 12 10:10:08 2012
New Revision: 1230469

URL: http://svn.apache.org/viewvc?rev=1230469&view=rev
Log:
ETCH-137 CAPU HashTable Implementation and Tests

Change-Id: Ia0fded93b5b9be83a994eced4f2b10a62b01bfc5

Added:
    incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Hash.h
      - copied, changed from r1230468, incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h
    incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/HashTable.h
    incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Pair.h
      - copied, changed from r1230468, incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h
    incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/test/container/HashTableTest.cpp
Modified:
    incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/CMakeLists.txt
    incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Config.h
    incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h

Modified: incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/CMakeLists.txt
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/CMakeLists.txt?rev=1230469&r1=1230468&r2=1230469&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/CMakeLists.txt (original)
+++ incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/CMakeLists.txt Thu Jan 12 10:10:08 2012
@@ -24,6 +24,7 @@ ADD_CLASS(os/Thread SOURCE_GROUP arch_so
 ADD_CLASS(os/CondVar SOURCE_GROUP arch_source_group)
 ADD_CLASS(os/StringUtils SOURCE_GROUP arch_source_group)
 ADD_CLASS(container/List)
+ADD_CLASS(container/HashTable)
 
 REQUIRED_PACKAGE(Thread)
 

Modified: incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Config.h
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Config.h?rev=1230469&r1=1230468&r2=1230469&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Config.h (original)
+++ incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Config.h Thu Jan 12 10:10:08 2012
@@ -23,6 +23,7 @@
 #include "stdlib.h"
 #include "string.h"
 
+#define DEFAULT_HASH_TABLE_SIZE 1000
 
 namespace capu
 {

Modified: incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h?rev=1230469&r1=1230468&r2=1230469&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h (original)
+++ incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h Thu Jan 12 10:10:08 2012
@@ -21,23 +21,25 @@
 
 #include "Config.h"
 
-namespace capu
-{
-    typedef int32_t status_t;
-    enum {
-        CAPU_OK                 = 0,
-        CAPU_EUNIMPL            = 1,
-        CAPU_ERANGE             = 2,
-        CAPU_EINVAL             = 3,
-        CAPU_ERROR              = 4,
-        CAPU_SOCKET_EBIND       = 5,
-        CAPU_SOCKET_ESOCKET     = 6,
-        CAPU_SOCKET_ECONNECT    = 7,
-        CAPU_SOCKET_ELISTEN     = 8,
-        CAPU_SOCKET_ECLOSE      = 9,
-        CAPU_SOCKET_EADDR       = 10,
-        CAPU_ENO_MEMORY         = 11
-    };
+namespace capu {
+  typedef int32_t status_t;
+
+  enum {
+    CAPU_OK = 0,
+    CAPU_EUNIMPL = 1,
+    CAPU_ERANGE = 2,
+    CAPU_EINVAL = 3,
+    CAPU_ERROR = 4,
+    CAPU_SOCKET_EBIND = 5,
+    CAPU_SOCKET_ESOCKET = 6,
+    CAPU_SOCKET_ECONNECT = 7,
+    CAPU_SOCKET_ELISTEN = 8,
+    CAPU_SOCKET_ECLOSE = 9,
+    CAPU_SOCKET_EADDR = 10,
+    CAPU_ENO_MEMORY = 11,
+    CAPU_TIMEOUT = 12,
+    CAPU_ENOT_EXIST = 13
+  };
 }
 #endif
 

Copied: incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Hash.h (from r1230468, incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h)
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Hash.h?p2=incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Hash.h&p1=incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h&r1=1230468&r2=1230469&rev=1230469&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h (original)
+++ incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Hash.h Thu Jan 12 10:10:08 2012
@@ -16,28 +16,38 @@
  * limitations under the License.
  */
 
-#ifndef __ERROR_H__
-#define __ERROR_H__
 
-#include "Config.h"
+#ifndef __HASH_H__
+#define __HASH_H__
 
-namespace capu
-{
-    typedef int32_t status_t;
-    enum {
-        CAPU_OK                 = 0,
-        CAPU_EUNIMPL            = 1,
-        CAPU_ERANGE             = 2,
-        CAPU_EINVAL             = 3,
-        CAPU_ERROR              = 4,
-        CAPU_SOCKET_EBIND       = 5,
-        CAPU_SOCKET_ESOCKET     = 6,
-        CAPU_SOCKET_ECONNECT    = 7,
-        CAPU_SOCKET_ELISTEN     = 8,
-        CAPU_SOCKET_ECLOSE      = 9,
-        CAPU_SOCKET_EADDR       = 10,
-        CAPU_ENO_MEMORY         = 11
-    };
+#include "capu/Config.h"
+
+namespace capu {
+
+  template <class T>
+  class Hash {
+  public:
+
+    static uint64_t Digest(T key) {
+      uint64_t result = 0;
+      for (uint64_t i = 0; i < 10; ++i) {
+        result = (result + static_cast<uint64_t> (key) * 13);
+      }
+      return static_cast<uint64_t> (result);
+    }
+
+    static uint64_t Digest(char* key) {
+      uint64_t result = 0;
+      char * keyStart = key;
+      char * keyEnd = key + strlen(key);
+      while (keyStart != keyEnd) {
+        result = (result + static_cast<uint64_t> (*keyStart) * 13);
+        ++keyStart;
+      }
+      return result;
+    }
+
+  };
 }
-#endif
+#endif /* HASH_H */
 

Added: incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/HashTable.h
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/HashTable.h?rev=1230469&view=auto
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/HashTable.h (added)
+++ incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/HashTable.h Thu Jan 12 10:10:08 2012
@@ -0,0 +1,389 @@
+/* $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __HASHTABLE_H__
+#define __HASHTABLE_H__
+#include "capu/Error.h"
+#include "capu/Config.h"
+#include "capu/container/Comparator.h"
+#include "capu/container/List.h"
+#include "capu/container/Pair.h"
+#include "capu/container/Hash.h"
+
+namespace capu {
+
+  template <class Key, class T, class C = Comparator<Key>, class Hash = Hash<Key> >
+  class HashTable {
+  private:
+
+    class HashTableIterator {
+    public:
+
+      /**
+       * constructor
+       *
+       * @param list     array of linked list which provide channing for hashtable
+       * @param listSize size of hash table (size of linked list array)
+       */
+      HashTableIterator(List<Pair<Key, T> > * list, uint64_t listSize);
+
+      /**
+       * destructor
+       */
+      ~HashTableIterator();
+
+      /**
+       * Check if iterator has next element.
+       * @return false if the next of current node that is pointed, is null otherwise true
+       */
+      bool_t hasNext();
+
+      /**
+       * Get next iterator element.
+       * @param value
+       * @return CAPU_ERANGE if the next of current node that is pointed, is null
+       *         CAPU_EINVAL if the value is NULL
+       *         CAPU_OK if the next element has been gotten
+       *
+       */
+      status_t next(Pair<Key, T>* value);
+
+    private:
+      uint64_t mCurrentListIndex;
+      typename List<Pair<Key, T> >::Iterator mCurrentListIterator;
+      List<Pair<Key, T> > * mList;
+      uint64_t mMaxListSize;
+    };
+
+  public:
+
+    typedef HashTableIterator Iterator;
+
+    /**
+     * Constructs HashTable.
+     */
+    HashTable();
+
+    /**
+     * Constructs HashTable.
+     */
+    HashTable(uint64_t size);
+
+    /**
+     * Destructure.
+     */
+    virtual ~HashTable();
+
+    /**
+     * put a new value to the hashtable.
+     * @param key               Key value
+     * @param value             new value that will be put to hash table
+     * @param value_old         buffer which will be used to store value of old element
+     *
+     * @return CAPU_OK if remove is successful
+               CAPU_ENO_MEMORY if allocation of element is failed
+     *         CAPU_EINVAL if value_old is null
+     *
+     */
+    status_t put(Key key, T value, T* value_old = NULL);
+
+    /**
+     * Get value associated with key in the hashtable.
+     * @param key       Key
+     * @param value     buffer which will be used to return the found element
+     *
+     * @return CAPU_OK if get is successful performed
+     *         CAPU_EINVAL if value is null
+     *         CAPU_ENOT_EXIST if there is no pair with specified key
+     */
+    status_t get(Key key, T* value);
+
+    /**
+     * Remove value associated with key in the hashtable.
+     *
+     * @param key               Key value
+     * @param value_old         buffer which will be used to store value of removed element
+     *
+     * @return CAPU_OK if remove is successful
+     *         CAPU_EINVAL if value_old is null
+     *         CAPU_ERANGE if the pair with specified key does not exist in hash table
+     *
+     */
+    status_t remove(Key key, T* value_old);
+
+    /**
+     * Returns count of the hashtable.
+     * @return number of element in hash table
+     */
+    uint64_t count();
+
+    /**
+     * Clear all key and values of the hashtable.
+     *
+     * @return CAPU_OK if all elements in list have been deleted
+     */
+    status_t clear();
+
+    /**
+     * Return iterator for iterating key value tuples.
+     * @return Iterator
+     */
+    Iterator begin();
+
+  private:
+
+    /**
+     * internally used function to check the same key exist in the specified linked list
+     *
+     * @param index   specify which link list will be checked
+     * @param k specify which key will be searched
+     * @return -1 if the key is unique
+     *          otherwise the index in the linked list
+     */
+    int32_t getKeyIndexFromBucket(uint64_t index, Key k) {
+      int32_t count = 0;
+      typename List<Pair<Key, T> >::Iterator it = mLists[index].begin();
+      Pair<Key, T> pair;
+      C compare;
+      while (it.hasNext()) {
+        it.next(&pair);
+        //NOT UNIQUE KEY
+        if (compare(pair.first, k))
+          return count;
+        count++;
+      }
+      //UNIQUE KEY
+      return -1;
+    }
+
+    List<Pair<Key, T>, Comparator<Pair<Key, T> > > *mLists;
+    uint64_t mSize;
+    uint64_t mCount;
+
+  };
+
+  template <class Key, class T, class C, class Hash>
+  HashTable<Key, T, C, Hash>::HashTable()
+  : mSize(DEFAULT_HASH_TABLE_SIZE)
+  , mCount(0) {
+    mLists = new List<Pair<Key, T>, Comparator<Pair<Key, T> > >[(uint32_t) mSize];
+  }
+
+  template <class Key, class T, class C, class Hash>
+  HashTable<Key, T, C, Hash>::HashTable(uint64_t size)
+  : mCount(0) {
+    if (size <= 0) {
+      mSize = DEFAULT_HASH_TABLE_SIZE;
+    } else {
+      mSize = size;
+    }
+    mLists = new List<Pair<Key, T>, Comparator<Pair<Key, T> > >[(uint32_t) mSize];
+  }
+
+  template <class Key, class T, class C, class Hash>
+  HashTable<Key, T, C, Hash>::~HashTable() {
+    delete [] mLists;
+  }
+
+  template <class Key, class T, class C, class Hash>
+  status_t HashTable<Key, T, C, Hash>::put(Key key, T value, T* value_old) {
+    status_t result;
+    uint64_t index = Hash::Digest(key) % mSize;
+    if (mLists[index].isEmpty()) {
+      Pair<Key, T> pair(key, value);
+      result = mLists[index].add(pair);
+      if (result != CAPU_OK) {
+        return result;
+      }
+      mCount++;
+      //THERE IS NO OLD VALUE
+    } else {
+      Pair<Key, T> new_pair(key, value);
+      int32_t key_duplicate_index = this->getKeyIndexFromBucket(index, key);
+      if (key_duplicate_index < 0) {
+        result = mLists[index].add(new_pair);
+        if (result != CAPU_OK) {
+          return result;
+        }
+        mCount++;
+        //THERE IS NO OLD VALUE
+      } else {
+        Pair <Key, T> old_pair;
+        result = mLists[index].get(key_duplicate_index, &old_pair);
+        if (result != CAPU_OK) {
+          return result;
+        }
+        //OLD VALUE
+        if (value_old == NULL) {
+          return CAPU_EINVAL;
+        } else {
+          *value_old = old_pair.second;
+        }
+
+        result = mLists[index].set(key_duplicate_index, new_pair);
+        if (result != CAPU_OK) {
+          return result;
+        }
+      }
+    }
+    return CAPU_OK;
+  }
+
+  template <class Key, class T, class C, class Hash>
+  status_t HashTable<Key, T, C, Hash>::get(Key key, T* value) {
+    if (value == NULL)
+      return CAPU_EINVAL;
+
+    status_t result;
+    uint64_t index = Hash::Digest(key) % mSize;
+
+    int32_t key_index = this->getKeyIndexFromBucket(index, key);
+    if (key_index < 0) {
+      return CAPU_ENOT_EXIST;
+    } else {
+      Pair<Key, T> pair;
+      result = mLists[index].get(key_index, &pair);
+      if (result != CAPU_OK) {
+        return result;
+      }
+      //GET THE VALUE
+      *value = pair.second;
+    }
+    return CAPU_OK;
+  }
+
+  template <class Key, class T, class C, class Hash>
+  status_t HashTable<Key, T, C, Hash>::remove(Key key, T* value_old) {
+    if (value_old == NULL) {
+      return CAPU_EINVAL;
+    }
+    status_t result;
+    uint64_t index = Hash::Digest(key) % mSize;
+
+    int32_t key_index = this->getKeyIndexFromBucket(index, key);
+    if (key_index < 0) {
+      return CAPU_ERANGE;
+    } else {
+      Pair<Key, T> pair;
+      //retrieve the value
+      result = mLists[index].get(key_index, &pair);
+      if (result != CAPU_OK) {
+        return result;
+      }
+      //delete
+      result = mLists[index].removeAt(key_index);
+      if (result != CAPU_OK) {
+        return result;
+      }
+      mCount--;
+      //GET THE VALUE
+      *value_old = pair.second;
+    }
+    return CAPU_OK;
+  }
+
+  template <class Key, class T, class C, class Hash>
+  uint64_t HashTable<Key, T, C, Hash>::count() {
+    return mCount;
+  }
+
+  template <class Key, class T, class C, class Hash>
+  status_t HashTable<Key, T, C, Hash>::clear() {
+    for (uint64_t i = 0; i < mSize; ++i) {
+      mLists[i].clear();
+    }
+    mCount = 0;
+    return CAPU_OK;
+  }
+
+  template <class Key, class T, class C, class Hash>
+  typename HashTable<Key, T, C, Hash>::Iterator HashTable<Key, T, C, Hash>::begin() {
+    return HashTable<Key, T, C, Hash>::Iterator(mLists, mSize);
+  }
+
+  template <class Key, class T, class C, class Hash>
+  HashTable<Key, T, C, Hash>::HashTableIterator::HashTableIterator(List<Pair<Key, T> > * list, uint64_t list_size) {
+    mCurrentListIndex = 0;
+    this->mList = list;
+    mMaxListSize = list_size;
+    this->mCurrentListIterator = list[mCurrentListIndex].begin();
+
+    //to point the first non-empty one
+    for (uint64_t i = 0; i < list_size; ++i) {
+      if (!mList[i].isEmpty()) {
+        mCurrentListIndex = i;
+        this->mCurrentListIterator = list[i].begin();
+        break;
+      }
+    }
+  }
+
+  template <class Key, class T, class C, class Hash>
+  HashTable<Key, T, C, Hash>::HashTableIterator::~HashTableIterator() {
+
+  }
+
+  template <class Key, class T, class C, class Hash>
+  bool_t HashTable<Key, T, C, Hash>::HashTableIterator::hasNext() {
+    if (mCurrentListIterator.hasNext()) {
+      return true;
+    } else {
+      do {
+        mCurrentListIndex++;
+        if (mCurrentListIndex >= mMaxListSize) {
+          return false;
+        }
+      } while (mList[mCurrentListIndex].isEmpty());
+
+      if (mCurrentListIndex < mMaxListSize) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+
+  template <class Key, class T, class C, class Hash>
+  status_t HashTable<Key, T, C, Hash>::HashTableIterator::next(Pair<Key, T>* value) {
+    if (value == NULL) {
+      return CAPU_EINVAL;
+    } else if (mCurrentListIndex >= mMaxListSize) {
+      return CAPU_ERANGE;
+    } else {
+      status_t result = mCurrentListIterator.next(value);
+      if (result != CAPU_OK)
+        return result;
+
+      if (!mCurrentListIterator.hasNext()) {
+        do {
+          mCurrentListIndex++;
+          if (mCurrentListIndex >= mMaxListSize) {
+            break;
+          }
+        } while (mList[mCurrentListIndex].isEmpty());
+
+        if (mCurrentListIndex < mMaxListSize) {
+          mCurrentListIterator = mList[mCurrentListIndex].begin();
+        }
+      }
+    }
+    return CAPU_OK;
+  }
+}
+
+#endif

Copied: incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Pair.h (from r1230468, incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h)
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Pair.h?p2=incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Pair.h&p1=incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h&r1=1230468&r2=1230469&rev=1230469&view=diff
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/Error.h (original)
+++ incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/include/capu/container/Pair.h Thu Jan 12 10:10:08 2012
@@ -15,29 +15,37 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __PAIR_H__
+#define __PAIR_H__
 
-#ifndef __ERROR_H__
-#define __ERROR_H__
+namespace capu {
 
-#include "Config.h"
+    template <class T1, class T2>
+    class Pair {
 
-namespace capu
-{
-    typedef int32_t status_t;
-    enum {
-        CAPU_OK                 = 0,
-        CAPU_EUNIMPL            = 1,
-        CAPU_ERANGE             = 2,
-        CAPU_EINVAL             = 3,
-        CAPU_ERROR              = 4,
-        CAPU_SOCKET_EBIND       = 5,
-        CAPU_SOCKET_ESOCKET     = 6,
-        CAPU_SOCKET_ECONNECT    = 7,
-        CAPU_SOCKET_ELISTEN     = 8,
-        CAPU_SOCKET_ECLOSE      = 9,
-        CAPU_SOCKET_EADDR       = 10,
-        CAPU_ENO_MEMORY         = 11
+    public:
+
+        inline bool_t operator==(const Pair<T1, T2> &rhs) {
+            return ((first == rhs.first) && (second == rhs.second));
+        }
+
+        ~Pair() {
+
+        }
+
+        Pair() {
+
+        }
+
+        Pair(T1 _first, T2 _second)
+        : first(_first), second(_second) {
+
+        }
+        T1 first;
+        T2 second;
     };
 }
-#endif
+
+
+#endif /* PAIR_H */
 

Added: incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/test/container/HashTableTest.cpp
URL: http://svn.apache.org/viewvc/incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/test/container/HashTableTest.cpp?rev=1230469&view=auto
==============================================================================
--- incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/test/container/HashTableTest.cpp (added)
+++ incubator/etch/trunk/binding-cpp/runtime/lib/capu/modules/capu/test/container/HashTableTest.cpp Thu Jan 12 10:10:08 2012
@@ -0,0 +1,258 @@
+/* $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include "capu/container/HashTable.h"
+#include "capu/Error.h"
+
+TEST(HashTable, Constructor_Default) {
+  //create an empty linked list
+  capu::HashTable<capu::int32_t, capu::int32_t>* list = new capu::HashTable<capu::int32_t, capu::int32_t > ();
+  delete list;
+}
+
+TEST(HashTable, put) {
+  capu::int32_t key = 10;
+  capu::int32_t value = 5;
+  capu::status_t status = capu::CAPU_OK;
+  capu::int64_t count = -1;
+
+  capu::HashTable<capu::int32_t, capu::int32_t>* h1 = new capu::HashTable<capu::int32_t, capu::int32_t > ();
+  // add new key
+  status = h1->put(key, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+  // check count
+  count = h1->count();
+  EXPECT_TRUE(count == 1);
+  delete h1;
+}
+
+TEST(HashTable, count) {
+  capu::int64_t count = -1;
+
+  capu::HashTable<capu::int32_t, capu::int32_t>* h1 = new capu::HashTable<capu::int32_t, capu::int32_t > ();
+  //check count
+  count = h1->count();
+  EXPECT_TRUE(count == 0);
+
+  delete h1;
+}
+
+TEST(HashTable, get) {
+  capu::int32_t key = 5;
+  capu::int32_t key2 = 6;
+  capu::int32_t value = 5;
+  capu::status_t status = capu::CAPU_OK;
+
+  capu::int32_t return_value = -1;
+  capu::int64_t count = -1;
+
+  capu::HashTable<capu::int32_t, capu::int32_t>* h1 =
+          new capu::HashTable<capu::int32_t, capu::int32_t > ();
+  // add new key
+  status = h1->put(key, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+  // check count
+  count = h1->count();
+  EXPECT_TRUE(count == 1);
+
+  // get the added element
+  status = h1->get(key, &return_value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+  //check its value
+  EXPECT_TRUE(return_value == value);
+  //get a element to null variable
+  status = h1->get(key, NULL);
+  EXPECT_TRUE(status == capu::CAPU_EINVAL);
+  //get an element of non existing key
+  status = h1->get(key2, &return_value);
+  EXPECT_TRUE(status == capu::CAPU_ENOT_EXIST);
+
+  delete h1;
+}
+
+TEST(HashTable, clear) {
+  capu::int32_t key = 5;
+  capu::int32_t key2 = 6;
+  capu::int32_t value = 5;
+  capu::status_t status = capu::CAPU_OK;
+
+  capu::int64_t count = -1;
+
+  capu::HashTable<capu::int32_t, capu::int32_t>* h1 = new capu::HashTable<capu::int32_t, capu::int32_t > ();
+  // add new keys
+  status = h1->put(key, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+
+  //add new keys
+  status = h1->put(key2, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+
+  // check count
+  count = h1->count();
+  EXPECT_TRUE(count == 2);
+
+  //remove all
+  status = h1->clear();
+  EXPECT_TRUE(status == capu::CAPU_OK);
+
+  //check count
+  count = h1->count();
+  EXPECT_TRUE(count == 0);
+
+  delete h1;
+}
+
+TEST(HashTable, remove) {
+  capu::int32_t key = 5;
+  capu::int32_t key2 = 6;
+  capu::int32_t value = 5;
+  capu::status_t status = capu::CAPU_OK;
+
+  capu::int32_t return_value = -1;
+  capu::int64_t count = -1;
+
+  capu::HashTable<capu::int32_t, capu::int32_t>* h1 = new capu::HashTable<capu::int32_t, capu::int32_t > ();
+  // add new keys
+  status = h1->put(key, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+  //delete a non existing key
+  status = h1->remove(key2, &return_value);
+  EXPECT_TRUE(status == capu::CAPU_ERANGE);
+
+  //add new value
+  status = h1->put(key2, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+
+  // check count
+  count = h1->count();
+  EXPECT_TRUE(count == 2);
+
+  //delete existing key
+  status = h1->remove(key, &return_value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+  EXPECT_TRUE(value == return_value);
+
+  //check count
+  count = h1->count();
+  EXPECT_TRUE(count == 1);
+
+  delete h1;
+}
+
+TEST(HashTable, set_get_existing) {
+  capu::int32_t key = 10;
+
+  capu::int32_t key2 = 11;
+  capu::int32_t value = 5;
+  capu::status_t status = capu::CAPU_OK;
+
+  capu::int32_t return_value = -1;
+  capu::int64_t count = -1;
+
+  capu::HashTable<capu::int32_t, capu::int32_t>* h1 = new capu::HashTable<capu::int32_t, capu::int32_t > ();
+  // add new keys
+  status = h1->put(key, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+
+  //add new value
+  status = h1->put(key2, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+
+  value = 3;
+  //add new value over existing one
+  status = h1->put(key, value, &return_value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+  //check the retrieved old value
+  EXPECT_TRUE(5 == return_value);
+
+  //check the new value
+  status = h1->get(key, &return_value);
+  EXPECT_TRUE(3 == return_value);
+
+  // check count
+  count = h1->count();
+  EXPECT_TRUE(count == 2);
+
+  delete h1;
+
+}
+
+TEST(HashtableIterator, hasNext) {
+  capu::int32_t key = 10;
+  capu::int32_t key2 = 12;
+
+  capu::int32_t value = 5;
+  capu::status_t status = capu::CAPU_OK;
+
+  capu::HashTable<capu::int32_t, capu::int32_t>* h1 = new capu::HashTable<capu::int32_t, capu::int32_t > ();
+
+  //create iterator
+  capu::HashTable<capu::int32_t, capu::int32_t>::Iterator it = h1->begin();
+  //check hasNext
+  EXPECT_TRUE(it.hasNext() == false);
+
+  // add new keys
+  status = h1->put(key, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+
+  //add new value
+  status = h1->put(key2, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+
+  it = h1->begin();
+  EXPECT_TRUE(it.hasNext() == true);
+
+  delete h1;
+}
+
+TEST(HashtableIterator, next) {
+  capu::int32_t key = 10;
+  capu::int32_t key2 = 12;
+
+  capu::int32_t value = 5;
+  capu::status_t status = capu::CAPU_OK;
+  capu::Pair<capu::int32_t, capu::int32_t> pair;
+  capu::HashTable<capu::int32_t, capu::int32_t>* h1 = new capu::HashTable<capu::int32_t, capu::int32_t > ();
+
+  //create iterator
+  capu::HashTable<capu::int32_t, capu::int32_t>::Iterator it = h1->begin();
+
+  //check hasNext
+  EXPECT_TRUE(it.hasNext() == false);
+
+  EXPECT_TRUE(it.next(&pair) == capu::CAPU_ERANGE);
+
+  // add new keys
+  status = h1->put(key, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+
+  //add new value
+  status = h1->put(key2, value);
+  EXPECT_TRUE(status == capu::CAPU_OK);
+  it = h1->begin();
+
+  it.next(&pair);
+  EXPECT_TRUE(pair.first == key);
+  EXPECT_TRUE(pair.second == value);
+
+  it.next(&pair);
+  EXPECT_TRUE(pair.first == key2);
+  EXPECT_TRUE(pair.second == value);
+  delete h1;
+}