void trans_alloc(trans_t * trans) { uint32 size, target; ASSERT(trans!=NULL); // calculate size target = option_get_int("Hash"); if (target < 4) target = 16; target *= 1024 * 1024; for (size = 1; size != 0 && size <= target; size *= 2) ; size /= 2; ASSERT(size>0&&size<=target); // allocate table size /= sizeof(entry_t); ASSERT(size!=0&&(size&(size-1))==0); // power of 2 trans->size = size + (ClusterSize - 1); // HACK to avoid testing for end of table trans->mask = size - 1; trans->table = (entry_t *) my_malloc(trans->size*sizeof(entry_t)); trans_clear(trans); ASSERT(trans_is_ok(trans)); }
void trans_free(trans_t * trans) { ASSERT(trans_is_ok(trans)); my_free(trans->table); trans->table = NULL; trans->size = 0; trans->mask = 0; }
void trans_stats(const trans_t * trans) { double full; // double hit, collision; ASSERT(trans_is_ok(trans)); full = double(trans->used) / double(trans->size); // hit = double(trans->read_hit) / double(trans->read_nb); // collision = double(trans->write_collision) / double(trans->write_nb); send("info hashfull %.0f",full*1000.0); }
static entry_t * trans_entry(trans_t * trans, uint64 key) { uint32 index; ASSERT(trans_is_ok(trans)); if (UseModulo) { index = KEY_INDEX(key) % (trans->mask + 1); } else { index = KEY_INDEX(key) & trans->mask; } ASSERT(index<=trans->mask); return &trans->table[index]; }
bool trans_retrieve(trans_t * trans, uint64 key, int * move, int * min_depth, int * max_depth, int * min_value, int * max_value) { entry_t * entry; int i; ASSERT(trans_is_ok(trans)); ASSERT(move!=NULL); ASSERT(min_depth!=NULL); ASSERT(max_depth!=NULL); ASSERT(min_value!=NULL); ASSERT(max_value!=NULL); // init trans->read_nb++; // probe entry = trans_entry(trans,key); for (i = 0; i < ClusterSize; i++, entry++) { if (entry->lock == KEY_LOCK(key) /*^ entry->key1 ^ entry->key2 ^ entry->key3*/) { // found trans->read_hit++; if (entry->date != trans->date) { entry->date = trans->date; entry->lock == KEY_LOCK(key) /*^ entry->key1 ^ entry->key2 ^ entry->key3*/; } *move = entry->move; *min_depth = entry->min_depth; *max_depth = entry->max_depth; *min_value = entry->min_value; *max_value = entry->max_value; return true; } } // not found return false; }
void trans_store(trans_t * trans, uint64 key, int move, int depth, int min_value, int max_value) { entry_t * entry, * best_entry; int score, best_score; int i; ASSERT(trans_is_ok(trans)); ASSERT(move>=0&&move<65536); ASSERT(depth>=-127&&depth<=+127); ASSERT(min_value>=-ValueInf&&min_value<=+ValueInf); ASSERT(max_value>=-ValueInf&&max_value<=+ValueInf); ASSERT(min_value<=max_value); // init trans->write_nb++; // probe best_entry = NULL; best_score = -32767; entry = trans_entry(trans,key); for (i = 0; i < ClusterSize; i++, entry++) { if (entry->lock == KEY_LOCK(key)) { // hash hit => update existing entry trans->write_hit++; if (entry->date != trans->date) trans->used++; entry->date = trans->date; if (trans_endgame || depth > entry->depth) entry->depth = depth; /* if (depth > entry->depth) entry->depth = depth; // for replacement scheme */ // if (move != MoveNone /* && depth >= entry->move_depth */) { if (move != MoveNone && (trans_endgame || depth >= entry->move_depth)) { entry->move_depth = depth; entry->move = move; } // if (min_value > -ValueInf /* && depth >= entry->min_depth */) { if (min_value > -ValueInf && (trans_endgame || depth >= entry->min_depth)) { entry->min_depth = depth; entry->min_value = min_value; } // if (max_value < +ValueInf /* && depth >= entry->max_depth */) { if (max_value < +ValueInf && (trans_endgame || depth >= entry->max_depth)) { entry->max_depth = depth; entry->max_value = max_value; } ASSERT(entry_is_ok(entry)); return; } // evaluate replacement score score = trans->age[entry->date] * 256 - entry->depth; ASSERT(score>-32767); if (score > best_score) { best_entry = entry; best_score = score; } } // "best" entry found entry = best_entry; ASSERT(entry!=NULL); ASSERT(entry->lock!=KEY_LOCK(key)); if (entry->date == trans->date) { trans->write_collision++; } else { trans->used++; } // store ASSERT(entry!=NULL); entry->lock = KEY_LOCK(key); entry->date = trans->date; entry->depth = depth; entry->move_depth = (move != MoveNone) ? depth : DepthNone; entry->move = move; entry->min_depth = (min_value > -ValueInf) ? depth : DepthNone; entry->max_depth = (max_value < +ValueInf) ? depth : DepthNone; entry->min_value = min_value; entry->max_value = max_value; ASSERT(entry_is_ok(entry)); }