Index: engine/cache.c =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/cache.c,v retrieving revision 1.41 diff -u -r1.41 cache.c --- engine/cache.c 19 May 2004 14:24:06 -0000 1.41 +++ engine/cache.c 22 May 2004 20:14:45 -0000 @@ -35,11 +35,14 @@ /* ================================================================ */ -/* The new transposition table */ +/* The transposition table */ /* ---------------------------------------------------------------- */ +static void tt_init(Transposition_table *table, int memsize); +static void tt_clear(Transposition_table *table); + /* The transposition table itself. */ -Transposition_table ttable; +Transposition_table ttable; static Hash_data komaster_hash[NUM_KOMASTER_STATES]; static Hash_data kom_pos_hash[BOARDMAX]; @@ -55,7 +58,8 @@ {kom_pos_hash, BOARDMAX}, {target1_hash, BOARDMAX}, {target2_hash, BOARDMAX}, - {routine_hash, NUM_CACHE_ROUTINES} + {routine_hash, NUM_CACHE_ROUTINES}, + {NULL, 0} }; /* Initialize random hash values identifying input data (other than the @@ -64,23 +68,16 @@ static void keyhash_init(void) { - static int is_initialized = 0; - Hash_data *array; - int size; - unsigned i; - int j; + static int is_initialized = 0; + Hash_data *array; + int size; + int i; + int j; if (is_initialized) return; -#if TRACE_READ_RESULTS - /* We need consistent hash values when this option is enabled. */ - gg_srand(1); -#endif - - for (i = 0; - i < sizeof(hash_init_values) / sizeof(struct init_struct); - i++) { + for (i = 0; hash_init_values[i].array != NULL; i++) { array = hash_init_values[i].array; size = hash_init_values[i].array_size; @@ -107,26 +104,20 @@ /* Initialize the transposition table. */ - -void + +static void tt_init(Transposition_table *table, int memsize) { - int num_entries; + int num_entries; /* Make sure the hash system is initialized. */ hash_init(); keyhash_init(); - num_entries = memsize / sizeof(Hashentry_ng); + num_entries = memsize / sizeof(table->entries[0]); -#if 0 - printf("Creating hash table of size double entries (%d bytes)\n", - bits, size); -#endif - table->num_entries = num_entries; - table->entries = (Hashentry_ng *) malloc(num_entries - * sizeof(Hashentry_ng)); + table->entries = malloc(num_entries * sizeof(table->entries[0])); if (table->entries == NULL) { perror("Couldn't allocate memory for transposition table. \n"); @@ -138,14 +129,13 @@ } -/* Clear the transposition table. - */ +/* Clear the transposition table. */ -void +static void tt_clear(Transposition_table *table) { - Hashentry_ng hash_null = {{hashdata_NULL, 0}, {hashdata_NULL, 0}}; - unsigned i; + Hashentry hash_null = {{hashdata_NULL, 0}, {hashdata_NULL, 0}}; + unsigned int i; if (table->is_clean) return; @@ -157,8 +147,7 @@ } -/* Free the transposition table. - */ +/* Free the transposition table. */ void tt_free(Transposition_table *table) @@ -181,9 +170,9 @@ Hash_data *extra_hash, int *value1, int *value2, int *move) { - Hash_data hashval; - Hashentry_ng *entry; - Hashnode_ng *node; + Hash_data hashval; + Hashentry *entry; + Hashnode *node; /* Get the combined hash value. */ calculate_hashval_for_tt(routine, target1, target2, &hashval); @@ -235,9 +224,9 @@ int value1, int value2, int move) { Hash_data hashval; - Hashentry_ng *entry; - Hashnode_ng *deepest; - Hashnode_ng *newest; + Hashentry *entry; + Hashnode *deepest; + Hashnode *newest; unsigned int data; /* Get routine costs definitions from cache.h. */ static const int routine_costs[] = { ROUTINE_COSTS }; @@ -278,7 +267,7 @@ /* If newest has become deeper than deepest, then switch them. */ if (hn_get_remaining_depth(newest->data) > hn_get_remaining_depth(deepest->data)) { - Hashnode_ng temp; + Hashnode temp; temp = *deepest; *deepest = *newest; @@ -315,593 +304,6 @@ } - -/* ================================================================ */ -/* The old transposition table */ - - -#if !USE_HASHTABLE_NG - -static Hashtable *movehash; - -static int hashtable_init(Hashtable *table, int tablesize, int num_nodes, - int num_results); -static Hashtable *hashtable_new(int tablesize, int num_nodes, int num_results); -static void hashtable_clear(Hashtable *table); - -static Hashnode *hashtable_enter_position(Hashtable *table, Hash_data *hd); -static Hashnode *hashtable_search(Hashtable *table, Hash_data *hd); - -static Read_result *hashnode_search(Hashnode *node, - unsigned int query_data1, - unsigned int query_data2); -static Read_result *hashnode_new_result(Hashtable *table, Hashnode *node, - unsigned int input_data1, - unsigned int input_data2); - -static void hashnode_unlink_closed_results(Hashnode *node, - int exclusions, - unsigned int remaining_depth_limit, - int statistics[][20]); -static void hashtable_partially_clear(Hashtable *table); -static int do_get_read_result(enum routine_id routine, - int str1, int str2, Read_result **read_result, - Hash_data *hashmodifier); - - -/* - * Dump an ASCII representation of the contents of a Read_result onto - * the FILE outfile. - */ -void -read_result_dump(Read_result *result, FILE *outfile) -{ - fprintf(outfile, "Komaster %u (%d, %d) Routine %u, (%d, %d), depth: %u ", - rr_get_komaster(*result), - I(rr_get_kom_pos(*result)), - J(rr_get_kom_pos(*result)), - rr_get_routine(*result), - I(rr_get_str(*result)), - J(rr_get_str(*result)), - rr_get_remaining_depth(*result)); - fprintf(outfile, "Result: %u %u, (%d, %d)\n", - rr_get_status(*result), - rr_get_result(*result), - I(rr_get_move(*result)), - J(rr_get_move(*result))); -} - - -/* - * Dump an ASCII representation of the contents of a Hashnode onto - * the FILE outfile. - */ - -void -hashnode_dump(Hashnode *node, FILE *outfile) -{ - Read_result *result; - - /* Data about the node itself. */ - fprintf(outfile, "Hash value: %lx\n", (unsigned long) node->key.hashval); - - for (result = node->results; result != NULL; result = result->next) { - read_result_dump(result, outfile); - } - /* FIXME: Dump contents of data also. */ -} - - -/* - * Dump an ASCII representation of the contents of a Hashtable onto - * the FILE outfile. - */ - -void -hashtable_dump(Hashtable *table, FILE *outfile) -{ - int i; - Hashnode *hn; - - /* Data about the table itself. */ - fprintf(outfile, "Dump of hashtable\n"); - fprintf(outfile, "Total size: %d\n", (int) (table->node_limit - - table->all_nodes)); - fprintf(outfile, "Size of hash table: %d\n", table->hashtablesize); - fprintf(outfile, "Number of positions in table: %d\n", - (int) (table->free_node - table->all_nodes)); - - /* Data about the contents. */ - for (i = 0; i < table->hashtablesize; ++i) { - fprintf(outfile, "Bucket %5d: ", i); - hn = table->hashtable[i]; - if (hn == NULL) - fprintf(outfile, "empty"); - else - while (hn) { - hashnode_dump(hn, outfile); - hn = hn->next; - } - fprintf(outfile, "\n"); - } -} - - -#if 0 -/* - * Dump an alternative representation of the contents of a Hashtable - * onto the FILE outfile. This one is mainly useful if you have to - * debug the hashtable implementation itself. - */ - -static void -hashtable_dump2(Hashtable *table, FILE *outfile) -{ - int i; - Hashnode *node; - Read_result *result; - - for (i = 0; i < table->hashtablesize; i++) { - fprintf(outfile, "bucket %d: ", i); - if (table->hashtable[i] == NULL) - fprintf(outfile, "NULL\n"); - else - fprintf(outfile, "%d\n", table->hashtable[i] - table->all_nodes); - } - - for (node = table->all_nodes; node < table->node_limit; node++) { - if (node->results == NULL) - continue; - fprintf(outfile, "node %d: ", i); - if (node->results == NULL) - fprintf(outfile, "NULL "); - else - fprintf(outfile, "%d ", node->results - table->all_results); - if (node->next == NULL) - fprintf(outfile, "NULL\n"); - else - fprintf(outfile, "%d\n", node->next - table->all_nodes); - } - - for (result = table->all_results; result < table->result_limit; result++) { - if (rr_get_status(*result) == 0) - continue; - fprintf(outfile, "result %d ", i); - if (result->next == NULL) - fprintf(outfile, "NULL "); - else - fprintf(outfile, "%d ", result->next - table->all_results); - read_result_dump(result, outfile); - } -} -#endif - - -/* - * Initialize a hash table for a given total size and size of the - * hash table. - * - * Return 0 if something went wrong. Just now this means that there - * wasn't enough memory available. - */ - -static int -hashtable_init(Hashtable *table, - int tablesize, int num_nodes, int num_results) -{ - /* Make sure the hash system is initialized. */ - hash_init(); - - /* Allocate memory for the pointers in the hash table proper. */ - table->hashtablesize = tablesize; - table->hashtable = (Hashnode **) malloc(tablesize * sizeof(Hashnode *)); - if (table->hashtable == NULL) { - free(table); - return 0; - } - - /* Allocate memory for the nodes. */ - table->all_nodes = (Hashnode *) malloc(num_nodes * sizeof(Hashnode)); - if (table->all_nodes == NULL) { - free(table->hashtable); - free(table); - return 0; - } - table->node_limit = table->all_nodes + num_nodes; - - /* Allocate memory for the results. */ - table->all_results = (Read_result *) malloc(num_results - * sizeof(Read_result)); - if (table->all_results == NULL) { - free(table->hashtable); - free(table->all_nodes); - free(table); - return 0; - } - table->result_limit = table->all_results + num_results; - - /* Force complete table clearing. */ - table->first_pass = 0; - hashtable_clear(table); - - return 1; -} - - -/* - * Allocate a new hash table and return a pointer to it. - * - * Return NULL if there is insufficient memory. - */ - -static Hashtable * -hashtable_new(int tablesize, int num_nodes, int num_results) -{ - Hashtable *table; - - /* Make sure the hash system is initialized. */ - hash_init(); - - /* Allocate the hashtable struct. */ - table = (Hashtable *) malloc(sizeof(Hashtable)); - if (table == NULL) - return NULL; - - /* Initialize the table. */ - if (!hashtable_init(table, tablesize, num_nodes, num_results)) { - free(table); - return NULL; - } - - return table; -} - - -/* - * Clear an existing hash table. - */ - -static void -hashtable_clear(Hashtable *table) -{ - int bucket; - Hashnode *node; - Hashnode *node_limit; - Read_result *result; - Read_result *result_limit; - - if (!table) - return; - - /* If the table is alredy clean, return immediatly. */ - if (table->first_pass && table->free_node == table->all_nodes) - return; - - /* Initialize all hash buckets to the empty list. */ - for (bucket = 0; bucket < table->hashtablesize; ++bucket) - table->hashtable[bucket] = NULL; - - /* Mark all nodes as free. Don't clean non-allocated nodes. */ - node_limit = table->first_pass ? table->free_node : table->node_limit; - table->free_node = table->all_nodes; - for (node = table->all_nodes; node < node_limit; node++) - node->results = NULL; - - /* Mark all read_results as free. Don't clean non-allocated results. */ - result_limit = table->first_pass ? table->free_result : table->result_limit; - table->free_result = table->all_results; - for (result = table->all_results; result < result_limit; result++) - result->data2 = 0; - - table->first_pass = 1; -} - - -/* Unlink all closed results except for those which has `routine' value marked - * in `exceptions' or large enough `remaining_depth' from the linked list of - * results at a node. It is assumed that the node contains at least one result. - */ -static void -hashnode_unlink_closed_results(Hashnode *node, - int exclusions, - unsigned int remaining_depth_limit, - int statistics[][20]) -{ - Read_result *result = node->results; - Read_result **link = &node->results; - - /* Traverse all node results. */ - do { - unsigned int result_remaining_depth = rr_get_remaining_depth(*result); - enum routine_id result_routine = rr_get_routine(*result); - - if (debug & DEBUG_READING_PERFORMANCE) { - int stat_stackp = depth - result_remaining_depth; - - if (stat_stackp > 19) - stat_stackp = 19; - if (stat_stackp < 0) - stat_stackp = 0; - - statistics[result_routine][stat_stackp]++; - } - - if (rr_is_closed(*result) - && result_remaining_depth <= remaining_depth_limit - && ((1 << result_routine) & exclusions) == 0) { - /* Unlink the result and mark it as free. */ - *link = result->next; - result->data2 = 0; - } - else - link = &result->next; - - result = result->next; - } while (result != NULL); -} - - -/* - * Clear an existing hash table except for open nodes. - * - * Don't even think about compressing the node and results arrays - * afterwards in order to simplify distribution of new nodes and - * results. The read result pointers out in reading.c and owl.c will - * never know that you moved them around. - * - * (comment) The above is only true about open results. All nodes can - * be moved as long as you fix links as well. However, it's - * doubtful that moving nodes will help anything. - */ - -static void -hashtable_partially_clear(Hashtable *table) -{ - int k, l; - Hashnode *node; - const int remaining_depth_limit = depth - 3; - - int statistics[NUM_CACHE_ROUTINES][20]; - - if (debug & DEBUG_READING_PERFORMANCE) { - gprintf("Hashtable cleared because it became full.\n"); - - for (k = 0; k < NUM_CACHE_ROUTINES; ++k) - for (l = 0; l < 20; ++l) - statistics[k][l] = 0; - } - - /* Walk through all_nodes. Since we free most of the nodes, it might seem - * faster to walk through all buckets. This approach really speeds up this - * function, but drastically slows down hashnode_unlink_closed_results() - * for in the first case results go almost continuously in the memory and - * in the second they are scattered randomly - very bad for memory caching. - */ - for (node = table->all_nodes; node < table->node_limit; node++) { - /* If there are no results attached, this node is not in the table. */ - if (node->results == NULL) - continue; - - /* Remove all closed results for this node except OWL_{ATTACK,DEFEND} - * and SEMEAI. - */ - hashnode_unlink_closed_results(node, - (1 << OWL_ATTACK | 1 << OWL_DEFEND - | 1 << SEMEAI), remaining_depth_limit, - statistics); - - if (node->results == NULL) { - int bucket = node->key.hashval[0] % table->hashtablesize; - Hashnode *bucket_node = table->hashtable[bucket]; - Hashnode **link = &table->hashtable[bucket]; - - /* Since all node results has been freed, we can free the node itself. */ - while (bucket_node != node) { - link = &bucket_node->next; - bucket_node = bucket_node->next; - } - - /* Unlink the node. It is already free, since node->results == NULL. */ - *link = node->next; - } - } - - if (debug & DEBUG_READING_PERFORMANCE) { - /* FIXME: These names should be where the constants are defined. - * They also look a bit outdated, check against cache.h. - */ - const char *routines[] = { - "find_defense", "defend1", "defend2", "defend3", - "defend4", "attack", "attack2", "attack3", - "owl_attack", "owl_defend", "", "", - "", "", "", "", - }; - int total; - - fprintf(stderr, "routine total 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19\n"); - - for (k = 0; k < NUM_CACHE_ROUTINES; ++k) { - total = 0; - for (l = 0; l < 20; ++l) - total += statistics[k][l]; - - if (total == 0) - continue; - - fprintf(stderr, "%-14s%6d", routines[k], total); - for (l = 0; l < 20; ++l) - fprintf(stderr, "%6d", statistics[k][l]); - fprintf(stderr, "\n"); - } - } - - /* FIXME: This is not entirely safe although it probably works more - * than 99.999% of all cases. If result no 0 or node no 0 is not - * free after the partial clearing, this will explode into our face. - * - * (answer) We check if a node or result is free before allocating, - * so these statements are ok. - */ - table->free_node = table->all_nodes; - table->free_result = table->all_results; - - table->first_pass = 0; -} - - -/* - * Enter a position with a given hash value into the table. Return - * a pointer to the hash node where it was stored. It is assumed that - * there is no such position in the table yet. - */ -static Hashnode * -hashtable_enter_position(Hashtable *table, Hash_data *hd) -{ - Hashnode *node; - int bucket; - - /* If the first node is not free, skip until we find one which is free. */ - while (table->free_node < table->node_limit - && table->free_node->results != NULL) - table->free_node++; - - if (table->free_node == table->node_limit) { - /* If the table is full, try to clean it up. */ - hashtable_partially_clear(table); - - while (table->free_node < table->node_limit - && table->free_node->results != NULL) - table->free_node++; - - if (table->free_node == table->node_limit) { - /* This shouldn't happen, at least with reasonably large tables. */ - return NULL; - } - } - - /* We have found a free node. Allocate it for the position. */ - node = table->free_node++; - node->key = *hd; - node->results = NULL; - - /* And link it into the corresponding bucket list. */ - bucket = hd->hashval[0] % table->hashtablesize; - node->next = table->hashtable[bucket]; - table->hashtable[bucket] = node; - - stats.position_entered++; - return node; -} - - -/* - * Given a Hashposition and a Hash value, find the hashnode which contains - * this very position with the given hash value. - * - * We could compute the hash value within this functions, but later - * when we have incremental calculation of the hash function, this - * would be dumb. So we demand the hash value from outside from the - * very beginning. - */ - -static Hashnode * -hashtable_search(Hashtable *table, Hash_data *hd) -{ - Hashnode *node; - int bucket; - int i; - - bucket = hd->hashval[0] % table->hashtablesize; - for (node = table->hashtable[bucket]; node != NULL; node = node->next) { - if (node->key.hashval[0] != hd->hashval[0]) - continue; - for (i = 1; i < NUM_HASHVALUES; i++) - if (node->key.hashval[i] != hd->hashval[i]) { - stats.hash_collisions++; - break; - } - if (i >= NUM_HASHVALUES) - break; - } - - return node; -} - - -/* Search the result list in a hash node for a particular result. This - * function accepts parameters in the same form as they are stored in - * Read_result structure. Use rr_input_data1() and rr_input_data2() - * macros to evaluate them. - */ -static Read_result * -hashnode_search(Hashnode *node, - unsigned int query_data1, unsigned int query_data2) -{ - Read_result *result; - - for (result = node->results; result != NULL; result = result->next) { - if (result->data1 == query_data1 - && (result->data2 & RR_INPUT_DATA2) == query_data2) - break; - } - - return result; -} - - -/* Enter a new Read_result into a Hashnode. - * We already have the node, now we just want to enter the result itself. - * The result is completed later. This function enters search information - * only (target string(s), routine, ko information, remaining depth). - */ -static Read_result * -hashnode_new_result(Hashtable *table, Hashnode *node, - unsigned int input_data1, unsigned int input_data2) -{ - Read_result *result; - - /* If the first result is not free, skip until we find one which is free. */ - while (table->free_result < table->result_limit - && !rr_is_free(*(table->free_result))) - table->free_result++; - - if (table->free_result == table->result_limit) { - Read_result *node_results = node->results; - - /* If the table is full, try to clean it up. */ - hashtable_partially_clear(table); - - if (node_results != NULL && node->results == NULL) { - /* If the node got freed, we need to reallocate it. */ - int bucket = node->key.hashval[0] % table->hashtablesize; - node->next = table->hashtable[bucket]; - table->hashtable[bucket] = node; - } - - while (table->free_result < table->result_limit - && !rr_is_free(*(table->free_result))) - table->free_result++; - - if (table->free_result == table->result_limit) { - /* This shouldn't happen, at least with reasonably large tables. */ - return NULL; - } - } - - /* We have found a free result entry. Allocate and initialize it. */ - result = table->free_result++; - result->data1 = input_data1; - result->data2 = input_data2 | RR_STATUS_OPEN; - - /* Link the result into the node's list. */ - result->next = node->results; - node->results = result; - - stats.read_result_entered++; - return result; -} -#endif - /* Initialize the cache for read results, using at most the given * number of bytes of memory. If the memory isn't sufficient to * allocate a single node or if the allocation fails, the caching is @@ -910,36 +312,7 @@ void reading_cache_init(int bytes) { -#if USE_HASHTABLE_NG tt_init(&ttable, bytes); -#else - float nodes; - - /* Initialize hash table. - * - * The number 1.4 below is the quotient between the number of nodes - * and the number of read results. It was found in a test that this - * number varies between 1.15 and 1.4. Thus we use 1.4. - */ - nodes = ((float) bytes - / (1.5 * sizeof(Hashnode *) - + sizeof(Hashnode) - + 1.4 * sizeof(Read_result))); - if (0) - gprintf("Allocated memory for %d hash nodes. \n", (int) nodes); - /* If we get a zero size hash table, disable hashing completely. */ - if (nodes < 1.0) - hashflags = HASH_NOTHING; - movehash = hashtable_new((int) (1.5 * nodes), /* table size */ - (int) nodes, /* nodes */ - (int) (1.4 * nodes)); /* read results */ - - if (!movehash) { - fprintf(stderr, - "Warning: failed to allocate hashtable, caching disabled.\n"); - hashflags = HASH_NOTHING; - } -#endif } @@ -947,167 +320,9 @@ void reading_cache_clear() { -#if USE_HASHTABLE_NG tt_clear(&ttable); -#else - hashtable_clear(movehash); -#endif -} - -#if !USE_HASHTABLE_NG - -int -get_read_result_hash_modified(enum routine_id routine, - int *str, Hash_data *hashmodifier, - Read_result **read_result) -{ - /* Only store the result if stackp <= depth. Above that, there - * is no branching, so we won't gain anything. - */ - if (stackp > depth) { - *read_result = NULL; - return 0; - } - - /* Find the origin of the string in order to make the caching of read - * results work better. - */ - *str = find_origin(*str); - - return do_get_read_result(routine, *str, NO_MOVE, - read_result, hashmodifier); -} - -/* - * Return a Read_result for the current position, routine and location. - * For performance, the location is changed to the origin of the string. - */ -int -get_read_result(enum routine_id routine, int *str, - Read_result **read_result) -{ - /* Only store the result if stackp <= depth. Above that, there - * is no branching, so we won't gain anything. - */ - if (stackp > depth) { - *read_result = NULL; - return 0; - } - - /* Find the origin of the string in order to make the caching of read - * results work better. - */ - *str = find_origin(*str); - - return do_get_read_result(routine, *str, NO_MOVE, read_result, NULL); -} - - -/* - * Variant with two calling strings. - */ -int -get_read_result2(enum routine_id routine, int *str1, int *str2, - Read_result **read_result) -{ - /* Only store the result if stackp <= depth. Above that, there - * is no branching, so we won't gain anything. - */ - if (stackp > depth) { - *read_result = NULL; - return 0; - } - - /* Find the origin of the strings in order to make the caching of read - * results work better. - */ - *str1 = find_origin(*str1); - *str2 = find_origin(*str2); - - return do_get_read_result(routine, *str1, *str2, - read_result, NULL); -} - - -static int -do_get_read_result(enum routine_id routine, - int str1, int str2, Read_result **read_result, - Hash_data *hashmodifier) -{ - Hashnode *node; - unsigned int data1 = rr_input_data1(routine, get_komaster(), get_kom_pos(), - str1, depth - stackp); - unsigned int data2 = rr_input_data2(str2); - Hash_data modified_hash; - -#if CHECK_HASHING - Hash_data key; - - /* Assert that hash data really corresponds to the state of the board. */ - hashdata_recalc(&key, board, board_ko_pos); - gg_assert(hashdata_compare(&key, &hashdata) == 0); - -#endif /* CHECK_HASHING */ - - if (hashmodifier) - modified_hash = xor_hashvalues(&hashdata, hashmodifier); - else - modified_hash = hashdata; - - /* First try to look this position up in the table. */ - node = hashtable_search(movehash, &modified_hash); - if (node != NULL) { - Read_result *result; - - stats.position_hits++; - DEBUG(DEBUG_READING_CACHE, "We found position %H in the hash table...\n", - (unsigned long) hashdata.hashval); - - /* The position is found. So, maybe the result is already in the table? */ - result = hashnode_search(node, data1, data2); - if (result != NULL) { - *read_result = result; - return 1; - } - - DEBUG(DEBUG_READING_CACHE, - "...but no previous result for routine %d and (%1m, %1m)...", - routine, str1, str2); - } - else { - node = hashtable_enter_position(movehash, &modified_hash); - if (node) { - DEBUG(DEBUG_READING_CACHE, "Created position %H in the hash table...\n", - (unsigned long) modified_hash.hashval); - } - else { - DEBUG(DEBUG_READING_CACHE, "Unable to clean up the hash table!\n"); - *read_result = NULL; - return 0; - } - } - - /* Enter the result into the table. */ - *read_result = hashnode_new_result(movehash, node, data1, data2); - - if (*read_result != NULL) - DEBUG(DEBUG_READING_CACHE, "...allocated a new result.\n"); - else { - /* If this ever happens and the node contains no results (can only be true - * if the node is newly allocated), we unlink the node from its bucket. - */ - if (node->results == NULL) { - int bucket = node->key.hashval[0] % movehash->hashtablesize; - movehash->hashtable[bucket] = node->next; - } - - DEBUG(DEBUG_READING_CACHE, "Unable to clean up the hash table!\n"); - } - - return 0; } -#endif /* Write reading trace data to an SGF file. Normally called through the * macro SGFTRACE in cache.h. Index: engine/cache.h =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/cache.h,v retrieving revision 1.48 diff -u -r1.48 cache.h --- engine/cache.h 19 May 2004 14:24:06 -0000 1.48 +++ engine/cache.h 22 May 2004 20:14:45 -0000 @@ -32,9 +32,6 @@ * (Reading/Hashing) for more information. */ -/* Define to 1 if you want the new transposition table. */ -#define USE_HASHTABLE_NG 1 - /* Hashnode: a node stored in the transposition table. * @@ -59,9 +56,9 @@ * The last 9 bits together give an index for the total costs. */ typedef struct { - Hash_data key; - unsigned int data; /* Should be 32 bits, but only wastes 25% if 64 bits. */ -} Hashnode_ng; + Hash_data key; + unsigned int data; /* Should be 32 bits, but only wastes 25% if 64 bits. */ +} Hashnode; #define HN_MAX_REMAINING_DEPTH 31 @@ -69,9 +66,9 @@ /* Hashentry: an entry, with two nodes of the hash_table */ typedef struct { - Hashnode_ng deepest; - Hashnode_ng newest; -} Hashentry_ng; + Hashnode deepest; + Hashnode newest; +} Hashentry; /* Hn is for hash node. */ #define hn_get_value1(hn) ((hn >> 23) & 0x0f) @@ -91,15 +88,13 @@ /* Transposition_table: transposition table used for caching. */ typedef struct { - unsigned int num_entries; - Hashentry_ng *entries; - int is_clean; + unsigned int num_entries; + Hashentry *entries; + int is_clean; } Transposition_table; -extern Transposition_table ttable; +extern Transposition_table ttable; -void tt_init(Transposition_table *table, int memsize); -void tt_clear(Transposition_table *table); void tt_free(Transposition_table *table); int tt_get(Transposition_table *table, enum routine_id routine, int target1, int target2, int remaining_depth, @@ -111,185 +106,25 @@ int value1, int value2, int move); -#if !USE_HASHTABLE_NG /* ================================================================ */ -/* The old transposition table */ -/* - * This struct contains the attack / defense point and the result. - * It is kept in a linked list, and each position has a list of - * these. - * - * When a new result node is created, 'status' is set to 1 'open'. - * This is then set to 2 'closed' when the result is entered. The main - * use for this is to identify open result nodes when the hashtable is - * partially cleared. Another potential use for this field is to - * identify repeated positions in the reading, in particular local - * double or triple kos. - * - * The data1 field packs into 32 bits the following - * fields: - * - * komaster : 3 bits (EMPTY, BLACK, WHITE, GRAY, GRAY_WHITE, ...) - * kom_pos : 10 bits (allows MAX_BOARD up to 31) - * routine : 4 bits (currently 10 different choices) - * str1 : 10 bits - * remaining_depth : 5 bits (depth - stackp) - * - * The data2 field packs into 32 bits the following - * fields: - * - * status : 2 bits (0 free, 1 open, 2 closed) - * result1: 4 bits - * result2: 4 bits - * move : 10 bits - * str2 : 10 bits - */ - -typedef struct read_result_t { - unsigned int data1; - unsigned int data2; - - struct read_result_t *next; -} Read_result; - -/* Bit mask for the input bits in the data2 field. */ -#define RR_INPUT_DATA2 0x3ff - -/* Read_result entry status. */ -#define RR_STATUS_OPEN (1 << 28) -#define RR_STATUS_CLOSED (2 << 28) - -/* Get parts of a Read_result identifying the input data. */ -#define rr_get_komaster(rr) (((rr).data1 >> 29) & 0x07) -#define rr_get_kom_pos(rr) (((rr).data1 >> 19) & 0x3ff) -#define rr_get_routine(rr) (((rr).data1 >> 15) & 0x0f) -#define rr_get_str1(rr) (((rr).data1 >> 5) & 0x3ff) -#define rr_get_remaining_depth(rr) (((rr).data1 >> 0) & 0x1f) -#define rr_get_str2(rr) (((rr).data2 >> 0) & 0x3ff) -#define rr_get_str(rr) rr_get_str1(rr) - -/* Set corresponding parts. */ -#define rr_input_data1(routine, komaster, kom_pos, str1, remaining_depth) \ - (((((((((komaster) << 10) | (kom_pos)) << 4) \ - | (routine)) << 10) | (str1)) << 5) | (remaining_depth)) -#define rr_input_data2(str2) (str2) \ - -/* Get parts of a Read_result constituting the result of a search. */ -#define rr_get_status(rr) (((rr).data2 >> 28) & 0x03) -#define rr_get_result1(rr) (((rr).data2 >> 24) & 0x0f) -#define rr_get_result2(rr) (((rr).data2 >> 20) & 0x0f) -#define rr_get_move(rr) (((rr).data2 >> 10) & 0x3ff) -#define rr_get_result(rr) rr_get_result1(rr) - -#define rr_is_free(rr) (((rr).data2 \ - & (RR_STATUS_OPEN | RR_STATUS_CLOSED)) == 0) -#define rr_is_open(rr) (((rr).data2 & RR_STATUS_OPEN) != 0) -#define rr_is_closed(rr) (((rr).data2 & RR_STATUS_CLOSED) != 0) - -/* Set corresponding parts. Closes the result entry. */ -#define rr_set_result_move(rr, result, move) \ - (rr).data2 = (((rr).data2 & 0x3ff) | RR_STATUS_CLOSED \ - | (((result) & 0x0f) << 24) | (((move) & 0x3ff) << 10)) - -/* Variation with two results. */ -#define rr_set_result_move2(rr, result1, result2, move) \ - (rr).data2 = (((rr).data2 & 0x3ff) | RR_STATUS_CLOSED \ - | (((result1) & 0x0f) << 24) \ - | (((result2) & 0x0f) << 20) \ - | (((move) & 0x3ff) << 10)) - -/* - * The hash table consists of hash nodes. Each hash node consists of - * The hash value for the position it holds, the position itself and - * the actual information which is purpose of the table from the start. - * - * There is also a pointer to another hash node which is used when - * the nodes are sorted into hash buckets (see below). - */ - -typedef struct hashnode_t { - Hash_data key; - Read_result *results; /* The results of previous readings */ - - struct hashnode_t *next; -} Hashnode; - - -/* - * The hash table consists of three parts: - * - The hash table proper: a number of hash buckets with collisions - * being handled by a linked list. - * - The hash nodes. These are allocated at creation time and are - * never removed or reallocated in the current implementation. - * - The search results. Since many different searches can - * be done in the same position, there should be more of these than - * hash nodes. - */ - -typedef struct hashtable { - int hashtablesize; /* Number of hash buckets. */ - Hashnode **hashtable; /* Pointer to array of hashnode lists. */ - - Hashnode *all_nodes; /* Pointer to all allocated hash nodes. */ - Hashnode *node_limit; /* Pointer to the end of all_nodes[] array. */ - Hashnode *free_node; /* Pointer to the first free node. */ - - Read_result *all_results; /* Pointer to all allocated results. */ - Read_result *result_limit; /* Pointer to the enf of all_results[] array. */ - Read_result *free_result; /* Pointer to the first free result. */ - - /* True if hashtable_partially_clear() hasn't been called yet. In this case - * allocated nodes and results (if any) go continuosly in memory which - * simplifies clearing. - */ - int first_pass; -} Hashtable; - - -void read_result_dump(Read_result *result, FILE *outfile); -void hashtable_dump(Hashtable *table, FILE *outfile); -void hashnode_dump(Hashnode *node, FILE *outfile); -#endif - -/* ================================================================ */ - - -/* Macros used from reading.c and owl.c to store and retrieve read - * results. +/* Macros used from reading.c, readconnect.c, and owl.c to store and + * retrieve read results. */ #if TRACE_READ_RESULTS -#if USE_HASHTABLE_NG - -#define TRACE_CACHED_RESULT_NG(result, move) \ +#define TRACE_CACHED_RESULT(result, move) \ gprintf("%o%s %1m %d %d %1m (cached) ", read_function_name, \ q, stackp, result, move); \ dump_stack(); -#define TRACE_CACHED_RESULT2_NG(result1, result2, move) \ +#define TRACE_CACHED_RESULT2(result1, result2, move) \ gprintf("%o%s %1m %1m %d %d %d %1m (cached) ", read_function_name, \ q1, q2, stackp, result1, result2, move); \ dump_stack(); -#else -#define TRACE_CACHED_RESULT(rr) \ - gprintf("%o%s %1m %d %d %1m (cached) ", read_function_name, \ - q, stackp, \ - rr_get_result(rr), \ - rr_get_move(rr)); \ - dump_stack(); - -#define TRACE_CACHED_RESULT2(rr) \ - gprintf("%o%s %1m %1m %d %d %d %1m (cached) ", read_function_name, \ - q1, q2, stackp, \ - rr_get_result1(rr), \ - rr_get_result2(rr), \ - rr_get_move(rr)); \ - dump_stack(); -#endif #define SETUP_TRACE_INFO(name, str) \ const char *read_function_name = name; \ @@ -302,13 +137,8 @@ #else -#if USE_HASHTABLE_NG -#define TRACE_CACHED_RESULT_NG(result, move) -#define TRACE_CACHED_RESULT2_NG(result1, result2, move) -#else -#define TRACE_CACHED_RESULT(rr) -#define TRACE_CACHED_RESULT2(rr) -#endif +#define TRACE_CACHED_RESULT(result, move) +#define TRACE_CACHED_RESULT2(result1, result2, move) #define SETUP_TRACE_INFO(name, str) \ const char *read_function_name = name; \ @@ -355,16 +185,6 @@ result1, result2, message) -#if !USE_HASHTABLE_NG -int get_read_result(enum routine_id routine, - int *str, Read_result **read_result); -int get_read_result_hash_modified(enum routine_id routine, - int *str, Hash_data *hash_modifier, - Read_result **read_result); -int get_read_result2(enum routine_id routine, - int *str1, int *str2, Read_result **read_result); -#endif - /* ================================================================ */ /* @@ -375,126 +195,67 @@ #if !TRACE_READ_RESULTS -#if USE_HASHTABLE_NG -#define READ_RETURN0_NG(routine, str, remaining_depth) \ +#define READ_RETURN0(routine, str, remaining_depth) \ do { \ - tt_update(&ttable, routine, str, NO_MOVE, \ - remaining_depth, NULL,\ + tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\ 0, 0, NO_MOVE);\ return 0; \ } while (0) -#define READ_RETURN_NG(routine, str, remaining_depth, point, move, value) \ +#define READ_RETURN(routine, str, remaining_depth, point, move, value) \ do { \ - tt_update(&ttable, routine, str, NO_MOVE, \ - remaining_depth, NULL,\ + tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\ value, 0, move);\ if ((value) != 0 && (point) != 0) *(point) = (move); \ return (value); \ } while (0) -#define READ_RETURN_SEMEAI_NG(routine, str1, str2, remaining_depth, point, move, value1, value2) \ +#define READ_RETURN_SEMEAI(routine, str1, str2, remaining_depth, point, move, value1, value2) \ do { \ - tt_update(&ttable, routine, str1, str2, \ - remaining_depth, NULL, \ + tt_update(&ttable, routine, str1, str2, remaining_depth, NULL, \ value1, value2, move); \ if ((value1) != 0 && (point) != 0) *(point) = (move); \ return; \ } while (0) -#define READ_RETURN_CONN_NG(routine, str1, str2, remaining_depth, point, move, value) \ +#define READ_RETURN_CONN(routine, str1, str2, remaining_depth, point, move, value) \ do { \ - tt_update(&ttable, routine, str1, str2, \ - remaining_depth, NULL,\ + tt_update(&ttable, routine, str1, str2, remaining_depth, NULL,\ value, 0, move);\ if ((value) != 0 && (point) != 0) *(point) = (move); \ return (value); \ } while (0) -#define READ_RETURN_HASH_NG(routine, str, remaining_depth, hash, point, move, value) \ +#define READ_RETURN_HASH(routine, str, remaining_depth, hash, point, move, value) \ do { \ - tt_update(&ttable, routine, str, NO_MOVE, \ - remaining_depth, hash,\ + tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, hash,\ value, 0, move);\ if ((value) != 0 && (point) != 0) *(point) = (move); \ return (value); \ } while (0) -#define READ_RETURN2_NG(routine, str, remaining_depth, point, move, value1, value2) \ +#define READ_RETURN2(routine, str, remaining_depth, point, move, value1, value2) \ do { \ - tt_update(&ttable, routine, str, NO_MOVE, \ - remaining_depth, NULL,\ + tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\ value1, value2, move);\ if ((value1) != 0 && (point) != 0) *(point) = (move); \ return (value1); \ } while (0) -#else - -#define READ_RETURN0(read_result) \ - do { \ - if (read_result) { \ - rr_set_result_move(*(read_result), 0, 0); \ - } \ - return 0; \ - } while (0) - -#define READ_RETURN(read_result, point, move, value) \ - do { \ - if ((value) != 0 && (point) != 0) *(point) = (move); \ - if (read_result) { \ - rr_set_result_move(*(read_result), (value), (move)); \ - } \ - return (value); \ - } while (0) - -#define READ_RETURN_SEMEAI(read_result, point, move, value_a, value_b) \ - do { \ - if ((value_a) != 0 && (point) != 0) *(point) = (move); \ - if (read_result) { \ - rr_set_result_move2(*(read_result), (value_a), (value_b), (move)); \ - } \ - return; \ - } while (0) - -#define READ_RETURN_CONN(read_result, point, move, value) \ - do { \ - if ((value) != 0 && (point) != 0) *(point) = (move); \ - if (read_result) { \ - rr_set_result_move(*(read_result), (value), (move)); \ - } \ - return (value); \ - } while (0) - -#define READ_RETURN2(read_result, point, move, value_a, value_b) \ - do { \ - if ((value_a) != 0 && (point) != 0) *(point) = (move); \ - if (read_result) { \ - rr_set_result_move2(*(read_result), (value_a), (value_b), (move)); \ - } \ - return (value_a); \ - } while (0) - -#endif - #else /* !TRACE_READ_RESULTS */ -#if USE_HASHTABLE_NG - -#define READ_RETURN0_NG(routine, str, remaining_depth) \ +#define READ_RETURN0(routine, str, remaining_depth) \ do { \ - tt_update(&ttable, routine, str, NO_MOVE, \ - remaining_depth, NULL,\ + tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\ 0, 0, NO_MOVE);\ gprintf("%o%s %1m %d 0 0 ", read_function_name, q, stackp); \ dump_stack(); \ return 0; \ } while (0) -#define READ_RETURN_NG(routine, str, remaining_depth, point, move, value) \ +#define READ_RETURN(routine, str, remaining_depth, point, move, value) \ do { \ - tt_update(&ttable, routine, str, NO_MOVE, \ - remaining_depth, NULL,\ + tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\ value, 0, move);\ if ((value) != 0 && (point) != 0) *(point) = (move); \ gprintf("%o%s %1m %d %d %1m ", read_function_name, q, stackp, \ @@ -503,10 +264,9 @@ return (value); \ } while (0) -#define READ_RETURN_SEMEAI_NG(routine, str1, str2, remaining_depth, point, move, value1, value2) \ +#define READ_RETURN_SEMEAI(routine, str1, str2, remaining_depth, point, move, value1, value2) \ do { \ - tt_update(&ttable, routine, str1, str2, \ - remaining_depth, NULL, \ + tt_update(&ttable, routine, str1, str2, remaining_depth, NULL, \ value1, value2, move); \ if ((value1) != 0 && (point) != 0) *(point) = (move); \ gprintf("%o%s %1m %1m %d %d %d %1m ", read_function_name, q1, q2, stackp, \ @@ -515,10 +275,9 @@ return; \ } while (0) -#define READ_RETURN_CONN_NG(routine, str1, str2, remaining_depth, point, move, value) \ +#define READ_RETURN_CONN(routine, str1, str2, remaining_depth, point, move, value) \ do { \ - tt_update(&ttable, routine, str1, str2, \ - remaining_depth, NULL,\ + tt_update(&ttable, routine, str1, str2, remaining_depth, NULL,\ value, 0, move);\ if ((value) != 0 && (point) != 0) *(point) = (move); \ gprintf("%o%s %1m %1m %d %d %1m ", read_function_name, q1, q2, stackp, \ @@ -527,10 +286,9 @@ return (value); \ } while (0) -#define READ_RETURN_HASH_NG(routine, str, remaining_depth, hash, point, move, value) \ +#define READ_RETURN_HASH(routine, str, remaining_depth, hash, point, move, value) \ do { \ - tt_update(&ttable, routine, str, NO_MOVE, \ - remaining_depth, hash,\ + tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, hash,\ value, 0, move);\ if ((value) != 0 && (point) != 0) *(point) = (move); \ gprintf("%o%s %1m %d %d %1m ", read_function_name, q, stackp, \ @@ -539,10 +297,9 @@ return (value); \ } while (0) -#define READ_RETURN2_NG(routine, str, remaining_depth, point, move, value1, value2) \ +#define READ_RETURN2(routine, str, remaining_depth, point, move, value1, value2) \ do { \ - tt_update(&ttable, routine, str, NO_MOVE, \ - remaining_depth, NULL,\ + tt_update(&ttable, routine, str, NO_MOVE, remaining_depth, NULL,\ value1, value2, move);\ if ((value1) != 0 && (point) != 0) *(point) = (move); \ gprintf("%o%s %1m %d %d %1m ", read_function_name, q, stackp, \ @@ -551,68 +308,6 @@ return (value1); \ } while (0) -#else - -#define READ_RETURN0(read_result) \ - do { \ - if (read_result) { \ - rr_set_result_move(*(read_result), 0, 0); \ - } \ - gprintf("%o%s %1m %d 0 0 ", read_function_name, q, stackp); \ - dump_stack(); \ - return 0; \ - } while (0) - -#define READ_RETURN(read_result, point, move, value) \ - do { \ - if ((value) != 0 && (point) != 0) *(point) = (move); \ - if (read_result) { \ - rr_set_result_move(*(read_result), (value), (move)); \ - } \ - gprintf("%o%s %1m %d %d %1m ", read_function_name, q, stackp, \ - (value), (move)); \ - dump_stack(); \ - return (value); \ - } while (0) - -#define READ_RETURN_SEMEAI(read_result, point, move, value_a, value_b) \ - do { \ - if ((value_a) != 0 && (point) != 0) *(point) = (move); \ - if (read_result) { \ - rr_set_result_move2(*(read_result), (value_a), (value_b), (move)); \ - } \ - gprintf("%o%s %1m %1m %d %d %d %1m ", read_function_name, q1, q2, stackp, \ - (value_a), (value_b), (move)); \ - dump_stack(); \ - return; \ - } while (0) - -#define READ_RETURN_CONN(read_result, point, move, value) \ - do { \ - if ((value) != 0 && (point) != 0) *(point) = (move); \ - if (read_result) { \ - rr_set_result_move(*(read_result), (value), (move)); \ - } \ - gprintf("%o%s %1m %1m %d %d %1m ", read_function_name, q1, q2, stackp, \ - (value), (move)); \ - dump_stack(); \ - return (value); \ - } while (0) - -#define READ_RETURN2(read_result, point, move, value_a, value_b) \ - do { \ - if ((value_a) != 0 && (point) != 0) *(point) = (move); \ - if (read_result) { \ - rr_set_result_move2(*(read_result), (value_a), (value_b), (move)); \ - } \ - gprintf("%o%s %1m %d %d %1m ", read_function_name, q, stackp, \ - (value_a), (move)); \ - dump_stack(); \ - return (value_a); \ - } while (0) - -#endif - #endif @@ -638,7 +333,6 @@ * or a backfilling move. If possible, we prefer making non-sacrifice * and direct moves. Of course savecode WIN is better than KO_A or KO_B. */ - #define UPDATE_SAVED_KO_RESULT(savecode, save, code, move) \ if (code != 0 && REVERSE_RESULT(code) > savecode) { \ Index: engine/hash.c =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/hash.c,v retrieving revision 1.25 diff -u -r1.25 hash.c --- engine/hash.c 12 Apr 2004 15:28:22 -0000 1.25 +++ engine/hash.c 22 May 2004 20:14:45 -0000 @@ -84,11 +84,6 @@ */ gg_get_rand_state(&state); -#if TRACE_READ_RESULTS - /* We need consistent hash values when this option is enabled. */ - gg_srand(1); -#endif - for (i = 0; i < NUM_HASHVALUES; i++) for (pos = BOARDMIN; pos < BOARDMAX; pos++) { /* Note: We initialize _all_ positions, not just those on board. @@ -120,23 +115,16 @@ for (i = 0; i < NUM_HASHVALUES; i++) target->hashval[i] = 0; + for (pos = BOARDMIN; pos < BOARDMAX; pos++) { - if (!ON_BOARD(pos)) - continue; - switch (p[pos]) { - default: - case EMPTY: - break; - case WHITE: - for (i = 0; i < NUM_HASHVALUES; i++) - target->hashval[i] ^= white_hash[pos][i]; - break; - case BLACK: - for (i = 0; i < NUM_HASHVALUES; i++) - target->hashval[i] ^= black_hash[pos][i]; - break; + if (board[pos] == WHITE) { + for (i = 0; i < NUM_HASHVALUES; i++) + target->hashval[i] ^= white_hash[pos][i]; + } + else if (board[pos] == BLACK) { + for (i = 0; i < NUM_HASHVALUES; i++) + target->hashval[i] ^= black_hash[pos][i]; } - } if (ko_pos != 0) @@ -200,24 +188,15 @@ { int i, pos; Hash_data return_value; + for (i = 0; i < NUM_HASHVALUES; i++) return_value.hashval[i] = 0; + for (pos = BOARDMIN; pos < BOARDMAX; pos++) if (ON_BOARD(pos) && goal[pos]) for (i = 0; i < NUM_HASHVALUES; i++) return_value.hashval[i] += white_hash[pos][i] + black_hash[pos][i]; - return return_value; -} - -/* Returns an XOR of the two hash values. */ -Hash_data -xor_hashvalues(Hash_data *hash1, Hash_data *hash2) -{ - int i; - Hash_data return_value; - - for (i = 0; i < NUM_HASHVALUES; i++) - return_value.hashval[i] = hash1->hashval[i] ^ hash2->hashval[i]; + return return_value; } Index: engine/hash.h =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/hash.h,v retrieving revision 1.27 diff -u -r1.27 hash.h --- engine/hash.h 19 May 2004 14:24:06 -0000 1.27 +++ engine/hash.h 22 May 2004 20:14:46 -0000 @@ -76,12 +76,11 @@ */ typedef struct { - Hashvalue hashval[NUM_HASHVALUES]; + Hashvalue hashval[NUM_HASHVALUES]; } Hash_data; extern Hash_data hashdata; -Hash_data xor_hashvalues(Hash_data *key1, Hash_data *key2); Hash_data goal_to_hashvalue(const char *goal); void hash_init(void); Index: engine/owl.c =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/owl.c,v retrieving revision 1.211 diff -u -r1.211 owl.c --- engine/owl.c 19 May 2004 14:24:06 -0000 1.211 +++ engine/owl.c 22 May 2004 20:14:46 -0000 @@ -553,13 +553,9 @@ const char *best_move_name = NULL; int this_resulta = -1; int this_resultb = -1; -#if USE_HASHTABLE_NG - int xpos; - int value1; - int value2; -#else - Read_result *read_result = NULL; -#endif + int xpos; + int value1; + int value2; int this_variation_number = count_variations - 1; int you_look_alive = 0; int I_look_alive = 0; @@ -580,14 +576,11 @@ ASSERT1(board[apos] == owla->color, apos); ASSERT1(board[bpos] == owlb->color, bpos); -#if USE_HASHTABLE_NG - if (stackp <= semeai_branch_depth && (hashflags & HASH_SEMEAI) && !pass && owl_phase - && tt_get(&ttable, SEMEAI, apos, bpos, - depth - stackp, NULL, + && tt_get(&ttable, SEMEAI, apos, bpos, depth - stackp, NULL, &value1, &value2, &xpos)) { - TRACE_CACHED_RESULT2_NG(value1, value2, xpos); + TRACE_CACHED_RESULT2(value1, value2, xpos); if (value1 != 0) *move = xpos; @@ -603,31 +596,6 @@ return; } -#else - if (stackp <= semeai_branch_depth && (hashflags & HASH_SEMEAI) - && !pass && owl_phase) { - if (get_read_result2(SEMEAI, &apos, &bpos, &read_result)) { - TRACE_CACHED_RESULT2(*read_result); - - if (rr_get_result1(*read_result) != 0) - *move = rr_get_move(*read_result); - - *resulta = rr_get_result1(*read_result); - *resultb = rr_get_result2(*read_result); - - TRACE("%oVariation %d: %1m %1m %s %s %1m (cached) ", - this_variation_number, apos, bpos, - result_to_string(*resulta), - result_to_string(*resultb), - *move); - SGFTRACE_SEMEAI(rr_get_move(*read_result), *resulta, - *resultb, "cached"); - return; - } - } - -#endif - global_owl_node_counter++; local_owl_node_counter++; @@ -679,12 +647,8 @@ sgf_dumptree = save_sgf_dumptree; count_variations = save_count_variations; SGFTRACE_SEMEAI(upos, WIN, WIN, "tactical win found"); -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, - depth - stackp, move, upos, WIN, WIN); -#else - READ_RETURN_SEMEAI(read_result, move, upos, WIN, WIN); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, upos, WIN, WIN); } else if (acode != 0 && find_defense(semeai_worms[sworm], NULL)) { @@ -802,12 +766,8 @@ count_variations = save_count_variations; TRACE("Both live\n"); SGFTRACE_SEMEAI(PASS_MOVE, WIN, 0, "Both live"); -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, - depth - stackp, move, PASS_MOVE, WIN, 0); -#else - READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, WIN, 0); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, PASS_MOVE, WIN, 0); } /* Next the shape moves. */ @@ -1044,12 +1004,8 @@ SGFTRACE_SEMEAI(mpos, WIN, WIN, moves[k].name); close_pattern_list(color, &shape_defensive_patterns); close_pattern_list(color, &shape_offensive_patterns); -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, - depth - stackp, move, mpos, WIN, WIN); -#else - READ_RETURN_SEMEAI(read_result, move, mpos, WIN, WIN); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, mpos, WIN, WIN); } /* When there is a choice between ko and seki, the prefer_ko * variable decides policy. Thus if prefer_ko == color we @@ -1083,12 +1039,8 @@ *resultb = 0; *move = PASS_MOVE; SGFTRACE_SEMEAI(PASS_MOVE, 0, 0, "You live, I die"); -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, - depth - stackp, move, PASS_MOVE, 0, 0); -#else - READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, 0, 0); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, PASS_MOVE, 0, 0); } /* If we can't find a move and we look dead even if including the @@ -1115,12 +1067,8 @@ *resultb = 0; *move = PASS_MOVE; SGFTRACE_SEMEAI(PASS_MOVE, 0, 0, "You live, I die - 2"); -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, - depth - stackp, move, PASS_MOVE, 0, 0); -#else - READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, 0, 0); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, PASS_MOVE, 0, 0); } include_semeai_worms_in_eyespace = 0; } @@ -1136,12 +1084,8 @@ *move = PASS_MOVE; TRACE("You have more eyes.\n"); SGFTRACE_SEMEAI(PASS_MOVE, 0, 0, "You have more eyes"); -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, - depth - stackp, move, PASS_MOVE, 0, 0); -#else - READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, 0, 0); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, PASS_MOVE, 0, 0); } else if (max_eyes(&probable_eyes_b) < min_eyes(&probable_eyes_a)) { *resulta = WIN; @@ -1149,12 +1093,8 @@ *move = PASS_MOVE; TRACE("I have more eyes\n"); SGFTRACE_SEMEAI(PASS_MOVE, WIN, WIN, "I have more eyes"); -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, - depth - stackp, move, PASS_MOVE, WIN, WIN); -#else - READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, WIN, WIN); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, PASS_MOVE, WIN, WIN); } else { *resulta = WIN; @@ -1162,12 +1102,8 @@ *move = PASS_MOVE; TRACE("Seki\n"); SGFTRACE_SEMEAI(PASS_MOVE, WIN, 0, "Seki"); -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, - depth - stackp, move, PASS_MOVE, WIN, 0); -#else - READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, WIN, 0); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, PASS_MOVE, WIN, 0); } } @@ -1180,12 +1116,8 @@ TRACE("No move found\n"); SGFTRACE_SEMEAI(PASS_MOVE, *resulta, *resultb, "No move found"); *move = PASS_MOVE; -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, - depth - stackp, move, PASS_MOVE, *resulta, *resultb); -#else - READ_RETURN_SEMEAI(read_result, move, PASS_MOVE, *resulta, *resultb); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, PASS_MOVE, *resulta, *resultb); } *resulta = best_resulta; @@ -1194,12 +1126,8 @@ best_move = PASS_MOVE; *move = best_move; SGFTRACE_SEMEAI(best_move, best_resulta, best_resultb, best_move_name); -#if USE_HASHTABLE_NG - READ_RETURN_SEMEAI_NG(SEMEAI, apos, bpos, depth - stackp, - move, best_move, best_resulta, best_resultb); -#else - READ_RETURN_SEMEAI(read_result, move, best_move, best_resulta, best_resultb); -#endif + READ_RETURN_SEMEAI(SEMEAI, apos, bpos, depth - stackp, + move, best_move, best_resulta, best_resultb); } /* Play a move, update goal and boundaries appropriately, and call @@ -1768,14 +1696,9 @@ struct eyevalue probable_eyes; /* Best guess of eyevalue. */ const char *live_reason; int move_cutoff; -#if USE_HASHTABLE_NG - int xpos; - int value1; - int value2; -#else - Read_result *read_result = NULL; - int found_read_result; -#endif + int xpos; + int value1; + int value2; int this_variation_number = count_variations - 1; SETUP_TRACE_INFO("owl_attack", str); @@ -1783,14 +1706,12 @@ shape_patterns.initialized = 0; str = find_origin(str); -#if USE_HASHTABLE_NG if ((hashflags & HASH_OWL_ATTACK) - && tt_get(&ttable, OWL_ATTACK, str, NO_MOVE, - depth - stackp, NULL, + && tt_get(&ttable, OWL_ATTACK, str, NO_MOVE, depth - stackp, NULL, &value1, &value2, &xpos) == 2) { - TRACE_CACHED_RESULT_NG(value1, xpos); + TRACE_CACHED_RESULT(value1, xpos); if (value1 != 0) { if (move) *move = xpos; @@ -1815,49 +1736,10 @@ } -#else - - if (hashflags & HASH_OWL_ATTACK) { - found_read_result = get_read_result(OWL_ATTACK, - &str, &read_result); - if (found_read_result) { - TRACE_CACHED_RESULT(*read_result); - if (rr_get_result(*read_result) != 0) { - if (move) - *move = rr_get_move(*read_result); - } - if (rr_get_result(*read_result) == GAIN) { - if (wormid) { - if (goal_worms_computed) - *wormid = rr_get_result2(*read_result); - else - *wormid = MAX_GOAL_WORMS; - } - } - - if (rr_get_result(*read_result) == WIN) - TRACE("%oVariation %d: DEAD (cached)\n", this_variation_number); - else - TRACE("%oVariation %d: ALIVE (cached)\n", this_variation_number); - - SGFTRACE(rr_get_move(*read_result), rr_get_result(*read_result), - "cached"); - return rr_get_result(*read_result); - } - } - -#endif - - /* If reading goes to deep or we run out of nodes, we assume life. */ if (reading_limit_reached(&live_reason, this_variation_number)) { SGFTRACE(0, 0, live_reason); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_ATTACK, str, depth - stackp, - move, 0, 0); -#else - READ_RETURN(read_result, move, 0, 0); -#endif + READ_RETURN(OWL_ATTACK, str, depth - stackp, move, 0, 0); } memset(mw, 0, sizeof(mw)); @@ -1898,22 +1780,14 @@ } SGFTRACE(0, acode, live_reason); TRACE("%oVariation %d: ALIVE (%s)\n", this_variation_number, live_reason); - if (acode == 0) -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_ATTACK, str, depth - stackp, - move, 0, 0); -#else - READ_RETURN(read_result, move, 0, 0); -#endif + if (acode == 0) { + READ_RETURN(OWL_ATTACK, str, depth - stackp, move, 0, 0); + } else { if (wormid) *wormid = saveworm; -#if USE_HASHTABLE_NG - READ_RETURN2_NG(OWL_ATTACK, str, depth - stackp, - move, mpos, acode, saveworm); -#else - READ_RETURN2(read_result, move, mpos, acode, saveworm); -#endif + READ_RETURN2(OWL_ATTACK, str, depth - stackp, + move, mpos, acode, saveworm); } } @@ -2002,12 +1876,7 @@ this_variation_number); SGFTRACE(0, WIN, "no defense"); close_pattern_list(other, &shape_patterns); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_ATTACK, str, depth - stackp, - move, 0, WIN); -#else - READ_RETURN(read_result, move, 0, WIN); -#endif + READ_RETURN(OWL_ATTACK, str, depth - stackp, move, 0, WIN); } else if (dpos != NO_MOVE) { /* The dragon could be defended by one more move. Try to @@ -2053,11 +1922,7 @@ TRACE("%oVariation %d: ALIVE (escaped)\n", this_variation_number); SGFTRACE(0, 0, "escaped"); close_pattern_list(other, &shape_patterns); -#if USE_HASHTABLE_NG - READ_RETURN0_NG(OWL_ATTACK, str, depth - stackp) -#else - READ_RETURN0(read_result); -#endif + READ_RETURN0(OWL_ATTACK, str, depth - stackp); } #endif @@ -2163,12 +2028,7 @@ SGFTRACE(mpos, WIN, winstr); } close_pattern_list(other, &shape_patterns); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_ATTACK, str, depth - stackp, - move, mpos, WIN); -#else - READ_RETURN(read_result, move, mpos, WIN); -#endif + READ_RETURN(OWL_ATTACK, str, depth - stackp, move, mpos, WIN); } else if (experimental_owl_ext && dcode == LOSS) { if (saveworm == MAX_GOAL_WORMS @@ -2247,21 +2107,12 @@ SGFTRACE(savemove, savecode, "attack effective (gain) - E"); if (wormid) *wormid = saveworm; -#if USE_HASHTABLE_NG - READ_RETURN2_NG(OWL_ATTACK, str, depth - stackp, - move, savemove, savecode, saveworm); -#else - READ_RETURN2(read_result, move, savemove, savecode, saveworm); -#endif + READ_RETURN2(OWL_ATTACK, str, depth - stackp, + move, savemove, savecode, saveworm); } else { SGFTRACE(savemove, savecode, "attack effective (ko) - E"); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_ATTACK, str, depth - stackp, - move, savemove, savecode); -#else - READ_RETURN(read_result, move, savemove, savecode); -#endif + READ_RETURN(OWL_ATTACK, str, depth - stackp, move, savemove, savecode); } } @@ -2271,11 +2122,8 @@ count_variations - this_variation_number); SGFTRACE(0, 0, winstr); } -#if USE_HASHTABLE_NG - READ_RETURN0_NG(OWL_ATTACK, str, depth - stackp); -#else - READ_RETURN0(read_result); -#endif + + READ_RETURN0(OWL_ATTACK, str, depth - stackp); } @@ -2491,14 +2339,9 @@ int escape_route; const char *live_reason; int move_cutoff; -# if USE_HASHTABLE_NG - int xpos; - int value1; - int value2; -#else - Read_result *read_result = NULL; - int found_read_result; -#endif + int xpos; + int value1; + int value2; int this_variation_number = count_variations - 1; SETUP_TRACE_INFO("owl_defend", str); @@ -2506,14 +2349,12 @@ shape_patterns.initialized = 0; str = find_origin(str); -#if USE_HASHTABLE_NG if ((hashflags & HASH_OWL_DEFEND) - && tt_get(&ttable, OWL_DEFEND, str, NO_MOVE, - depth - stackp, NULL, + && tt_get(&ttable, OWL_DEFEND, str, NO_MOVE, depth - stackp, NULL, &value1, &value2, &xpos) == 2) { - TRACE_CACHED_RESULT_NG(value1, xpos); + TRACE_CACHED_RESULT(value1, xpos); if (value1 != 0) { if (move) *move = xpos; @@ -2537,40 +2378,6 @@ return value1; } -#else - - if (hashflags & HASH_OWL_DEFEND) { - found_read_result = get_read_result(OWL_DEFEND, - &str, &read_result); - if (found_read_result) { - TRACE_CACHED_RESULT(*read_result); - if (rr_get_result(*read_result) != 0) { - if (move) - *move = rr_get_move(*read_result); - } - if (rr_get_result(*read_result) == LOSS) { - if (wormid) { - if (goal_worms_computed) - *wormid = rr_get_result2(*read_result); - else - *wormid = MAX_GOAL_WORMS; - } - } - - if (rr_get_result(*read_result) == WIN - || rr_get_result(*read_result) == LOSS) - TRACE("%oVariation %d: ALIVE (cached)\n", this_variation_number); - else - TRACE("%oVariation %d: DEAD (cached)\n", this_variation_number); - - SGFTRACE(rr_get_move(*read_result), rr_get_result(*read_result), - "cached"); - return rr_get_result(*read_result); - } - } - -#endif - /* In order to get a defense move even if we seem to already have * escaped and to reduce the impact of overestimated escape * possibilities, we don't declare escape victory on the first move. @@ -2586,23 +2393,13 @@ */ TRACE("%oVariation %d: ALIVE (escaped)\n", this_variation_number); SGFTRACE(0, WIN, "escaped"); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_DEFEND, str, depth - stackp, - move, 0, WIN); -#else - READ_RETURN(read_result, move, 0, WIN); -#endif + READ_RETURN(OWL_DEFEND, str, depth - stackp, move, 0, WIN); } /* If reading goes to deep or we run out of nodes, we assume life. */ if (reading_limit_reached(&live_reason, this_variation_number)) { SGFTRACE(0, WIN, live_reason); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_DEFEND, str, depth - stackp, - move, 0, WIN); -#else - READ_RETURN(read_result, move, 0, WIN); -#endif + READ_RETURN(OWL_DEFEND, str, depth - stackp, move, 0, WIN); } memset(mw, 0, sizeof(mw)); @@ -2619,12 +2416,7 @@ SGFTRACE(0, WIN, live_reason); TRACE("%oVariation %d: ALIVE (%s)\n", this_variation_number, live_reason); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_DEFEND, str, depth - stackp, - move, 0, WIN); -#else - READ_RETURN(read_result, move, 0, WIN); -#endif + READ_RETURN(OWL_DEFEND, str, depth - stackp, move, 0, WIN); } } else { @@ -2800,12 +2592,7 @@ SGFTRACE(mpos, WIN, winstr); } close_pattern_list(color, &shape_patterns); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_DEFEND, str, depth - stackp, - move, mpos, WIN); -#else - READ_RETURN(read_result, move, mpos, WIN); -#endif + READ_RETURN(OWL_DEFEND, str, depth - stackp, move, mpos, WIN); } if (acode == GAIN) saveworm = wid; @@ -2831,32 +2618,18 @@ SGFTRACE(savemove, savecode, "defense effective (loss) - B"); if (wormid) *wormid = saveworm; -#if USE_HASHTABLE_NG - READ_RETURN2_NG(OWL_DEFEND, str, depth - stackp, - move, savemove, savecode, saveworm); -#else - READ_RETURN2(read_result, move, savemove, savecode, saveworm); -#endif + READ_RETURN2(OWL_DEFEND, str, depth - stackp, + move, savemove, savecode, saveworm); } else { SGFTRACE(savemove, savecode, "defense effective (ko) - B"); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_DEFEND, str, depth - stackp, - move, savemove, savecode); -#else - READ_RETURN(read_result, move, savemove, savecode); -#endif + READ_RETURN(OWL_DEFEND, str, depth - stackp, move, savemove, savecode); } } if (number_tried_moves == 0 && min_eyes(&probable_eyes) >= 2) { SGFTRACE(0, WIN, "genus probably >= 2"); -#if USE_HASHTABLE_NG - READ_RETURN_NG(OWL_DEFEND, str, depth - stackp, - move, 0, WIN); -#else - READ_RETURN(read_result, move, 0, WIN); -#endif + READ_RETURN(OWL_DEFEND, str, depth - stackp, move, 0, WIN); } @@ -2868,11 +2641,7 @@ SGFTRACE(0, 0, winstr); } -#if USE_HASHTABLE_NG - READ_RETURN0_NG(OWL_DEFEND, str, depth - stackp); -#else - READ_RETURN0(read_result); -#endif + READ_RETURN0(OWL_DEFEND, str, depth - stackp); } Index: engine/readconnect.c =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/readconnect.c,v retrieving revision 1.79 diff -u -r1.79 readconnect.c --- engine/readconnect.c 19 May 2004 14:24:06 -0000 1.79 +++ engine/readconnect.c 22 May 2004 20:14:46 -0000 @@ -1935,12 +1935,7 @@ int savemove = NO_MOVE; int savecode = 0; int tried_moves = 0; -#if USE_HASHTABLE_NG - int value; -#else - int found_read_result; - Read_result *read_result = NULL; -#endif + int value; SETUP_TRACE_INFO2("recursive_connect2", str1, str2); @@ -1973,14 +1968,11 @@ str1 = find_origin(str1); str2 = find_origin(str2); -#if USE_HASHTABLE_NG - if (stackp <= depth && (hashflags & HASH_CONNECT) && !has_passed - && tt_get(&ttable, CONNECT, str1, str2, - depth - stackp, NULL, + && tt_get(&ttable, CONNECT, str1, str2, depth - stackp, NULL, &value, NULL, &xpos) == 2) { - TRACE_CACHED_RESULT2_NG(value, value, xpos); + TRACE_CACHED_RESULT2(value, value, xpos); if (value != 0) if (move) *move = xpos; @@ -1988,37 +1980,10 @@ SGFTRACE2(xpos, value, "cached"); return value; } - -#else - - if (stackp <= depth - && (hashflags & HASH_CONNECT) - && !has_passed) { - found_read_result = get_read_result2(CONNECT, - &str1, &str2, &read_result); - if (found_read_result) { - TRACE_CACHED_RESULT2(*read_result); - if (rr_get_result(*read_result) != 0) - if (move) - *move = rr_get_move(*read_result); - - SGFTRACE2(rr_get_move(*read_result), - rr_get_result(*read_result), "cached"); - return rr_get_result(*read_result); - } - } - -#endif if (trivial_connection(str1, str2, &xpos) == WIN) { SGFTRACE2(xpos, WIN, "trivial connection"); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(CONNECT, str1, str2, - depth - stackp, - move, xpos, WIN); -#else - READ_RETURN_CONN(read_result, move, xpos, WIN); -#endif + READ_RETURN_CONN(CONNECT, str1, str2, depth - stackp, move, xpos, WIN); } num_moves = find_string_connection_moves(str1, str2, color, @@ -2038,13 +2003,8 @@ popgo(); if (acode == 0) { SGFTRACE2(xpos, WIN, "connection effective"); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(CONNECT, str1, str2, - depth - stackp, - move, xpos, WIN); -#else - READ_RETURN_CONN(read_result, move, xpos, WIN); -#endif + READ_RETURN_CONN(CONNECT, str1, str2, depth - stackp, + move, xpos, WIN); } /* if the move works with ko we save it, then look for something * better. @@ -2065,34 +2025,17 @@ if (tried_moves == 0 && distance < 1.0) { SGFTRACE2(NO_MOVE, WIN, "no move, probably connected"); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(CONNECT, str1, str2, - depth - stackp, - move, NO_MOVE, WIN); -#else - READ_RETURN_CONN(read_result, move, NO_MOVE, WIN); -#endif + READ_RETURN_CONN(CONNECT, str1, str2, depth - stackp, move, NO_MOVE, WIN); } if (savecode != 0) { SGFTRACE2(savemove, savecode, "saved move"); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(CONNECT, str1, str2, - depth - stackp, - move, savemove, savecode); -#else - READ_RETURN_CONN(read_result, move, savemove, savecode); -#endif + READ_RETURN_CONN(CONNECT, str1, str2, depth - stackp, + move, savemove, savecode); } SGFTRACE2(0, 0, NULL); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(CONNECT, str1, str2, - depth - stackp, - move, NO_MOVE, 0); -#else - READ_RETURN_CONN(read_result, move, NO_MOVE, 0); -#endif + READ_RETURN_CONN(CONNECT, str1, str2, depth - stackp, move, NO_MOVE, 0); } @@ -2131,12 +2074,7 @@ int attack_pos2; SGFTree *save_sgf_dumptree = sgf_dumptree; int save_count_variations = count_variations; -#if USE_HASHTABLE_NG - int value; -#else - int found_read_result; - Read_result *read_result = NULL; -#endif + int value; SETUP_TRACE_INFO2("recursive_disconnect2", str1, str2); @@ -2199,12 +2137,12 @@ sgf_dumptree = save_sgf_dumptree; count_variations = save_count_variations; -#if USE_HASHTABLE_NG - if ((stackp <= depth) && (hashflags & HASH_DISCONNECT) + if (stackp <= depth + && (hashflags & HASH_DISCONNECT) && tt_get(&ttable, DISCONNECT, str1, str2, depth - stackp, NULL, &value, NULL, &xpos) == 2) { - TRACE_CACHED_RESULT2_NG(value, value, xpos); + TRACE_CACHED_RESULT2(value, value, xpos); if (value != 0) if (move) *move = xpos; @@ -2213,45 +2151,14 @@ return value; } -#else - - if ((stackp <= depth) && (hashflags & HASH_DISCONNECT)) { - found_read_result = get_read_result2(DISCONNECT, - &str1, &str2, &read_result); - if (found_read_result) { - TRACE_CACHED_RESULT2(*read_result); - if (rr_get_result(*read_result) != 0) - if (move) - *move = rr_get_move(*read_result); - - SGFTRACE2(rr_get_move(*read_result), - rr_get_result(*read_result), "cached"); - return rr_get_result(*read_result); - } - } - -#endif - if (ladder_capture(str1, &xpos) == WIN) { SGFTRACE2(xpos, WIN, "first string capturable"); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(DISCONNECT, str1, str2, - depth - stackp, - move, xpos, WIN); -#else - READ_RETURN_CONN(read_result, move, xpos, WIN); -#endif + READ_RETURN_CONN(DISCONNECT, str1, str2, depth - stackp, move, xpos, WIN); } if (ladder_capture(str2, &xpos) == WIN) { SGFTRACE2(xpos, WIN, "second string capturable"); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(DISCONNECT, str1, str2, - depth - stackp, - move, xpos, WIN); -#else - READ_RETURN_CONN(read_result, move, xpos, WIN); -#endif + READ_RETURN_CONN(DISCONNECT, str1, str2, depth - stackp, move, xpos, WIN); } num_moves = find_string_connection_moves(str1, str2, other, @@ -2290,13 +2197,8 @@ popgo(); if (dcode == 0) { SGFTRACE2(xpos, WIN, "disconnection effective"); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(DISCONNECT, str1, str2, - depth - stackp, - move, xpos, WIN); -#else - READ_RETURN_CONN(read_result, move, xpos, WIN); -#endif + READ_RETURN_CONN(DISCONNECT, str1, str2, depth - stackp, + move, xpos, WIN); } /* if the move works with ko we save it, then look for something * better. @@ -2320,34 +2222,18 @@ && (has_passed || !recursive_connect2(str1, str2, NULL, 1))) { SGFTRACE2(NO_MOVE, WIN, "no move, probably disconnected"); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(DISCONNECT, str1, str2, - depth - stackp, - move, NO_MOVE, WIN); -#else - READ_RETURN_CONN(read_result, move, NO_MOVE, WIN); -#endif + READ_RETURN_CONN(DISCONNECT, str1, str2, depth - stackp, + move, NO_MOVE, WIN); } if (savecode != 0) { SGFTRACE2(savemove, savecode, "saved move"); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(DISCONNECT, str1, str2, - depth - stackp, - move, savemove, savecode); -#else - READ_RETURN_CONN(read_result, move, savemove, savecode); -#endif + READ_RETURN_CONN(DISCONNECT, str1, str2, depth - stackp, + move, savemove, savecode); } SGFTRACE2(0, 0, NULL); -#if USE_HASHTABLE_NG - READ_RETURN_CONN_NG(DISCONNECT, str1, str2, - depth - stackp, - move, NO_MOVE, 0); -#else - READ_RETURN_CONN(read_result, move, NO_MOVE, 0); -#endif + READ_RETURN_CONN(DISCONNECT, str1, str2, depth - stackp, move, NO_MOVE, 0); } @@ -2888,12 +2774,7 @@ int savemove = NO_MOVE; int savecode = 0; int tried_moves = 0; -#if USE_HASHTABLE_NG int retval; -#else - int found_read_result; - Read_result *read_result = NULL; -#endif SETUP_TRACE_INFO("recursive_break", str); @@ -2918,7 +2799,6 @@ return 0; } -#if USE_HASHTABLE_NG str = find_origin(str); if (stackp <= depth && (hashflags & HASH_BREAK_IN) @@ -2927,36 +2807,18 @@ depth - stackp, goal_hash, &retval, NULL, &xpos) == 2) { /* FIXME: Use move for move ordering if tt_get() returned 1 */ - TRACE_CACHED_RESULT_NG(retval, xpos); + TRACE_CACHED_RESULT(retval, xpos); SGFTRACE(xpos, retval, "cached"); if (move) *move = xpos; return retval; } -#else - if (stackp <= depth - && (hashflags & HASH_BREAK_IN) - && !has_passed) { - found_read_result - = get_read_result_hash_modified(BREAK_IN, - &str, goal_hash, &read_result); - if (found_read_result) { - TRACE_CACHED_RESULT(*read_result); - if (rr_get_result(*read_result) != 0) - if (move) - *move = rr_get_move(*read_result); - - SGFTRACE(rr_get_move(*read_result), - rr_get_result(*read_result), "cached"); - return rr_get_result(*read_result); - } - } -#endif #if 0 if (trivial_connection(str1, str2, &xpos) == WIN) { SGFTRACE2(xpos, WIN, "trivial connection"); - READ_RETURN_CONN(read_result, move, xpos, WIN); + READ_RETURN_HASH(BREAK_IN, str, depth - stackp, goal_hash, + move, xpos, WIN); } #endif @@ -2976,12 +2838,8 @@ popgo(); if (acode == 0) { SGFTRACE(xpos, WIN, "break effective"); -#if USE_HASHTABLE_NG - READ_RETURN_HASH_NG(BREAK_IN, str, depth - stackp, - goal_hash, move, xpos, WIN); -#else - READ_RETURN(read_result, move, xpos, WIN); -#endif + READ_RETURN_HASH(BREAK_IN, str, depth - stackp, goal_hash, + move, xpos, WIN); } /* if the move works with ko we save it, then look for something * better. @@ -3005,31 +2863,18 @@ */ if (tried_moves == 0 && distance < 0.89) { SGFTRACE(NO_MOVE, WIN, "no move, probably connected"); -#if USE_HASHTABLE_NG - READ_RETURN_HASH_NG(BREAK_IN, str, depth - stackp, - goal_hash, move, NO_MOVE, WIN); -#else - READ_RETURN(read_result, move, NO_MOVE, WIN); -#endif + READ_RETURN_HASH(BREAK_IN, str, depth - stackp, goal_hash, + move, NO_MOVE, WIN); } if (savecode != 0) { SGFTRACE(savemove, savecode, "saved move"); -#if USE_HASHTABLE_NG - READ_RETURN_HASH_NG(BREAK_IN, str, depth - stackp, - goal_hash, move, savemove, savecode); -#else - READ_RETURN(read_result, move, savemove, savecode); -#endif + READ_RETURN_HASH(BREAK_IN, str, depth - stackp, goal_hash, + move, savemove, savecode); } SGFTRACE(0, 0, NULL); -#if USE_HASHTABLE_NG - READ_RETURN_HASH_NG(BREAK_IN, str, depth - stackp, - goal_hash, move, NO_MOVE, 0); -#else - READ_RETURN(read_result, move, NO_MOVE, 0); -#endif + READ_RETURN_HASH(BREAK_IN, str, depth - stackp, goal_hash, move, NO_MOVE, 0); } @@ -3049,12 +2894,7 @@ int savemove = NO_MOVE; int savecode = 0; int tried_moves = 0; -#if USE_HASHTABLE_NG int retval; -#else - int found_read_result; - Read_result *read_result = NULL; -#endif SETUP_TRACE_INFO("recursive_block", str); nodes_connect++; @@ -3085,44 +2925,22 @@ return WIN; } -#if USE_HASHTABLE_NG str = find_origin(str); - if ((stackp <= depth) + if (stackp <= depth && (hashflags & HASH_BLOCK_OFF) - && (tt_get(&ttable, BLOCK_OFF, str, NO_MOVE, - depth - stackp, goal_hash, &retval, NULL, &xpos) == 2)) { - TRACE_CACHED_RESULT_NG(retval, xpos); + && tt_get(&ttable, BLOCK_OFF, str, NO_MOVE, + depth - stackp, goal_hash, &retval, NULL, &xpos) == 2) { + TRACE_CACHED_RESULT(retval, xpos); SGFTRACE(xpos, retval, "cached"); if (move) *move = xpos; return retval; } -#else - if ((stackp <= depth) && (hashflags & HASH_BLOCK_OFF)) { - found_read_result - = get_read_result_hash_modified(BLOCK_OFF, - &str, goal_hash, &read_result); - if (found_read_result) { - TRACE_CACHED_RESULT(*read_result); - if (rr_get_result(*read_result) != 0) - if (move) - *move = rr_get_move(*read_result); - - SGFTRACE(rr_get_move(*read_result), - rr_get_result(*read_result), "cached"); - return rr_get_result(*read_result); - } - } -#endif if (ladder_capture(str, &xpos) == WIN) { SGFTRACE(xpos, WIN, "string capturable"); -#if USE_HASHTABLE_NG - READ_RETURN_HASH_NG(BLOCK_OFF, str, depth - stackp, - goal_hash, move, xpos, WIN); -#else - READ_RETURN(read_result, move, xpos, WIN); -#endif + READ_RETURN_HASH(BLOCK_OFF, str, depth - stackp, goal_hash, + move, xpos, WIN); } num_moves = find_break_moves(str, goal, other, moves, &distance); @@ -3141,12 +2959,8 @@ popgo(); if (dcode == 0) { SGFTRACE(xpos, WIN, "block effective"); -#if USE_HASHTABLE_NG - READ_RETURN_HASH_NG(BLOCK_OFF, str, - depth - stackp, goal_hash, move, xpos, WIN); -#else - READ_RETURN(read_result, move, xpos, WIN); -#endif + READ_RETURN_HASH(BLOCK_OFF, str, depth - stackp, goal_hash, + move, xpos, WIN); } /* if the move works with ko we save it, then look for something * better. @@ -3170,31 +2984,19 @@ || !recursive_break(str, goal, NULL, 1, goal_hash))) { SGFTRACE(NO_MOVE, WIN, "no move, probably disconnected"); -#if USE_HASHTABLE_NG - READ_RETURN_HASH_NG(BLOCK_OFF, str, - depth - stackp, goal_hash, move, NO_MOVE, WIN); -#else - READ_RETURN(read_result, move, NO_MOVE, WIN); -#endif + READ_RETURN_HASH(BLOCK_OFF, str, depth - stackp, goal_hash, + move, NO_MOVE, WIN); } if (savecode != 0) { SGFTRACE(savemove, savecode, "saved move"); -#if USE_HASHTABLE_NG - READ_RETURN_HASH_NG(BLOCK_OFF, str, - depth - stackp, goal_hash, move, savemove, savecode); -#else - READ_RETURN(read_result, move, savemove, savecode); -#endif + READ_RETURN_HASH(BLOCK_OFF, str, depth - stackp, goal_hash, + move, savemove, savecode); } SGFTRACE(0, 0, NULL); -#if USE_HASHTABLE_NG - READ_RETURN_HASH_NG(BLOCK_OFF, str, - depth - stackp, goal_hash, move, NO_MOVE, 0); -#else - READ_RETURN(read_result, move, NO_MOVE, 0); -#endif + READ_RETURN_HASH(BLOCK_OFF, str, depth - stackp, goal_hash, + move, NO_MOVE, 0); } Index: engine/reading.c =================================================================== RCS file: /cvsroot/gnugo/gnugo/engine/reading.c,v retrieving revision 1.141 diff -u -r1.141 reading.c --- engine/reading.c 19 May 2004 14:24:15 -0000 1.141 +++ engine/reading.c 22 May 2004 20:14:47 -0000 @@ -1163,12 +1163,7 @@ int xpos = NO_MOVE; int dcode = 0; int liberties; -#if !USE_HASHTABLE_NG - int found_read_result; - Read_result *read_result = NULL; -#else int retval; -#endif SETUP_TRACE_INFO("find_defense", str); @@ -1199,41 +1194,20 @@ if (liberties > 2 && move) xpos = *move; -#if USE_HASHTABLE_NG - - if ((stackp <= depth) && (hashflags & HASH_FIND_DEFENSE) - && tt_get(&ttable, FIND_DEFENSE, str, NO_MOVE, - depth - stackp, NULL, + if (stackp <= depth + && (hashflags & HASH_FIND_DEFENSE) + && tt_get(&ttable, FIND_DEFENSE, str, NO_MOVE, depth - stackp, NULL, &retval, NULL, &xpos) == 2) { /* Note that if return value is 1 (too small depth), the move will * still be used for move ordering. */ - TRACE_CACHED_RESULT_NG(retval, xpos); + TRACE_CACHED_RESULT(retval, xpos); SGFTRACE(xpos, retval, "cached"); if (move) *move = xpos; return retval; } -#else - - if ((stackp <= depth) && (hashflags & HASH_FIND_DEFENSE)) { - found_read_result = get_read_result(FIND_DEFENSE, - &str, &read_result); - if (found_read_result) { - TRACE_CACHED_RESULT(*read_result); - if (rr_get_result(*read_result) != 0) - if (move) - *move = rr_get_move(*read_result); - - SGFTRACE(rr_get_move(*read_result), - rr_get_result(*read_result), "cached"); - return rr_get_result(*read_result); - } - } - -#endif - #if EXPERIMENTAL_READING if (defend_by_pattern) { dcode = do_defend_pat(str, &xpos); @@ -1252,19 +1226,10 @@ dcode = defend4(str, &xpos); if (dcode) { -#if USE_HASHTABLE_NG - READ_RETURN_NG(FIND_DEFENSE, str, depth - stackp, - move, xpos, dcode); -#else - READ_RETURN(read_result, move, xpos, dcode); -#endif + READ_RETURN(FIND_DEFENSE, str, depth - stackp, move, xpos, dcode); } -#if USE_HASHTABLE_NG - READ_RETURN0_NG(FIND_DEFENSE, str, depth - stackp); -#else - READ_RETURN0(read_result); -#endif + READ_RETURN0(FIND_DEFENSE, str, depth - stackp); } @@ -2955,12 +2920,7 @@ int xpos = NO_MOVE; int liberties; int result = 0; -#if !USE_HASHTABLE_NG - int found_read_result; - Read_result *read_result = NULL; -#else - int retval; -#endif + int retval; SETUP_TRACE_INFO("attack", str); @@ -2992,41 +2952,20 @@ if (liberties > 3 && move) xpos = *move; -#if USE_HASHTABLE_NG - /* Note that if return value is 1 (too small depth), the move will * still be used for move ordering. */ - if ((stackp <= depth) && (hashflags & HASH_ATTACK) - && tt_get(&ttable, ATTACK, str, NO_MOVE, - depth - stackp, NULL, + if (stackp <= depth + && (hashflags & HASH_ATTACK) + && tt_get(&ttable, ATTACK, str, NO_MOVE, depth - stackp, NULL, &retval, NULL, &xpos) == 2) { - TRACE_CACHED_RESULT_NG(retval, xpos); + TRACE_CACHED_RESULT(retval, xpos); SGFTRACE(xpos, retval, "cached"); if (move) *move = xpos; return retval; } -#else - - if ((stackp <= depth) && (hashflags & HASH_ATTACK)) { - found_read_result = get_read_result(ATTACK, - &str, &read_result); - if (found_read_result) { - TRACE_CACHED_RESULT(*read_result); - if (rr_get_result(*read_result) != 0) - if (move) - *move = rr_get_move(*read_result); - - SGFTRACE(rr_get_move(*read_result), - rr_get_result(*read_result), "cached"); - return rr_get_result(*read_result); - } - } - -#endif - #if EXPERIMENTAL_READING if (attack_by_pattern) { result = do_attack_pat(str, &xpos); @@ -3053,19 +2992,11 @@ ASSERT1(result >= 0 && result <= WIN, str); - if (result) -#if USE_HASHTABLE_NG - READ_RETURN_NG(ATTACK, str, depth - stackp, - move, xpos, result); -#else - READ_RETURN(read_result, move, xpos, result); -#endif + if (result) { + READ_RETURN(ATTACK, str, depth - stackp, move, xpos, result); + } -#if USE_HASHTABLE_NG - READ_RETURN0_NG(ATTACK, str, depth - stackp); -#else - READ_RETURN0(read_result); -#endif + READ_RETURN0(ATTACK, str, depth - stackp); }