ntesukiTable.h Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
ntesukiTable.h
Go to the documentation of this file.
1 #ifndef _PD_NTESUKI_TABLE_H
2 #define _PD_NTESUKI_TABLE_H
3 #include "osl/ntesuki/ntesukiRecord.h"
4 #include "osl/ntesuki/ntesukiMove.h"
5 #include "osl/misc/carray.h"
6 #include "osl/stl/hash_set.h"
7 #include "osl/pathEncoding.h"
8 #include "osl/hash/hashKey.h"
9 #include "osl/stl/hash_map.h"
10 #include "osl/stl/slist.h"
11 #include <boost/scoped_ptr.hpp>
12 #include <stdexcept>
13
14 namespace osl
15 {
16 namespace stl
17 {
18 template <>
19 struct hash<Square>{
20 unsigned long operator()(const Square& p) const
21 {
22 return p.uintValue();
23 }
24 };
25 }
26
27 namespace ntesuki
28 {
32 struct TableFull : std::runtime_error
33 {
34 TableFull() : std::runtime_error("table full")
35 {
36 }
37 };
38
43 struct RootStateNotSet : std::runtime_error
44 {
45 RootStateNotSet () : std::runtime_error("root node not set")
46 {
47 }
48 };
52 class NtesukiTable
53 {
54 private:
55 typedef hash_map<SignatureKey, NtesukiRecord::RecordList> ntesuki_hash_map;
56
57 public:
58 class Table : public ntesuki_hash_map
59 {
60 public:
61 unsigned int capacity, default_gc_size;
62 bool verbose, no_gc, gc_request;
63 unsigned int numEntry, numCacheHit, gcCount;
64 NtesukiRecord *root;
65 boost::scoped_ptr<NumEffectState> rootState;
66 static int largeGCCount;
67
68 Table(unsigned int capacity,
69 unsigned int default_gc_size,
70 bool verbose);
71
72 ~Table();
73
81 NtesukiRecord *allocate(const HashKey& key,
82 const PieceStand& white_stand,
83 signed short distance);
84
91 NtesukiRecord *find(const HashKey& key);
92
96 void erase(const HashKey key);
97
101 template <class F> void forEachRecord(F& f);
102 template <class F> void forEachRecordFrom(F&,
103 NumEffectState&,
104 NtesukiRecord *);
105 template <class F> void forEachRecordFromRoot(F& f);
106
111 void collectGarbage(unsigned int gc_size);
112 };
113
114
115 private:
116 boost::scoped_ptr<Table> table;
117 bool verbose;
118
119 public:
120 typedef NtesukiRecord record_t;
121
122 struct HashPathEncoding
123 {
124 unsigned long operator()(PathEncoding const& pe) const
125 {
126 return pe.getPath();
127 }
128 };
129 typedef hash_set<PathEncoding, HashPathEncoding> PathSet;
130
131 std::vector<int> depths;
132
136 NtesukiTable(unsigned int capacity,
137 unsigned int default_gc_size=0,
138 bool verbose=false);
139 ~NtesukiTable();
140
141 void clear()
142 {
143 table->clear();
144 }
145
146 Table::const_iterator begin() const
147 {
148 return table->begin();
149 }
150 Table::const_iterator end() const
151 {
152 return table->end();
153 }
154
160 NtesukiRecord *allocateRoot(const HashKey& key,
161 const PieceStand& white_stand,
162 signed short distance,
163 const NumEffectState* root_state = NULL)
164 {
165 table->root = table->allocate(key, white_stand, distance);
166 if (root_state)
167 {
168 table->rootState.reset(new NumEffectState(*root_state));
169 }
170 return table->root;
171 }
172
173 NtesukiRecord *allocateWithMove(NtesukiRecord* record,
174 const NtesukiMove& move)
175 {
176 /* 毎回 white stand を計算しているのは無駄 */
177 PieceStand white_stand = record->white_stand;
178 const Move m = move.getMove();
179 if (!move.isPass() && m.player())
180 {
181 if (m.isDrop())
182 {
183 white_stand.sub(m.ptype());
184 }
185 else if (m.capturePtype() != PTYPE_EMPTY)
186 {
187 white_stand.add(unpromote(m.capturePtype()));
188 }
189 }
190 unsigned short child_distance = record->distance + 1;
191 NtesukiRecord *child = table->allocate(record->key.newHashWithMove(m),
192 white_stand, child_distance);
193 if (child)
194 {
195 child->distance = std::min(child->distance, child_distance);
196 child->checkNewParent(record);
197 }
198 return child;
199 }
200
204 NtesukiRecord *find(const HashKey& key)
205 {
206 return table->find(key);
207 }
208
209 const NtesukiRecord *find(const HashKey& key) const
210 {
211 return table->find(key);
212 }
213
217 void erase(const HashKey key)
218 {
219 table->erase(key);
220 }
221
225 void collectGarbage(unsigned int gc_size)
226 {
227 table->collectGarbage(gc_size);
228 }
229
234 NtesukiRecord *findWithMove(NtesukiRecord *record,
235 const NtesukiMove& move)
236 {
237 /* テーブルを調べ，あったら move に登録しておく
238 *
239 * (関係ないところから持ってきた move だと
240 * record にない piece を drop する可能性が)
241 */
242 if (move.isNormal() && move.isDrop())
243 {
244 const Ptype drop_type = unpromote(move.getMove().ptype());
245 const PieceStand ps = record->getPieceStandSlow(move.getMove()
246 .player());
247 if (ps.get(drop_type) == 0)
248 {
249 return NULL;
250 }
251 }
252 NtesukiRecord *child = table->find(record->key.newHashWithMove(move.getMove()));
253 if (child)
254 {
255 child->checkNewParent(record);
256 }
257 return child;
258 }
259
260 NtesukiRecord *findWithMoveConst(const NtesukiRecord *record,
261 const NtesukiMove& move)
262 {
263 /* テーブルを調べ，あったら move に登録しておく
264 *
265 * (関係ないところから持ってきた move だと
266 * record にない piece を drop する可能性が)
267 */
268 if (move.isNormal() && move.isDrop())
269 {
270 const Ptype drop_type = unpromote(move.getMove().ptype());
271 const PieceStand ps = record->getPieceStandSlow(move.getMove()
272 .player());
273 if (ps.get(drop_type) == 0)
274 {
275 return NULL;
276 }
277 }
278 return table->find(record->key.newHashWithMove(move.getMove()));
279 }
280
284 template <class F> void forEachRecord(F& f)
285 {
286 table->forEachRecord<F>(f);
287 }
288
292 template <class F> void forEachRecordFromRoot(F& f)
293 {
294 table->forEachRecordFromRoot<F>(f);
295 }
296
300 unsigned int size() const
301 {
302 return table->numEntry;/* not size() */
303 }
304
305 unsigned int capacity() const
306 {
307 return table->capacity;
308 }
309
310 void lockGC()
311 {
312 table->no_gc = true;
313 }
314
315 void unlockGC()
316 {
317 table->no_gc = false;
318 if (table->gc_request && (table->default_gc_size > 0))
319 {
320 table->collectGarbage(table->default_gc_size);
321 table->gc_request = false;
322 }
323 }
324
325 bool isVerbose() const;
326 };
327 } //ntesuki
328 }// osl
329
330 #endif /* _PD_NTESUKI_TABLE_H */
331 // ;;; Local Variables:
332 // ;;; mode:c++
333 // ;;; c-basic-offset:2
334 // ;;; End: