TransTable.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #ifndef TRANSTABLE_H
00007 #define TRANSTABLE_H
00008
00009 #include <boost/concept_check.hpp>
00010
00011 #include "Hex.hpp"
00012
00013 _BEGIN_BENZENE_NAMESPACE_
00014
00015
00016
00017
00018 template<class T>
00019 struct TransTableStateConcept
00020 {
00021 void constraints()
00022 {
00023 boost::function_requires< boost::DefaultConstructibleConcept<T> >();
00024 boost::function_requires< boost::AssignableConcept<T> >();
00025
00026 const T a;
00027 if (a.Initialized()) { }
00028
00029 const T b;
00030 if (a.ReplaceWith(b)) { }
00031 }
00032 };
00033
00034
00035
00036
00037
00038 template<class T>
00039 class TransTable
00040 {
00041 BOOST_CLASS_REQUIRE(T, benzene, TransTableStateConcept);
00042
00043 public:
00044
00045
00046 TransTable(int bits);
00047
00048
00049 ~TransTable();
00050
00051
00052 std::size_t Bits() const;
00053
00054
00055 std::size_t Size() const;
00056
00057
00058 void Clear();
00059
00060
00061
00062
00063 bool Put(hash_t hash, const T& data);
00064
00065
00066
00067
00068
00069 bool Get(hash_t hash, T& data);
00070
00071
00072 std::string Stats() const;
00073
00074 private:
00075
00076
00077
00078 struct Statistics
00079 {
00080 unsigned reads;
00081 unsigned hits;
00082 unsigned writes;
00083 unsigned overwrites;
00084
00085 Statistics() : reads(0), hits(0), writes(0), overwrites(0) { }
00086 };
00087
00088
00089
00090 int m_bits;
00091
00092 std::size_t m_size;
00093
00094 std::size_t m_mask;
00095
00096 std::vector<T> m_data;
00097
00098 std::vector<hash_t> m_hash;
00099
00100 Statistics m_stats;
00101 };
00102
00103
00104
00105 template<typename T>
00106 TransTable<T>::TransTable(int bits)
00107 : m_bits(bits),
00108 m_size(1 << bits),
00109 m_mask(m_size - 1),
00110 m_data(m_size),
00111 m_hash(m_size, 0),
00112 m_stats()
00113 {
00114 Clear();
00115 }
00116
00117 template<typename T>
00118 TransTable<T>::~TransTable()
00119 {
00120 }
00121
00122 template<typename T>
00123 inline std::size_t TransTable<T>::Bits() const
00124 {
00125 return m_bits;
00126 }
00127
00128 template<typename T>
00129 inline std::size_t TransTable<T>::Size() const
00130 {
00131 return m_size;
00132 }
00133
00134 template<typename T>
00135 inline void TransTable<T>::Clear()
00136 {
00137 for (std::size_t i = 0; i < m_size; ++i)
00138 {
00139 m_data[i] = T();
00140 m_hash[i] = 0;
00141 }
00142 }
00143
00144 template<typename T>
00145 bool TransTable<T>::Put(hash_t hash, const T& data)
00146 {
00147 std::size_t slot = hash & m_mask;
00148 if (m_data[slot].ReplaceWith(data))
00149 {
00150 m_stats.writes++;
00151 if (m_hash[slot] && m_hash[slot] != hash)
00152 m_stats.overwrites++;
00153 m_data[slot] = data;
00154 m_hash[slot] = hash;
00155 }
00156 return true;
00157 }
00158
00159 template<typename T>
00160 bool TransTable<T>::Get(hash_t hash, T& data)
00161 {
00162 m_stats.reads++;
00163 std::size_t slot = hash & m_mask;
00164 T& old = m_data[slot];
00165 bool ret = old.Initialized() && (m_hash[slot] == hash);
00166 if (ret)
00167 {
00168 data = old;
00169 m_stats.hits++;
00170 }
00171 return ret;
00172 }
00173
00174 template<typename T>
00175 std::string TransTable<T>::Stats() const
00176 {
00177 std::ostringstream os;
00178 os << "TT statistics\n"
00179 << "Reads " << m_stats.reads << '\n'
00180 << "Hits " << m_stats.hits << '\n'
00181 << "Writes " << m_stats.writes << '\n'
00182 << "Overwrites " << m_stats.overwrites << '\n';
00183 return os.str();
00184 }
00185
00186
00187
00188 _END_BENZENE_NAMESPACE_
00189
00190 #endif // TRANSTABLE_H