示例#1
0
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;
}
示例#2
0
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() */
示例#3
0
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;
    }
}
示例#4
0
文件: move.c 项目: shlomif/fc-solve
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};
}
示例#5
0
文件: wrsamp.c 项目: TheChetan/ECGCS
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);
}
示例#6
0
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() */
示例#7
0
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;
}
示例#8
0
文件: wrsamp.c 项目: TheChetan/ECGCS
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);
}
示例#9
0
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() */
示例#10
0
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;
}
示例#11
0
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);
            }
        }
    }
示例#12
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;
}