2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 uint64_t pawn_hash_mask
;
22 uint64_t main_hash_mask
;
24 struct pawn_hash_entry_t
*pawn_hash
[2];
25 struct main_hash_entry_t
*main_hash
;
27 uint16_t hashtable_age
;
30 initialize_main_hashtable(void)
36 if (!e
.main_hash_size
|| !e
.main_hash_enabled
)
41 max_elements
= (e
.main_hash_size
* 1024 * 1024 / 4) / \
42 sizeof(struct main_hash_entry_t
);
44 /* calculate hashmask */
45 while (max_elements
>>= 1)
46 main_hash_mask
= (main_hash_mask
<< 1) | 1;
49 if (!(main_hash
= malloc(4 * (main_hash_mask
+ 1) * \
50 sizeof(struct main_hash_entry_t
))))
54 fprintf(stdout
, "Allocated main hashtable: %lluk entries, %lluMB\n",
55 (4 * main_hash_mask
) >> 10, (4 * main_hash_mask
*
56 sizeof(struct main_hash_entry_t
)) >> 20);
63 initialize_pawn_hashtable(void)
70 if (!e
.pawn_hash_size
|| !e
.pawn_hash_enabled
)
77 max_elements
= (e
.pawn_hash_size
* 1024 * 1024 / 2) / \
78 sizeof(struct pawn_hash_entry_t
);
80 /* calculate hashmask */
81 while (max_elements
>>= 1)
82 pawn_hash_mask
= (pawn_hash_mask
<< 1) | 1;
85 if (!(pawn_hash
[WHITE
] = malloc((pawn_hash_mask
+ 1) * \
86 sizeof(struct pawn_hash_entry_t
))))
88 if (!(pawn_hash
[BLACK
] = malloc((pawn_hash_mask
+ 1) * \
89 sizeof(struct pawn_hash_entry_t
)))) {
90 free(pawn_hash
[WHITE
]);
95 fprintf(stdout
, "Allocated pawn hashtable: %lluk entries, %lluMB\n",
96 (2 * pawn_hash_mask
) >> 10, (2 * pawn_hash_mask
*
97 sizeof(struct pawn_hash_entry_t
)) >> 20);
103 hashtable_get(int side
, int depth
, int ply
, int *move
, int *score
)
108 struct main_hash_entry_t
*mhe
;
111 mhe
= main_hash
+ (brd
.hash_key
& main_hash_mask
) * 4;
113 for (i
= 0; i
< 4; i
++, mhe
++) {
114 if (mhe
->key
== brd
.hash_key
) {
125 entry_depth
= (mhe
->mdf
>> 21) & 0xFF;
126 *move
= mhe
->mdf
& 0x1FFFFF;
128 if (entry_depth
< depth
)
133 if (SCORE_IS_MATE(*score
))
134 *score
+= *score
> 0 ? -ply
: ply
;
136 return mhe
->mdf
>> 29;
140 hashtable_put(int side
, int depth
, int ply
, int flag
, int move
, int score
)
145 struct main_hash_entry_t
*mhe
;
146 struct main_hash_entry_t
*replace
;
148 mhe
= main_hash
+ (brd
.hash_key
& main_hash_mask
) * 4;
151 for (i
= 0; i
< 4; i
++, mhe
++) {
152 if (mhe
->key
== brd
.hash_key
) {
153 mhe
->mdf
= move
| (depth
<< 21) | (flag
<< 29);
156 if (SCORE_IS_MATE(score
))
157 mhe
->score
+= score
> 0 ? ply
: -ply
;
161 entry_depth
= (mhe
->mdf
>> 21) & 0xFF;
162 replace_depth
= (replace
->mdf
>> 21) & 0xFF;
164 if (replace
->age
== hashtable_age
) {
165 if (mhe
->age
!= hashtable_age
|| entry_depth
< replace_depth
)
167 } else if (mhe
->age
!= hashtable_age
&& entry_depth
< replace_depth
)
171 replace
->key
= brd
.hash_key
;
172 replace
->score
= score
;
173 replace
->mdf
= move
| (depth
<< 21) | (flag
<< 29);
175 if (SCORE_IS_MATE(score
))
176 replace
->score
+= score
> 0 ? ply
: -ply
;
180 free_main_hashtable(void)
186 free_pawn_hashtable(void)
188 free(pawn_hash
[WHITE
]);
189 free(pawn_hash
[BLACK
]);
192 /* clear hashtables */
194 clear_main_hashtable(void)
199 memset(main_hash
, 0, 4 * (main_hash_mask
+ 1) * \
200 sizeof(struct main_hash_entry_t
));
204 clear_pawn_hashtable(void)
206 if (pawn_hash
[WHITE
])
207 memset(pawn_hash
[WHITE
], 0, (pawn_hash_mask
+ 1) * \
208 sizeof(struct pawn_hash_entry_t
));
209 if (pawn_hash
[BLACK
])
210 memset(pawn_hash
[BLACK
], 0, (pawn_hash_mask
+ 1) * \
211 sizeof(struct pawn_hash_entry_t
));