Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

StateDB.hpp

Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 /** @file StateDB.hpp
00003  */
00004 //----------------------------------------------------------------------------
00005 
00006 #ifndef POSITIONDB_HPP
00007 #define POSITIONDB_HPP
00008 
00009 #include <boost/concept_check.hpp>
00010 #include "HashDB.hpp"
00011 #include "HexState.hpp"
00012 
00013 _BEGIN_BENZENE_NAMESPACE_
00014 
00015 //----------------------------------------------------------------------------
00016 
00017 namespace {
00018 
00019 hash_t GetHash(const HexState& state)
00020 {
00021     hash_t hash1 = state.Hash();
00022     HexState rotatedState(state);
00023     rotatedState.Position().RotateBoard();
00024     hash_t hash2 = rotatedState.Hash();
00025     return std::min(hash1, hash2);
00026 }
00027 
00028 /** Data must be stored for the state of the minimum hash. */
00029 inline bool NeedToRotate(const HexState& state, hash_t minHash)
00030 {
00031     return state.Hash() != minHash;
00032 }
00033 
00034 }
00035 
00036 //----------------------------------------------------------------------------
00037 
00038 /** Class is rotatable by calling Rotate(). */
00039 template<class T>
00040 struct RotatableConcept
00041 {
00042     void constraints() 
00043     {
00044         const ConstBoard& brd = ConstBoard::Get(1, 1);
00045         T t;
00046         t.Rotate(brd);
00047     }
00048 };
00049 
00050 /** Concept of a state in a HashDB. */
00051 template<class T>
00052 struct StateDBStateConcept
00053 {
00054     void constraints() 
00055     {
00056         boost::function_requires< HashDBStateConcept<T> >();
00057         boost::function_requires< RotatableConcept<T> >();
00058     }
00059 };
00060 
00061 //----------------------------------------------------------------------------
00062 
00063 /** Database of hex positions handling rotations. */
00064 template<class T>
00065 class StateDB
00066 {
00067     BOOST_CLASS_REQUIRE(T, benzene, StateDBStateConcept);
00068 
00069 public:
00070 
00071     struct Statistics
00072     {
00073         std::size_t m_gets;
00074 
00075         std::size_t m_hits;
00076 
00077         std::size_t m_puts;
00078 
00079         std::size_t m_rotations;
00080 
00081         std::string Write() const;
00082 
00083         Statistics();
00084     };
00085 
00086     /** Opens database, creates it if it does not exist. */
00087     StateDB(const std::string& filename, const std::string& type);
00088 
00089     /** Closes database. */    
00090     ~StateDB();
00091 
00092     /** Returns true if position exists in database. */
00093     bool Exists(const HexState& pos) const;
00094 
00095     /** Returns true if get is successful. */
00096     bool Get(const HexState& pos, T& data) const;
00097 
00098     /** Returns true if put is successful. */
00099     bool Put(const HexState& brd, const T& data);
00100 
00101     void Flush();
00102 
00103     Statistics GetStatistics() const;
00104 
00105     std::string BDBStatistics();
00106 
00107 private:
00108     HashDB<T> m_db;
00109 
00110     mutable Statistics m_stats;
00111 };
00112 
00113 template<class T>
00114 StateDB<T>::StateDB(const std::string& filename, const std::string& type)
00115     : m_db(filename, type),
00116       m_stats()
00117 {
00118 }
00119 
00120 template<class T>
00121 StateDB<T>::~StateDB()
00122 {
00123 }
00124 
00125 template<class T>
00126 bool StateDB<T>::Exists(const HexState& state) const
00127 {
00128     return m_db.Exists(GetHash(state));
00129 }
00130 
00131 template<class T>
00132 bool StateDB<T>::Get(const HexState& state, T& data) const
00133 {
00134     m_stats.m_gets++;
00135     hash_t hash = GetHash(state);
00136     if (!m_db.Get(hash, data))
00137         return false;
00138     m_stats.m_hits++;
00139     if (NeedToRotate(state, hash))
00140     {
00141         m_stats.m_rotations++;
00142         data.Rotate(state.Position().Const());
00143     }
00144     return true;
00145 }
00146 
00147 template<class T>
00148 bool StateDB<T>::Put(const HexState& state, const T& data)
00149 {
00150     m_stats.m_puts++;
00151     hash_t hash = GetHash(state);
00152     T myData(data);
00153     if (NeedToRotate(state, hash))
00154     {
00155         m_stats.m_rotations++;
00156         myData.Rotate(state.Position().Const());
00157     }
00158     return m_db.Put(hash, myData);
00159 }
00160 
00161 template<class T>
00162 void StateDB<T>::Flush()
00163 {
00164     m_db.Flush();
00165 }
00166 
00167 template<class T>
00168 typename StateDB<T>::Statistics 
00169 StateDB<T>::GetStatistics() const
00170 {
00171     return m_stats;
00172 }
00173 
00174 template<class T>
00175 StateDB<T>::Statistics::Statistics()
00176     : m_gets(0), 
00177       m_hits(0), 
00178       m_puts(0), 
00179       m_rotations(0) 
00180 { 
00181 }
00182 
00183 template<class T>
00184 std::string StateDB<T>::Statistics::Write() const
00185 {
00186     std::ostringstream os;
00187     os << "StateDB statistics\n"
00188        << "Reads      " << m_gets << '\n'
00189        << "Hits       " << m_hits << '\n'
00190        << "Writes     " << m_puts << '\n'
00191        << "Rotations  " << m_rotations;
00192     return os.str();
00193 }
00194 
00195 template<class T>
00196 std::string StateDB<T>::BDBStatistics()
00197 {
00198     return m_db.BDBStatistics();
00199 }
00200 
00201 //----------------------------------------------------------------------------
00202 
00203 /** Set of positions; handles rotations. */
00204 class StateSet
00205 {
00206 public:
00207     StateSet();
00208 
00209     ~StateSet();
00210 
00211     void Insert(const HexState& state);
00212 
00213     bool Exists(const HexState& state) const;
00214 
00215     std::size_t Size() const;
00216 
00217 private:
00218     std::set<hash_t> m_set;
00219 };
00220 
00221 inline StateSet::StateSet()
00222 {
00223 }
00224 
00225 inline StateSet::~StateSet()
00226 {
00227 }
00228 
00229 inline void StateSet::Insert(const HexState& state)
00230 {
00231     m_set.insert(GetHash(state));
00232 }
00233 
00234 inline bool StateSet::Exists(const HexState& state) const
00235 {
00236     return m_set.count(GetHash(state)) > 0;
00237 }
00238 
00239 inline std::size_t StateSet::Size() const
00240 {
00241     return m_set.size();
00242 }
00243 
00244 //----------------------------------------------------------------------------
00245 
00246 /** Map of positions; handles rotations. */
00247 template<class T>
00248 class StateMap
00249 {
00250 public:
00251     StateMap();
00252 
00253     ~StateMap();
00254 
00255     bool Exists(const HexState& state) const;
00256 
00257     T& operator[](const HexState& state);
00258 
00259     std::size_t Size() const;
00260 
00261 private:
00262     std::map<hash_t, T> m_map;
00263 };
00264 
00265 template<class T>
00266 inline StateMap<T>::StateMap()
00267 {
00268 }
00269 
00270 template<class T>
00271 inline StateMap<T>::~StateMap()
00272 {
00273 }
00274 
00275 template<class T>
00276 bool StateMap<T>::Exists(const HexState& state) const
00277 {
00278     return m_map.find(GetHash(state)) != m_map.end();
00279 }
00280 
00281 template<class T>
00282 inline T& StateMap<T>::operator[](const HexState& state)
00283 {
00284     return m_map[GetHash(state)];
00285 }
00286 
00287 template<class T>
00288 inline std::size_t StateMap<T>::Size() const
00289 {
00290     return m_map.size();
00291 }
00292 
00293 //----------------------------------------------------------------------------
00294 
00295 _END_BENZENE_NAMESPACE_
00296 
00297 #endif // POSITIONDB_HPP
00298 


6 Jan 2011 Doxygen 1.6.3