void fc_solve_compact_allocator_extend( fcs_compact_allocator_t * allocator ) { /* Allocate a new pack */ if ((++allocator->num_packs) == allocator->max_num_packs) { allocator->packs = (char * *)SREALLOC( allocator->packs, allocator->max_num_packs += IA_STATE_PACKS_GROW_BY ); allocator->packs[allocator->num_packs-1] = SMALLOC(allocator->packs[allocator->num_packs-1], ALLOCED_SIZE); for (int i = allocator->num_packs ; i < allocator->max_num_packs ; i++) { allocator->packs[i] = NULL; } } else { if (! allocator->packs[allocator->num_packs - 1]) { allocator->packs[allocator->num_packs - 1] = SMALLOC( allocator->packs[allocator->num_packs - 1], ALLOCED_SIZE ); } } allocator->max_ptr = (allocator->ptr = allocator->rollback_ptr = allocator->packs[allocator->num_packs - 1] ) + ALLOCED_SIZE; }
corpus_type *read_corpus(corpusflags_type *flags, FILE *in) { sentence_type s; feature_type fmax = 0; int nread, i = 0, maxnparses = 0, nloserparses = 0; Float sum_g = 0; /* allocate feature counts */ read_parse_nfc_max = MIN_NFC; read_parse_fcp = MALLOC(read_parse_nfc_max*sizeof(fc_type)); assert(read_parse_fcp != NULL); /* allocate features w/ 1 count */ read_parse_nf_max = MIN_NF; read_parse_fp = MALLOC(read_parse_nf_max*sizeof(feature_type)); assert(read_parse_fp != NULL); corpus_type *c = SMALLOC(sizeof(corpus_type)); assert(c != NULL); size_type nsentences; nread = fscanf(in, " S = %d ", &nsentences); assert(nread != EOF); c->sentence = MALLOC(nsentences*sizeof(sentence_type)); assert(c->sentence != NULL); while (read_sentence(flags, in, &s, &fmax, &maxnparses) != EOF) { if (i >= nsentences) { nsentences *= 2; c->sentence = REALLOC(c->sentence, nsentences*sizeof(sentence_type)); assert(c->sentence != NULL); } assert(i < nsentences); /* skip sentences with no winners but some parses -- these are typically parse failures. */ if (s.Px == 0.0 && s.nparses != 0) continue; c->sentence[i++] = s; sum_g += s.g; if (s.Px > 0) nloserparses += s.nparses - 1; } c->nsentences = i; c->sentence = SREALLOC(c->sentence, nsentences*sizeof(sentence_type), c->nsentences*sizeof(sentence_type)); assert(c->sentence != NULL); c->nfeatures = fmax+1; c->maxnparses = maxnparses; c->nloserparses = nloserparses; if (flags && flags->Px_propto_g) for (i = 0; i < c->nsentences; ++i) /* normalize Px */ c->sentence[i].Px *= c->nsentences * c->sentence[i].g / sum_g; FREE(read_parse_fcp); FREE(read_parse_fp); return c; } /* read_corpus() */
static inline void instance_alloc_num_moves( fcs_dbm_solver_instance_t *const instance, const size_t buffer_size) { if (buffer_size > instance->max_moves_to_state_len) { instance->moves_to_state = SREALLOC(instance->moves_to_state, buffer_size); instance->max_moves_to_state_len = buffer_size; } }
void fc_solve_derived_states_list_add_state(fcs_derived_states_list *const list, fcs_collectible_state *const state, const int context) { if ((!((list->num_states + (list->states != NULL)) & (DERIVED_STATES_LIST_GROW_BY - 1)))) { list->states = SREALLOC(list->states, list->num_states + (list->states != NULL) + DERIVED_STATES_LIST_GROW_BY); } list->states[list->num_states++] = (fcs_derived_states_list_item){ .state_ptr = state, .context.i = context}; }
char *read_line(FILE *ifile, char rsep) { static char *buf; int c; static size_t i = 0, length = 0; while ((c = getc(ifile)) != rsep) { if (i >= length) { if (length == 0) length = 512; length *= 2; SREALLOC(buf, length+2, sizeof(char)); } if (c == EOF) { SFREE(buf); return (buf = NULL); } buf[i++] = c; } buf[i] = '\0'; i = 0; return (buf); }
corpus_type *read_corpus(corpusflags_type *flags, FILE *in, int nsentences) { sentence_type s; feature_type fmax = 0; int nread, i = 0, maxnparses = 0; Float sum_g = 0; corpus_type *c = SMALLOC(sizeof(corpus_type)); assert(c != NULL); nread = fscanf(in, " S = %d ", &nsentences); assert(nread != EOF); c->sentence = MALLOC(nsentences*sizeof(sentence_type)); assert(c->sentence != NULL); while (read_sentence(flags, in, &s, &fmax, &maxnparses) != EOF) { if (i >= nsentences) { nsentences *= 2; c->sentence = REALLOC(c->sentence, nsentences*sizeof(sentence_type)); assert(c->sentence != NULL); } assert(i < nsentences); c->sentence[i++] = s; sum_g += s.g; } c->nsentences = i; c->sentence = SREALLOC(c->sentence, nsentences*sizeof(sentence_type), c->nsentences*sizeof(sentence_type)); assert(c->sentence != NULL); c->nfeatures = fmax+1; c->maxnparses = maxnparses; if (flags->Px_propto_g) for (i = 0; i < c->nsentences; ++i) /* normalize Px */ c->sentence[i].Px *= c->nsentences * c->sentence[i].g / sum_g; return c; } /* read_corpus() */
static inline void instance__inspect_new_state( fcs_dbm_solver_instance_t *const instance, fcs_cache_key_t *const state) { instance->count_num_processed++; if (fcs_pdfs_cache_does_key_exist(&(instance->cache), &(state->s))) { instance->stack_depth--; return; } const fcs_dbm_variant_type_t local_variant = instance->local_variant; const int depth = (instance->stack_depth); const int max_depth = instance->max_stack_depth; if (depth == max_depth) { instance->stack = SREALLOC(instance->stack, ++(instance->max_stack_depth)); pseduo_dfs_stack_item_t *const stack_item = instance->stack + max_depth; stack_item->next_states = NULL; stack_item->max_count_next_states = 0; } pseduo_dfs_stack_item_t *const stack_item = instance->stack + depth; stack_item->curr_state = state; fcs_derived_state_t *derived_list = NULL, *derived_iter = NULL; if (instance_solver_thread_calc_derived_states(instance->local_variant, state, NULL, &derived_list, &(instance->derived_list_recycle_bin), &(instance->derived_list_allocator), TRUE)) { instance->should_terminate = SOLUTION_FOUND_TERMINATE; instance->solution_was_found = TRUE; return; } stack_item->count_next_states = 0; stack_item->next_state_idx = 0; fcs_kv_state_t kv; /* Now recycle the derived_list */ while (derived_list) { kv.key = &(derived_list->state.s); kv.val = &(derived_list->state.info); fc_solve_canonize_state(kv.key, FREECELLS_NUM, STACKS_NUM); if (!lookup_state( &(instance->store), &(instance->cache), &(derived_list->state))) { int i = (stack_item->count_next_states)++; if (i >= stack_item->max_count_next_states) { stack_item->next_states = SREALLOC(stack_item->next_states, ++(stack_item->max_count_next_states)); } stack_item->next_states[i] = derived_list->state; insert_state(&(instance->store), &(stack_item->next_states[i])); } #define derived_list_next derived_iter derived_list_next = derived_list->next; derived_list->next = instance->derived_list_recycle_bin; instance->derived_list_recycle_bin = derived_list; derived_list = derived_list_next; #undef derived_list_next } return; }
Tokenarray *parseline(char *line, Parsemode *pmode) { int i, m = (strlen(line) + 1)/2, n = 0, state = 0; char d, *p, *q = NULL; SSTRCPY(tbuf, line); p = tbuf-1; SREALLOC(ta, sizeof(int)*2 + sizeof(char *)*m, 1); ta->maxtokens = m; if (pmode == NULL) pmode = &defpmode; else if (pmode->delim == NULL) pmode->delim = defpmode.delim; while (*(++p)) { /* for each character in the line */ /* is *p an escape character? */ if (pmode->esc && *p == pmode->esc) { if (*(p+1) == '\0') break; if (state == 0) { /* start a new token */ state = 1; ta->token[n++] = p; } p++; /* include the next character in the token */ continue; } /* is *p the character needed to complete a quoted string? */ if (q) { if (*p == *q) { *p = '\0'; q = NULL; } continue; } /* is *p a delimiter character? */ i = 0; while (d = pmode->delim[i++]) { if (*p == d) { *p = '\0'; /* replace delimiter with null */ if (state == 0) { /* not in a token */ if (pmode->collapse == 0) ta->token[n++] = p; /* count an empty token */ } state = 0; break; } } /* is *p an open-quote character? */ i = 0; while (q = pmode->quotepair[i++]) { /* q is an open-quote character */ if (*p == *q) { /* *p is first character of a quoted string */ if (state == 0) { /* start a new token */ ta->token[n++] = p+1; state = 1; } q++; /* *q is now the matching close-quote character */ break; } } if (d == '\0' && q == NULL) { /* p must be part of a token */ if (state == 0) { ta->token[n++] = p; /* start a new token */ state = 1; } } } ta->ntokens = n; return (ta); }
static void read_parse(FILE *in, parse_type *p, feature_type *fmax) { feature_type f, *fp; fc_type *fcp; int nread; size_t nf = 0, nfc = 0; DataFloat c; size_t nf_max = (last_nf <= MIN_NF) ? MIN_NF : last_nf; size_t nfc_max = (last_nfc <= MIN_NFC) ? MIN_NFC : last_nfc; fcp = MALLOC(nfc_max*sizeof(fc_type)); /* allocate feature counts */ assert(fcp != NULL); fp = MALLOC(nf_max*sizeof(feature_type)); /* allocate features w/ 1 count */ assert(fp != NULL); p->p = 1; nread = fscanf(in, " P = " DATAFLOAT_FORMAT " ", &p->p); /* read p */ assert(nread != EOF); p->w = 0; nread = fscanf(in, " W = " DATAFLOAT_FORMAT " ", &p->w); /* read pwinner */ assert(nread != EOF); while ((nread = fscanf(in, " " FEATURE_FORMAT " ", &f))) { /* read feature */ assert(nread != EOF); if (nread == 0) break; assert(f >= 0); c = 1.0; /* default value for c */ /* read feature count */ nread = fscanf(in, " = " DATAFLOAT_FORMAT " ", &c); assert(nread != EOF); if (f > *fmax) *fmax = f; if (c == 1.0) { if (nf >= nf_max) { nf_max *= 2; fp = REALLOC(fp, nf_max*sizeof(feature_type)); assert(fp != NULL); } assert(nf<nf_max); fp[nf] = f; nf++; } else { /* c != 1 */ if (nfc >= nfc_max) { nfc_max *= 2; fcp = REALLOC(fcp, nfc_max*sizeof(fc_type)); assert(fcp != NULL); } assert(nfc<nfc_max); fcp[nfc].f = f; fcp[nfc].c = c; nfc++; } } /* copy features into p */ last_nf = p->nf = nf; p->f = SREALLOC(fp, nf_max*sizeof(feature_type), nf*sizeof(feature_type)); if (nf > 0) assert(p->f != NULL); last_nfc = p->nfc = nfc; p->fc = SREALLOC(fcp, nfc_max*sizeof(fc_type), nfc*sizeof(fc_type)); if (nfc > 0) assert(p->fc != NULL); fscanf(in, " ,"); /* read final ',' */ } /* read_parse() */
bool BTIsNodeUsed(const BTreePtr bTree, bt_nodeid_t nodeNum) { if (bTree->_loadingBitmap == true) { // Is it somewhere we've loaded so far? if (nodeNum > bTree->nodeBitmapSize) { // Really can't say yes, but everything breaks if we say no. debug("Returning blind YES since node is beyond current bitmap."); return true; } else { debug("Returning answer from partially-loaded result."); } } assert(bTree); // Load the tree bitmap, if needed. if (bTree->nodeBitmap == NULL) { debug("Tree %u: loading node bitmap.", bTree->treeID); bTree->_loadingBitmap = true; // Get the B-Tree's header node (#0) BTreeNodePtr node = NULL; if ( BTGetNode(&node, bTree, 0) < 0) return false; // Get the third record (map data) BTNodeRecord record = {0}; BTGetBTNodeRecord(&record, node, 2); // Copy the data out into a persistant buffer bTree->nodeBitmapSize = record.recordLen; // Initially allocate space for up to 16 nodes. bTree->nodeBitmap = ALLOC(bTree->headerRecord.nodeSize * 16); assert(bTree->nodeBitmap != NULL); memcpy(bTree->nodeBitmap, record.record, record.recordLen); // Concat any linked map node records while (node->nodeDescriptor->fLink > 0 && (signed)node->nodeDescriptor->fLink != -1) { int loaded = false; size_t old_size = bTree->nodeBitmapSize; bt_nodeid_t node_id = node->nodeDescriptor->fLink; debug("Loading bitmap continuation node %d", node_id); BTFreeNode(node); node = NULL; loaded = BTGetNode(&node, bTree, node_id); assert(loaded == 0); assert(node != NULL); if (loaded != 0) { critical("bitmap continuation node not loaded: %u", node_id); } BTGetBTNodeRecord(&record, node, 0); bTree->nodeBitmapSize += record.recordLen; SREALLOC(bTree->nodeBitmap, bTree->nodeBitmapSize); memcpy(bTree->nodeBitmap + old_size, record.record, record.recordLen); } debug("Done loading nodes."); // Clean up BTFreeNode(node); bTree->_loadingBitmap = false; } // Check the bit in the data. bool result = BTIsBlockUsed(nodeNum, bTree->nodeBitmap, bTree->nodeBitmapSize); debug2("returning %d", result); return result; }
static inline void instance_check_key(fcs_dbm_solver_thread_t *const thread, fcs_dbm_solver_instance_t *const instance, const int key_depth, fcs_encoded_state_buffer_t *const key, fcs_dbm_record_t *const parent, const unsigned char move GCC_UNUSED, const fcs_which_moves_bitmask_t *const which_irreversible_moves_bitmask #ifdef FCS_DBM_CACHE_ONLY , const fcs_fcc_move_t *moves_to_parent #endif ) { #ifdef DEBUG_OUT fcs_state_locs_struct_t locs; fc_solve_init_locs(&locs); const_AUTO(local_variant, instance->common.variant); #endif const_AUTO(coll, &(instance->coll)); { #ifdef FCS_DBM_WITHOUT_CACHES fcs_dbm_record_t *token; #else fcs_dbm_record_t *token = key; #endif #ifndef FCS_DBM_WITHOUT_CACHES if (cache_does_key_exist(&(coll->cache_store.cache), key)) { return; } #ifndef FCS_DBM_CACHE_ONLY else if (pre_cache_does_key_exist(&(coll->cache_store.pre_cache), key)) { return; } #endif #ifndef FCS_DBM_CACHE_ONLY else if (fc_solve_dbm_store_does_key_exist( coll->cache_store.store, key->s)) { cache_insert(&(coll->cache_store.cache), key, NULL, '\0'); return; } #endif else #else if ((token = fc_solve_dbm_store_insert_key_value( coll->cache_store.store, key, parent, TRUE))) #endif { #ifdef FCS_DBM_CACHE_ONLY fcs_cache_key_info_t *cache_key; #endif #ifndef FCS_DBM_WITHOUT_CACHES #ifndef FCS_DBM_CACHE_ONLY pre_cache_insert(&(coll->cache_store.pre_cache), key, parent); #else cache_key = cache_insert( &(coll->cache_store.cache), key, moves_to_parent, move); #endif #endif if (key_depth == instance->curr_depth) { /* Now insert it into the queue. */ fcs_lock_lock(&instance->global_lock); fcs_depth_multi_queue__insert( &(coll->depth_queue), thread->state_depth + 1, #ifdef FCS_DBM_WITHOUT_CACHES (const fcs_offloading_queue_item_t *)(&token) #else key #endif ); instance->common.count_of_items_in_queue++; instance->common.num_states_in_collection++; instance_debug_out_state(instance, &(token->key)); fcs_lock_unlock(&instance->global_lock); } else { /* Handle an irreversible move */ /* Calculate the new fingerprint to which the exit * point belongs. */ fcs_which_moves_bitmask_t new_fingerprint = {{'\0'}}; for (size_t i = 0; i < COUNT(new_fingerprint.s); i++) { new_fingerprint.s[i] = which_irreversible_moves_bitmask->s[i] + instance->fingerprint_which_irreversible_moves_bitmask .s[i]; } int trace_num; fcs_encoded_state_buffer_t *trace; fcs_lock_lock(&instance->fcc_exit_points_output_lock); /* instance->storage_lock is already locked * in instance_check_multiple_keys and we should not * lock it here. */ calc_trace(token, &trace, &trace_num); { FccEntryPointNode fcc_entry_key; fcc_entry_key.kv.key.key = trace[trace_num - 1]; FccEntryPointNode *val_proto = RB_FIND(FccEntryPointList, &(instance->fcc_entry_points), &fcc_entry_key); const long location_in_file = val_proto->kv.val.location_in_file; fseek(instance->fingerprint_fh, location_in_file, SEEK_SET); #ifdef HAVE_GETLINE getline(&(instance->fingerprint_line), &(instance->fingerprint_line_size), instance->fingerprint_fh); #else fgets(instance->fingerprint_line, instance->fingerprint_line_size, instance->fingerprint_fh); #endif char *const moves_to_state_enc = strchr( strchr(instance->fingerprint_line, ' ') + 1, ' ') + 1; char *const trailing_newline = strchr(moves_to_state_enc, '\n'); if (trailing_newline) { *trailing_newline = '\0'; } const size_t string_len = strlen(moves_to_state_enc); instance_alloc_num_moves( instance, ((string_len * 3) >> 2) + 20); base64_decode(moves_to_state_enc, string_len, ((unsigned char *)instance->moves_to_state), &(instance->moves_to_state_len)); } const_SLOT(moves_to_state_len, instance); const size_t added_moves_to_output = moves_to_state_len + trace_num - 1; instance_alloc_num_moves(instance, added_moves_to_output); unsigned char *const moves_to_state = instance->moves_to_state; for (int i = trace_num - 1; i > 0; i--) { moves_to_state[moves_to_state_len + trace_num - 1 - i] = get_move_from_parent_to_child(instance, &(thread->delta_stater), trace[i], trace[i - 1]); } const size_t new_max_enc_len = ((added_moves_to_output * 4) / 3) + 20; if (new_max_enc_len > instance->moves_base64_encoding_buffer_max_len) { instance->moves_base64_encoding_buffer = SREALLOC(instance->moves_base64_encoding_buffer, new_max_enc_len); instance->moves_base64_encoding_buffer_max_len = new_max_enc_len; } size_t unused_output_len; base64_encode(moves_to_state, added_moves_to_output, instance->moves_base64_encoding_buffer, &unused_output_len); char fingerprint_base64[100]; char state_base64[100]; base64_encode(new_fingerprint.s, sizeof(new_fingerprint), fingerprint_base64, &unused_output_len); base64_encode((unsigned char *)&(*key), sizeof(*key), state_base64, &unused_output_len); /* Output the exit point. */ fprintf(instance->fcc_exit_points_out_fh, "%s %s %zd %s\n", fingerprint_base64, state_base64, added_moves_to_output, instance->moves_base64_encoding_buffer); #ifdef DEBUG_OUT { fcs_state_keyval_pair_t state; DECLARE_IND_BUF_T(indirect_stacks_buffer) fc_solve_delta_stater_decode_into_state( &(thread->delta_stater), key->s, &state, indirect_stacks_buffer); char state_str[2000]; FCS__RENDER_STATE(state_str, &(state.s), &locs); fprintf(stderr, "Check Key: <<<\n%s\n>>>\n\n[%s %s %ld %s]\n\n", state_str, fingerprint_base64, state_base64, added_moves_to_output, instance->moves_base64_encoding_buffer); } #endif fflush(instance->fcc_exit_points_out_fh); fcs_lock_unlock(&instance->fcc_exit_points_output_lock); free(trace); } } }
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; }