示例#1
0
文件: cache.c 项目: Fierralin/gnugo
int
tt_get(Transposition_table *table, 
       enum routine_id routine, 
       int target1, int target2, int remaining_depth,
       Hash_data *extra_hash,
       int *value1, int *value2, int *move)
{
  Hash_data hashval;
  Hashentry *entry;
  Hashnode *node;
 
  /* Sanity check. */
  if (remaining_depth < 0 || remaining_depth > HN_MAX_REMAINING_DEPTH)
    return 0;

  /* Get the combined hash value. */
  calculate_hashval_for_tt(&hashval, routine, target1, target2, extra_hash);

  /* Get the correct entry and node. */
  entry = &table->entries[hashdata_remainder(hashval, table->num_entries)];
  if (hashdata_is_equal(hashval, entry->deepest.key))
    node = &entry->deepest;
  else if (hashdata_is_equal(hashval, entry->newest.key))
    node = &entry->newest;
  else
    return 0;

  stats.read_result_hits++;

  /* Return data.  Only set the result if remaining depth in the table
   * is big enough to be trusted.  The move can always be used for move
   * ordering if nothing else.
   */
  if (move)
    *move = hn_get_move(node->data);
  if (remaining_depth <= (int) hn_get_remaining_depth(node->data)) {
    if (value1)
      *value1 = hn_get_value1(node->data);
    if (value2)
      *value2 = hn_get_value2(node->data);
    stats.trusted_read_result_hits++;
    return 2;
  }

  return 1;
}
示例#2
0
/* Find a cache entry matching the data given in the parameters.
 * Important: We assume that unused parameters are normalized to NO_MOVE
 * when storing or retrieving, so that we can ignore them here.
 */ 
static struct persistent_cache_entry *
find_persistent_cache_entry(struct persistent_cache *cache,
			    enum routine_id routine, int apos, int bpos,
			    int cpos, Hash_data *goal_hash, int node_limit)
{
  int k;
  for (k = 0; k < cache->current_size; k++) {
    struct persistent_cache_entry *entry = cache->table + k;
    if (entry->routine == routine
	&& entry->apos == apos
	&& entry->bpos == bpos
	&& entry->cpos == cpos
        && depth - stackp <= entry->remaining_depth
        && (entry->node_limit >= node_limit || entry->result_certain)
        && (goal_hash == NULL
	    || hashdata_is_equal(entry->goal_hash, *goal_hash))
        && verify_stored_board(entry->board))
      return entry;
  }
  return NULL;
}
示例#3
0
文件: cache.c 项目: Fierralin/gnugo
void
tt_update(Transposition_table *table,
	  enum routine_id routine, int target1, int target2,
	  int remaining_depth, Hash_data *extra_hash, 
	  int value1, int value2, int move)
{
  Hash_data hashval;
  Hashentry *entry;
  Hashnode *deepest;
  Hashnode *newest;
  unsigned int data;
  /* Get routine costs definitions from liberty.h. */
  static const int routine_costs[] = { ROUTINE_COSTS };
  gg_assert(routine_costs[NUM_CACHE_ROUTINES] == -1);

  /* Sanity check. */
  if (remaining_depth < 0 || remaining_depth > HN_MAX_REMAINING_DEPTH)
    return;

  /* Get the combined hash value. */
  calculate_hashval_for_tt(&hashval, routine, target1, target2, extra_hash);

  data = hn_create_data(remaining_depth, value1, value2, move,
      		        routine_costs[routine]);

  /* Get the entry and nodes. */ 
  entry = &table->entries[hashdata_remainder(hashval, table->num_entries)];
  deepest = &entry->deepest;
  newest  = &entry->newest;
 
  /* See if we found an already existing node. */
  if (hashdata_is_equal(hashval, deepest->key)
      && remaining_depth >= (int) hn_get_remaining_depth(deepest->data)) {

    /* Found deepest */
    deepest->data = data;

  }
  else if (hashdata_is_equal(hashval, newest->key)
           && remaining_depth >= (int) hn_get_remaining_depth(newest->data)) {

    /* Found newest */
    newest->data = data;

    /* If newest has become deeper than deepest, then switch them. */
    if (hn_get_remaining_depth(newest->data)
	> hn_get_remaining_depth(deepest->data)) {
      Hashnode temp;

      temp = *deepest;
      *deepest = *newest;
      *newest = temp;
    }

  }
  else if (hn_get_total_cost(data) > hn_get_total_cost(deepest->data)) {
    if (hn_get_total_cost(newest->data) < hn_get_total_cost(deepest->data))
      *newest = *deepest;
    deepest->key  = hashval;
    deepest->data = data;
  } 
  else {
    /* Replace newest. */
    newest->key  = hashval;
    newest->data = data;
  }

  stats.read_result_entered++;
  table->is_clean = 0;
}