void fc_solve_instance__init_hard_thread( fc_solve_instance_t * instance, fc_solve_hard_thread_t * hard_thread ) { hard_thread->instance = instance; hard_thread->num_soft_threads = 0; hard_thread->soft_threads = NULL; fc_solve_new_soft_thread(hard_thread); /* Set a limit on the Hard-Thread's scan. */ hard_thread->num_times_step = NUM_TIMES_STEP; hard_thread->prelude_as_string = NULL; hard_thread->prelude = NULL; hard_thread->prelude_num_items = 0; hard_thread->prelude_idx = 0; fc_solve_reset_hard_thread(hard_thread); fc_solve_compact_allocator_init(&(hard_thread->allocator)); fcs_move_stack_init(hard_thread->reusable_move_stack); }
static inline void instance_init(fcs_dbm_solver_instance_t *const instance, const fcs_dbm_variant_type_t local_variant, fcs_cache_key_t *init_state, long max_num_elements_in_cache) { instance->local_variant = local_variant; instance->solution_was_found = FALSE; instance->should_terminate = DONT_TERMINATE; instance->count_num_processed = 0; instance->max_count_num_processed = LONG_MAX; instance->store = (Pvoid_t)NULL; instance->stack = NULL; instance->max_stack_depth = 0; instance->stack_depth = 0; fc_solve_meta_compact_allocator_init(&(instance->meta_alloc)); fc_solve_compact_allocator_init( &(instance->derived_list_allocator), &(instance->meta_alloc)); instance->derived_list_recycle_bin = NULL; fcs_pdfs_cache_init( &(instance->cache), max_num_elements_in_cache, &(instance->meta_alloc)); insert_state(&(instance->store), init_state); instance__inspect_new_state(instance, init_state); }
dict_t *dict_init(dict_t *dict, dict_comp_t comp) #endif { dict->compare = comp; /* Removed for fc-solve. */ #if 0 dict->allocnode = dnode_alloc; dict->freenode = dnode_free; #else fc_solve_compact_allocator_init(&(dict->dict_allocator)); dict->dict_recycle_bin = NULL; #endif dict->context = NULL; #ifdef NO_FC_SOLVE dict->nodecount = 0; dict->maxcount = maxcount; #endif dict->nilnode.left = &dict->nilnode; dict->nilnode.right = &dict->nilnode; dict->nilnode.parent = &dict->nilnode; dict->nilnode.color = dnode_black; #ifdef NO_FC_SOLVE dict->dupes = 0; #endif return dict; }
/* This is the commmon code from alloc_hard_thread() and * recycle_hard_thread() */ static GCC_INLINE void reset_hard_thread( fc_solve_hard_thread_t * hard_thread ) { hard_thread->num_times = 0; hard_thread->ht_max_num_times = hard_thread->num_times_step; hard_thread->max_num_times = -1; hard_thread->num_soft_threads_finished = 0; fc_solve_compact_allocator_init(&(hard_thread->allocator)); }
static inline void instance_init(fcs_dbm_solver_instance_t *const instance, const fcs_dbm_common_input_t *const inp, fcs_which_moves_bitmask_t *fingerprint_which_irreversible_moves_bitmask, FILE *out_fh) { fc_solve_meta_compact_allocator_init(&(instance->fcc_meta_alloc)); instance->fcc_entry_points = FccEntryPointList_init; fc_solve_compact_allocator_init( &(instance->fcc_entry_points_allocator), &(instance->fcc_meta_alloc)); instance->start_key_ptr = NULL; instance->dbm_store_path = inp->dbm_store_path; instance->fingerprint_which_irreversible_moves_bitmask = (*fingerprint_which_irreversible_moves_bitmask); instance->moves_base64_encoding_buffer = NULL; instance->moves_base64_encoding_buffer_max_len = 0; { int curr_depth = 0; { for (size_t i = 0; i < COUNT(fingerprint_which_irreversible_moves_bitmask->s); i++) { unsigned char c = fingerprint_which_irreversible_moves_bitmask->s[i]; while (c != 0) { curr_depth += (c & 0x3); c >>= 2; } } } instance->curr_depth = curr_depth; } fcs_lock_init(&instance->global_lock); instance->offload_dir_path = inp->offload_dir_path; fcs_dbm__common_init(&(instance->common), inp->iters_delta_limit, inp->local_variant, out_fh); fcs_lock_init(&instance->output_lock); fcs_lock_init(&instance->fcc_entry_points_lock); fcs_lock_init(&instance->fcc_exit_points_output_lock); { fcs_dbm_collection_by_depth_t *const coll = &(instance->coll); fcs_dbm__cache_store__init(&(coll->cache_store), &(instance->common), &(coll->queue_meta_alloc), inp->dbm_store_path, inp->pre_cache_max_count, inp->caches_delta); } }
/* * The char * returned is malloc()ed and should be free()ed. */ DLLEXPORT int fc_solve_user_INTERNAL_calc_derived_states_wrapper( enum fcs_dbm_variant_type_t local_variant, const char * init_state_str_proto, int * const num_out_derived_states, fcs_derived_state_debug_t * * out_derived_states, const fcs_bool_t perform_horne_prune ) { fcs_state_keyval_pair_t init_state; fc_solve_delta_stater_t * delta; fcs_encoded_state_buffer_t enc_state; fcs_state_locs_struct_t locs; fcs_derived_state_t * derived_list = NULL; fcs_derived_state_t * derived_list_recycle_bin = NULL; fcs_compact_allocator_t allocator; fcs_meta_compact_allocator_t meta_alloc; int states_count = 0; fcs_derived_state_t * iter; fcs_derived_state_debug_t * debug_ret; int idx = 0; DECLARE_IND_BUF_T(indirect_stacks_buffer) fc_solve_initial_user_state_to_c( init_state_str_proto, &init_state, FREECELLS_NUM, STACKS_NUM, DECKS_NUM, indirect_stacks_buffer ); delta = fc_solve_delta_stater_alloc( &(init_state.s), STACKS_NUM, FREECELLS_NUM #ifndef FCS_FREECELL_ONLY , FCS_SEQ_BUILT_BY_ALTERNATE_COLOR #endif ); fcs_init_and_encode_state( delta, local_variant, &(init_state), &enc_state ); fc_solve_meta_compact_allocator_init (&meta_alloc); fc_solve_compact_allocator_init( &allocator, &meta_alloc); instance_solver_thread_calc_derived_states( local_variant, &init_state, NULL, &derived_list, &derived_list_recycle_bin, &allocator, perform_horne_prune ); iter = derived_list; while (iter) { states_count++; iter = iter->next; } *(num_out_derived_states) = states_count; debug_ret = SMALLOC(debug_ret, states_count); *(out_derived_states) = debug_ret; fc_solve_init_locs(&locs); iter = derived_list; while (iter) { debug_ret[idx].state_string = fc_solve_state_as_string( &(iter->state.s), &locs, FREECELLS_NUM, STACKS_NUM, DECKS_NUM, 1, 0, 1 ); debug_ret[idx].move = iter->move; debug_ret[idx].core_irreversible_moves_count = iter->core_irreversible_moves_count; debug_ret[idx].num_non_reversible_moves_including_prune = iter->num_non_reversible_moves_including_prune; /* TODO : Put something meaningful there by passing it to the function. */ debug_ret[idx].which_irreversible_moves_bitmask = iter->which_irreversible_moves_bitmask; idx++; iter = iter->next; } assert(idx == states_count); fc_solve_compact_allocator_finish(&allocator); fc_solve_meta_compact_allocator_finish( &meta_alloc ); fc_solve_delta_stater_free (delta); return 0; }
/* * The char * returned is malloc()ed and should be free()ed. */ DLLEXPORT int fc_solve_user_INTERNAL_calc_derived_states_wrapper( fcs_dbm_variant_type_t local_variant, const char *init_state_str_proto, int *const num_out_derived_states, fcs_derived_state_debug_t **out_derived_states, const fcs_bool_t perform_horne_prune) { fcs_state_keyval_pair_t init_state; fcs_encoded_state_buffer_t enc_state; fcs_state_locs_struct_t locs; fcs_derived_state_t *derived_list = NULL; fcs_derived_state_t *derived_list_recycle_bin = NULL; fcs_compact_allocator_t allocator; fcs_meta_compact_allocator_t meta_alloc; size_t states_count = 0; fcs_derived_state_t *iter; DECLARE_IND_BUF_T(indirect_stacks_buffer) fc_solve_initial_user_state_to_c(init_state_str_proto, &init_state, FREECELLS_NUM, STACKS_NUM, DECKS_NUM, indirect_stacks_buffer); fc_solve_delta_stater_t delta; fc_solve_delta_stater_init( &delta, &(init_state.s), STACKS_NUM, FREECELLS_NUM #ifndef FCS_FREECELL_ONLY , FCS_SEQ_BUILT_BY_ALTERNATE_COLOR #endif ); fcs_init_and_encode_state(&delta, local_variant, &(init_state), &enc_state); fc_solve_meta_compact_allocator_init(&meta_alloc); fc_solve_compact_allocator_init(&allocator, &meta_alloc); instance_solver_thread_calc_derived_states(local_variant, &init_state, NULL, &derived_list, &derived_list_recycle_bin, &allocator, perform_horne_prune); iter = derived_list; while (iter) { states_count++; iter = iter->next; } *(num_out_derived_states) = states_count; fcs_derived_state_debug_t *const debug_ret = SMALLOC(debug_ret, states_count); *(out_derived_states) = debug_ret; fc_solve_init_locs(&locs); iter = derived_list; size_t idx = 0; while (iter) { debug_ret[idx] = (typeof(debug_ret[idx])){ .state_string = SMALLOC(debug_ret[idx].state_string, 1000), .move = iter->move, .core_irreversible_moves_count = iter->core_irreversible_moves_count, .num_non_reversible_moves_including_prune = iter->num_non_reversible_moves_including_prune, .which_irreversible_moves_bitmask = iter->which_irreversible_moves_bitmask}; FCS__RENDER_STATE(debug_ret[idx].state_string, &(iter->state.s), &locs); /* TODO : Put something meaningful there by passing it to the function. */ idx++; iter = iter->next; } assert(idx == states_count); fc_solve_compact_allocator_finish(&allocator); fc_solve_meta_compact_allocator_finish(&meta_alloc); fc_solve_delta_stater_release(&delta); return 0; } /* * The char * returned is malloc()ed and should be free()ed. */ DLLEXPORT int fc_solve_user_INTERNAL_perform_horne_prune( fcs_dbm_variant_type_t local_variant, const char *init_state_str_proto, char **ret_state_s) { fcs_state_keyval_pair_t init_state; fcs_state_locs_struct_t locs; int prune_ret; DECLARE_IND_BUF_T(indirect_stacks_buffer) fc_solve_init_locs(&locs); fc_solve_initial_user_state_to_c(init_state_str_proto, &init_state, FREECELLS_NUM, STACKS_NUM, DECKS_NUM, indirect_stacks_buffer); prune_ret = horne_prune__simple(local_variant, &init_state); *ret_state_s = SMALLOC(*ret_state_s, 1000); FCS__RENDER_STATE(*ret_state_s, &(init_state.s), &locs); return prune_ret; }
/* * The char * returned is malloc()ed and should be free()ed. */ DLLEXPORT int fc_solve_user_INTERNAL_find_fcc_start_points( enum fcs_dbm_variant_type_t local_variant, const char * init_state_str_proto, const int start_state_moves_count, const fcs_fcc_move_t * const start_state_moves, fcs_FCC_start_point_result_t * * out_fcc_start_points, long * out_num_new_positions ) { fcs_state_keyval_pair_t init_state; fc_solve_delta_stater_t * delta; fcs_encoded_state_buffer_t enc_state; fcs_state_locs_struct_t locs; int i; fcs_meta_compact_allocator_t meta_alloc; fcs_FCC_start_points_list_t start_points_list; dict_t * do_next_fcc_start_points_exist; dict_t * does_min_by_sorting_exist; fcs_lru_cache_t does_state_exist_in_any_FCC_cache; const int max_num_elements_in_cache = 1000; fcs_bool_t is_min_by_sorting_new; fcs_encoded_state_buffer_t min_by_sorting; fcs_fcc_moves_seq_allocator_t moves_list_allocator; fcs_fcc_moves_seq_t start_state_moves_seq; int states_count = 0; fcs_FCC_start_point_t * iter; fcs_FCC_start_point_result_t * ret; add_start_point_context_t add_start_point_context; void * tree_recycle_bin = NULL; fcs_compact_allocator_t moves_list_compact_alloc; DECLARE_IND_BUF_T(indirect_stacks_buffer) fc_solve_initial_user_state_to_c( init_state_str_proto, &init_state, FREECELLS_NUM, STACKS_NUM, DECKS_NUM, indirect_stacks_buffer ); delta = fc_solve_delta_stater_alloc( &(init_state.s), STACKS_NUM, FREECELLS_NUM #ifndef FCS_FREECELL_ONLY , FCS_SEQ_BUILT_BY_ALTERNATE_COLOR #endif ); fcs_init_and_encode_state( delta, local_variant, &(init_state), &enc_state ); start_points_list.list = NULL; start_points_list.recycle_bin = NULL; fc_solve_meta_compact_allocator_init( &meta_alloc ); fc_solve_compact_allocator_init(&(start_points_list.allocator), &meta_alloc); do_next_fcc_start_points_exist = fc_solve_kaz_tree_create(fc_solve_compare_encoded_states, NULL, &meta_alloc, &tree_recycle_bin); does_min_by_sorting_exist = fc_solve_kaz_tree_create(fc_solve_compare_encoded_states, NULL, &meta_alloc, &tree_recycle_bin); cache_init(&does_state_exist_in_any_FCC_cache, max_num_elements_in_cache, &meta_alloc); fc_solve_compact_allocator_init(&(moves_list_compact_alloc), &(meta_alloc)); moves_list_allocator.recycle_bin = NULL; moves_list_allocator.allocator = &(moves_list_compact_alloc); start_state_moves_seq.count = start_state_moves_count; start_state_moves_seq.moves_list = NULL; { fcs_fcc_moves_list_item_t * * moves_iter = &(start_state_moves_seq.moves_list); for ( i=0 ; i < start_state_moves_count ; ) { if (i % FCS_FCC_NUM_MOVES_IN_ITEM == 0) { *(moves_iter) = fc_solve_fcc_alloc_moves_list_item(&moves_list_allocator); } (*moves_iter)->data.s[i % FCS_FCC_NUM_MOVES_IN_ITEM] = start_state_moves[i]; if ((++i) % FCS_FCC_NUM_MOVES_IN_ITEM == 0) { moves_iter = &((*moves_iter)->next); } } } add_start_point_context.do_next_fcc_start_points_exist = do_next_fcc_start_points_exist; add_start_point_context.next_start_points_list = &start_points_list; add_start_point_context.moves_list_allocator = &moves_list_allocator; perform_FCC_brfs( local_variant, &(init_state), enc_state, &start_state_moves_seq, fc_solve_add_start_point_in_mem, &add_start_point_context, &is_min_by_sorting_new, &min_by_sorting, does_min_by_sorting_exist, &does_state_exist_in_any_FCC_cache, out_num_new_positions, &moves_list_allocator, &meta_alloc ); iter = start_points_list.list; while (iter) { states_count++; iter = iter->next; } *out_fcc_start_points = ret = SMALLOC(ret, states_count+1); ret[states_count].count = 0; fc_solve_init_locs(&locs); iter = start_points_list.list; for (i = 0; i < states_count ; i++) { fcs_state_keyval_pair_t state; DECLARE_IND_BUF_T(state_indirect_stacks_buffer) ret[i].count = iter->moves_seq.count; ret[i].moves = SMALLOC(ret[i].moves, ret[i].count); { int moves_idx; fcs_fcc_moves_list_item_t * moves_iter = iter->moves_seq.moves_list; for (moves_idx = 0 ; moves_idx < ret[i].count ; ) { ret[i].moves[moves_idx] = moves_iter->data.s[moves_idx % FCS_FCC_NUM_MOVES_IN_ITEM]; if ((++moves_idx) % FCS_FCC_NUM_MOVES_IN_ITEM == 0) { moves_iter = moves_iter->next; } } } fc_solve_delta_stater_decode_into_state(delta, iter->enc_state.s, &(state), state_indirect_stacks_buffer); ret[i].state_as_string = fc_solve_state_as_string( &(state.s), &locs, FREECELLS_NUM, STACKS_NUM, DECKS_NUM, 1, 0, 1 ); iter = iter->next; } fc_solve_compact_allocator_finish(&(start_points_list.allocator)); fc_solve_compact_allocator_finish(&(moves_list_compact_alloc)); fc_solve_delta_stater_free (delta); fc_solve_kaz_tree_destroy(do_next_fcc_start_points_exist); fc_solve_kaz_tree_destroy(does_min_by_sorting_exist); cache_destroy(&does_state_exist_in_any_FCC_cache); fc_solve_meta_compact_allocator_finish( &meta_alloc ); return 0; }
DLLEXPORT int fc_solve_user_INTERNAL_is_fcc_new( enum fcs_dbm_variant_type_t local_variant, const char * init_state_str_proto, const char * start_state_str_proto, /* NULL-terminated */ const char * * min_states, /* NULL-terminated */ const char * * states_in_cache, fcs_bool_t * const out_is_fcc_new ) { fcs_state_keyval_pair_t init_state; fc_solve_delta_stater_t * delta; fcs_encoded_state_buffer_t enc_state; fcs_encoded_state_buffer_t start_enc_state; fcs_meta_compact_allocator_t meta_alloc; fcs_FCC_start_points_list_t start_points_list; dict_t * do_next_fcc_start_points_exist; dict_t * does_min_by_sorting_exist; fcs_compact_allocator_t temp_allocator; fcs_fcc_moves_seq_allocator_t moves_list_allocator; const int max_num_elements_in_cache = 1000000; fcs_lru_cache_t does_state_exist_in_any_FCC_cache; fcs_encoded_state_buffer_t min_by_sorting; fcs_fcc_moves_seq_t init_moves_seq; add_start_point_context_t add_start_point_context; void * tree_recycle_bin = NULL; DECLARE_IND_BUF_T(indirect_stacks_buffer) fc_solve_initial_user_state_to_c( init_state_str_proto, &init_state, FREECELLS_NUM, STACKS_NUM, DECKS_NUM, indirect_stacks_buffer ); delta = fc_solve_delta_stater_alloc( &(init_state.s), STACKS_NUM, FREECELLS_NUM #ifndef FCS_FREECELL_ONLY , FCS_SEQ_BUILT_BY_ALTERNATE_COLOR #endif ); fcs_init_and_encode_state( delta, local_variant, &(init_state), &enc_state ); fc_solve_state_string_to_enc( local_variant, delta, start_state_str_proto, &(start_enc_state) ); fc_solve_meta_compact_allocator_init( &meta_alloc ); start_points_list.list = NULL; start_points_list.recycle_bin = NULL; fc_solve_compact_allocator_init(&(start_points_list.allocator), &meta_alloc); do_next_fcc_start_points_exist = fc_solve_kaz_tree_create(fc_solve_compare_encoded_states, NULL, &meta_alloc, &tree_recycle_bin); does_min_by_sorting_exist = fc_solve_kaz_tree_create(fc_solve_compare_encoded_states, NULL, &meta_alloc, &tree_recycle_bin); fc_solve_compact_allocator_init(&(temp_allocator), &meta_alloc); moves_list_allocator.recycle_bin = NULL; moves_list_allocator.allocator = &(temp_allocator); /* Populate does_min_by_sorting_exist from min_states */ { const char * * min_states_iter = min_states; for (; *(min_states_iter) ; min_states_iter++) { fcs_encoded_state_buffer_t * min_enc_state; min_enc_state = (fcs_encoded_state_buffer_t *) fcs_compact_alloc_ptr( &(temp_allocator), sizeof (*min_enc_state) ); fc_solve_state_string_to_enc( local_variant, delta, *(min_states_iter), min_enc_state ); fc_solve_kaz_tree_alloc_insert( does_min_by_sorting_exist, min_enc_state ); } } cache_init(&does_state_exist_in_any_FCC_cache, max_num_elements_in_cache, &meta_alloc); /* Populate does_state_exist_in_any_FCC_cache from states_in_cache */ { const char * * min_states_iter = states_in_cache; for (; *(min_states_iter) ; min_states_iter++) { fcs_encoded_state_buffer_t * min_enc_state; min_enc_state = (fcs_encoded_state_buffer_t *) fcs_compact_alloc_ptr( &(temp_allocator), sizeof (*min_enc_state) ); fc_solve_state_string_to_enc( local_variant, delta, *(min_states_iter), min_enc_state ); cache_insert (&does_state_exist_in_any_FCC_cache, min_enc_state, NULL, '\0'); } } init_moves_seq.moves_list = NULL; init_moves_seq.count = 0; add_start_point_context.do_next_fcc_start_points_exist = do_next_fcc_start_points_exist; add_start_point_context.next_start_points_list = &start_points_list; add_start_point_context.moves_list_allocator = &moves_list_allocator; { long num_new_positions_temp; perform_FCC_brfs( local_variant, &(init_state), start_enc_state, &init_moves_seq, fc_solve_add_start_point_in_mem, &add_start_point_context, out_is_fcc_new, &min_by_sorting, does_min_by_sorting_exist, &does_state_exist_in_any_FCC_cache, &num_new_positions_temp, &moves_list_allocator, &meta_alloc ); } fc_solve_compact_allocator_finish(&(start_points_list.allocator)); fc_solve_compact_allocator_finish(&(temp_allocator)); fc_solve_delta_stater_free (delta); fc_solve_kaz_tree_destroy(do_next_fcc_start_points_exist); fc_solve_kaz_tree_destroy(does_min_by_sorting_exist); cache_destroy(&does_state_exist_in_any_FCC_cache); fc_solve_meta_compact_allocator_finish( &meta_alloc ); return 0; }
static void *instance_run_solver_thread(void *const void_arg) { fcs_dbm_queue_item_t physical_item; fcs_dbm_record_t *token = NULL; fcs_dbm_queue_item_t *item, *prev_item; fcs_derived_state_t *derived_list, *derived_list_recycle_bin, *derived_iter; fcs_compact_allocator_t derived_list_allocator; fcs_state_keyval_pair_t state; char *base64_encoding_buffer = NULL; #if 0 size_t base64_encoding_buffer_max_len = 0; #endif #ifdef DEBUG_OUT fcs_state_locs_struct_t locs; fc_solve_init_locs(&locs); #endif DECLARE_IND_BUF_T(indirect_stacks_buffer) const_AUTO(thread, ((thread_arg_t *)void_arg)->thread); const_SLOT(instance, thread); const_AUTO(delta_stater, &(thread->delta_stater)); const_AUTO(local_variant, instance->common.variant); prev_item = item = NULL; int queue_num_extracted_and_processed = 0; fc_solve_compact_allocator_init( &(derived_list_allocator), &(thread->thread_meta_alloc)); derived_list_recycle_bin = NULL; derived_list = NULL; FILE *const out_fh = instance->common.out_fh; TRACE("%s\n", "instance_run_solver_thread start"); const_AUTO(coll, &(instance->coll)); #if 0 fcs_bool_t was_start_key_reachable = instance->was_start_key_reachable; #endif while (1) { /* First of all extract an item. */ fcs_lock_lock(&instance->global_lock); if (prev_item) { instance->common.queue_num_extracted_and_processed--; } if (instance->common.should_terminate == DONT_TERMINATE) { if (fcs_depth_multi_queue__extract(&(coll->depth_queue), &(thread->state_depth), (fcs_offloading_queue_item_t *)(&token))) { physical_item.key = token->key; item = &physical_item; instance_increment(instance); } else { item = NULL; } queue_num_extracted_and_processed = instance->common.queue_num_extracted_and_processed; } fcs_lock_unlock(&instance->global_lock); if ((instance->common.should_terminate != DONT_TERMINATE) || (!queue_num_extracted_and_processed)) { break; } if (!item) { /* Sleep until more items become available in the * queue. */ usleep(5000); } else { /* Handle item. */ fc_solve_delta_stater_decode_into_state( delta_stater, item->key.s, &state, indirect_stacks_buffer); /* A section for debugging. */ FCS__OUTPUT_STATE(out_fh, "", &(state.s), &locs); #if 0 { FccEntryPointNode key; key.kv.key.key = item->key; fcs_lock_lock(&instance->fcc_entry_points_lock); FccEntryPointNode * val_proto = RB_FIND( FccEntryPointList, &(instance->fcc_entry_points), &(key) ); fcs_bool_t to_prune = FALSE; fcs_bool_t to_output = FALSE; if (val_proto) { val_proto->kv.val.is_reachable = TRUE; const int moves_count = instance->start_key_moves_count + item->moves_seq.count; if (was_start_key_reachable) { if (val_proto->kv.val.depth <= moves_count) { /* We can prune based on here. */ to_prune = TRUE; } else { /* We can set it to the more pessimstic move count * for future trimming. */ to_output = !(val_proto->kv.val.was_consumed); val_proto->kv.val.depth = moves_count; val_proto->kv.val.was_consumed = TRUE; } } else { if (! val_proto->kv.val.was_consumed) { to_output = TRUE; if (val_proto->kv.val.depth >= moves_count) { val_proto->kv.val.depth = moves_count; val_proto->kv.val.was_consumed = TRUE; } } } } fcs_lock_unlock(&instance->fcc_entry_points_lock); if (to_output) { const size_t needed_len = ( (sizeof(key.kv.key.key)+2) << 2 ) / 3 + 20; if (base64_encoding_buffer_max_len < needed_len) { base64_encoding_buffer = SREALLOC(base64_encoding_buffer, needed_len); base64_encoding_buffer_max_len = needed_len; } size_t unused_output_len; base64_encode( (unsigned char *)&(key.kv.key.key), sizeof(key.kv.key.key), base64_encoding_buffer, &unused_output_len ); fcs_lock_lock(&instance->output_lock); fprintf( instance->consumed_states_fh, "%s\n", base64_encoding_buffer ); fflush(instance->consumed_states_fh); fcs_lock_unlock(&instance->output_lock); } if (to_prune) { continue; } } #endif if (instance_solver_thread_calc_derived_states(local_variant, &state, token, &derived_list, &derived_list_recycle_bin, &derived_list_allocator, TRUE)) { fcs_lock_lock(&instance->global_lock); fcs_dbm__found_solution(&(instance->common), token, item); fcs_lock_unlock(&instance->global_lock); break; } /* Encode all the states. */ for (derived_iter = derived_list; derived_iter; derived_iter = derived_iter->next) { fcs_init_and_encode_state(delta_stater, local_variant, &(derived_iter->state), &(derived_iter->key)); } instance_check_multiple_keys(thread, instance, &(coll->cache_store), &(coll->queue_meta_alloc), &derived_list, 1 #ifdef FCS_DBM_CACHE_ONLY , item->moves_to_key #endif ); /* Now recycle the derived_list */ while (derived_list) { #define derived_list_next derived_iter derived_list_next = derived_list->next; derived_list->next = derived_list_recycle_bin; derived_list_recycle_bin = derived_list; derived_list = derived_list_next; #undef derived_list_next } /* End handle item. */ } /* End of main thread loop */ prev_item = item; } free(base64_encoding_buffer); fc_solve_compact_allocator_finish(&(derived_list_allocator)); TRACE("%s\n", "instance_run_solver_thread end"); return NULL; }