Fawkes API  Fawkes Development Version
lock_hashmap.h
00001 
00002 /***************************************************************************
00003  *  lock_hashmap.h - Lockable hash map
00004  *
00005  *  Created: Fri May 11 22:40:09 2007
00006  *  Copyright  2006-2007  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #ifndef __CORE_UTILS_LOCK_HASHMAP_H_
00025 #define __CORE_UTILS_LOCK_HASHMAP_H_
00026 
00027 #include <core/threading/mutex.h>
00028 #include <core/utils/refptr.h>
00029 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
00030 #  include <tr1/unordered_map>
00031 #else
00032 #  include <ext/hash_map>
00033 #endif
00034 
00035 namespace fawkes {
00036 
00037 
00038 template <class KeyType,
00039           class ValueType,
00040 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
00041           class HashFunction = std::tr1::hash<KeyType>,
00042           class EqualKey     = std::equal_to<KeyType> >
00043 class LockHashMap : public std::tr1::unordered_map<KeyType, ValueType, HashFunction, EqualKey>
00044 #else
00045           class HashFunction = __gnu_cxx::hash<KeyType>,
00046           class EqualKey     = std::equal_to<KeyType> >
00047 class LockHashMap : public __gnu_cxx::hash_map<KeyType, ValueType, HashFunction, EqualKey>
00048 #endif
00049 {
00050  public:
00051   LockHashMap();
00052   LockHashMap(const LockHashMap<KeyType, ValueType, HashFunction, EqualKey> &lh);
00053   virtual ~LockHashMap();
00054 
00055   void          lock() const;
00056   bool          try_lock() const;
00057   void          unlock() const;
00058   RefPtr<Mutex> mutex() const;
00059 
00060   LockHashMap<KeyType, ValueType, HashFunction, EqualKey> &
00061   operator=(const LockHashMap<KeyType, ValueType, HashFunction, EqualKey> &ll);
00062 
00063  private:
00064   mutable RefPtr<Mutex> __mutex;
00065 
00066 };
00067 
00068 
00069 /** @class LockHashMap core/utils/lock_hashmap.h
00070  * Hash map with a lock.
00071  * This class provides a hash map that has an intrinsic lock. The lock can be applied
00072  * with the regular locking methods.
00073  *
00074  * @see Mutex
00075  * @ingroup FCL
00076  * @author Tim Niemueller
00077  */
00078 
00079 
00080 /** Constructor. */
00081 template <class KeyType, class ValueType, class HashFunction, class EqualKey>
00082 LockHashMap<KeyType, ValueType, HashFunction, EqualKey>::LockHashMap()
00083   : __mutex(new Mutex())
00084 {
00085 }
00086 
00087 
00088 /** Copy constructor.
00089  * @param lh LockHashMap to copy
00090  */
00091 template <class KeyType, class ValueType, class HashFunction, class EqualKey>
00092 LockHashMap<KeyType, ValueType, HashFunction, EqualKey>::LockHashMap(const LockHashMap<KeyType, ValueType, HashFunction, EqualKey> &lh)
00093 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)
00094   : std::tr1::unordered_map<KeyType, ValueType, HashFunction, EqualKey>::unordered_map(lh)
00095 #else
00096   : __gnu_cxx::hash_map<KeyType, ValueType, HashFunction, EqualKey>::hash_map(lh)
00097 #endif
00098     , __mutex(new Mutex())
00099 {
00100 }
00101 
00102 
00103 /** Destructor. */
00104 template <class KeyType, class ValueType, class HashFunction, class EqualKey>
00105 LockHashMap<KeyType, ValueType, HashFunction, EqualKey>::~LockHashMap()
00106 {
00107 }
00108 
00109 
00110 /** Lock map. */
00111 template <class KeyType, class ValueType, class HashFunction, class EqualKey>
00112 void
00113 LockHashMap<KeyType, ValueType, HashFunction, EqualKey>::lock() const
00114 {
00115   __mutex->lock();
00116 }
00117 
00118 
00119 /** Try to lock map.
00120  * @return true, if the lock has been aquired, false otherwise.
00121  */
00122 template <class KeyType, class ValueType, class HashFunction, class EqualKey>
00123 bool
00124 LockHashMap<KeyType, ValueType, HashFunction, EqualKey>::try_lock() const
00125 {
00126   return __mutex->try_lock();
00127 }
00128 
00129 
00130 /** Unlock map. */
00131 template <class KeyType, class ValueType, class HashFunction, class EqualKey>
00132 void
00133 LockHashMap<KeyType, ValueType, HashFunction, EqualKey>::unlock() const
00134 {
00135   return __mutex->unlock();
00136 }
00137 
00138 
00139 /** Get access to the internal mutex.
00140  * Can be used with MutexLocker.
00141  * @return internal mutex
00142  */
00143 template <typename KeyType, typename ValueType, class HashFunction, typename EqualKey>
00144 RefPtr<Mutex>
00145 LockHashMap<KeyType, ValueType, HashFunction, EqualKey>::mutex() const
00146 {
00147   return __mutex;
00148 }
00149 
00150 
00151 /** Copy values from another LockHashMap.
00152  * Copies the values one by one. Both instances are locked during the copying and
00153  * this instance is cleared before copying.
00154  * @param ll hash map to copy
00155  * @return reference to this instance
00156  */
00157 template <typename KeyType, typename ValueType, class HashFunction, typename EqualKey>
00158 LockHashMap<KeyType, ValueType, HashFunction, EqualKey> &
00159 LockHashMap<KeyType, ValueType, HashFunction, EqualKey>::operator=(
00160   const LockHashMap<KeyType, ValueType, HashFunction, EqualKey> &ll)
00161 {
00162   __mutex->lock();
00163   ll.lock();
00164   this->clear();
00165   typename LockHashMap<KeyType, ValueType, HashFunction, EqualKey>::const_iterator i;
00166   for (i = ll.begin(); i != ll.end(); ++i) {
00167     this->insert(*i);
00168   }
00169   ll.unlock();
00170   __mutex->unlock();
00171 
00172   return *this;
00173 }
00174 
00175 } // end namespace fawkes
00176 
00177 #endif