StateDB.hpp
Go to the documentation of this file.00001
00002
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
00029 inline bool NeedToRotate(const HexState& state, hash_t minHash)
00030 {
00031 return state.Hash() != minHash;
00032 }
00033
00034 }
00035
00036
00037
00038
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
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
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
00087 StateDB(const std::string& filename, const std::string& type);
00088
00089
00090 ~StateDB();
00091
00092
00093 bool Exists(const HexState& pos) const;
00094
00095
00096 bool Get(const HexState& pos, T& data) const;
00097
00098
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
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
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