double  qsearch_fulltree_sum_distance_org(FullTree *tree, int a, int b) {
    
    FullNode *map = get_nodes(tree);
    int branch2b = map[a].node_branch[b];
    int branch2a = map[b].node_branch[a];
     
    return npairs( map[a].leaf_count[branch2b] ) * map[a].dist[branch2b] + npairs( map[b].leaf_count[branch2a] ) * map[b].dist[branch2a];

}
static void set_score(FullTree *tree) {
    // calculate the score
    tree->raw_score = 0;
    FullNode *map = get_nodes(tree);
    int i;
    for (i = (tree->node_count + 2)/2; i < tree->node_count; ++i) {
        tree->raw_score += npairs(map[i].leaf_count[0]) * map[i].dist[0];
        tree->raw_score += npairs(map[i].leaf_count[1]) * map[i].dist[1];
        tree->raw_score += npairs(map[i].leaf_count[2]) * map[i].dist[2];
    }
}
예제 #3
0
int
dict_find(const ref * pdref, const ref * pkey, ref ** ppvalue)
{
    dict *pdict = pdref->value.pdict;
    int code = real_dict_find(pdref, pkey, ppvalue);

    stats_dict.lookups++;
    if (r_has_type(pkey, t_name) && dict_is_packed(pdict)) {
        uint nidx = name_index(dict_mem(pdict), pkey);
        uint hash =
        dict_hash_mod(dict_name_index_hash(nidx), npairs(pdict)) + 1;

        if (pdict->keys.value.packed[hash] ==
            pt_tag(pt_literal_name) + nidx
            )
            stats_dict.probe1++;
        else if (pdict->keys.value.packed[hash - 1] ==
                 pt_tag(pt_literal_name) + nidx
            )
            stats_dict.probe2++;
    }
    /* Do the cheap flag test before the expensive remainder test. */
    if (gs_debug_c('d') && !(stats_dict.lookups % 1000))
        dlprintf3("[d]lookups=%ld probe1=%ld probe2=%ld\n",
                  stats_dict.lookups, stats_dict.probe1, stats_dict.probe2);
    return code;
}
예제 #4
0
파일: idstack.c 프로젝트: 99years/plan9
ref *
dstack_find_name_by_index(dict_stack_t * pds, uint nidx)
{
    ref *pvalue = real_dstack_find_name_by_index(pds, nidx);
    dict *pdict = pds->stack.p->value.pdict;

    INCR(lookups);
    if (dict_is_packed(pdict)) {
	uint hash =
	dict_hash_mod(dict_name_index_hash(nidx), npairs(pdict)) + 1;

	if (pdict->keys.value.packed[hash] ==
	    pt_tag(pt_literal_name) + nidx
	    )
	    INCR(probes[0]);
	else if (pdict->keys.value.packed[hash - 1] ==
		 pt_tag(pt_literal_name) + nidx
	    )
	    INCR(probes[1]);
    }
    if (gs_debug_c('d') && !(stats_dstack.lookups % 1000))
	dlprintf3("[d]lookups=%ld probe1=%ld probe2=%ld\n",
		  stats_dstack.lookups, stats_dstack.probes[0],
		  stats_dstack.probes[1]);
    return pvalue;
}
double  qsearch_fulltree_sum_distance(FullTree *tree, int a, int b) {
    
    FullNode *map = get_nodes(tree);

    double sum = 0.0;

    int node = map[a].connections[ map[a].node_branch[b] ];
    int n = 0;
    while (node != b) {
        int toa = map[node].node_branch[a];
        int tob = map[node].node_branch[b];
        
        sum += npairs( map[node].leaf_count[ toa ] ) * map[node].dist[toa];
        sum += npairs( map[node].leaf_count[ tob ] ) * map[node].dist[tob];
        n++;
        node = map[node].connections[ tob ];
    }

    return sum / n;
}
예제 #6
0
/* Grow a dictionary for dict_put. */
int
dict_grow(ref * pdref, dict_stack_t *pds)
{
    dict *pdict = pdref->value.pdict;
    /* We might have maxlength < npairs, if */
    /* dict_round_size increased the size. */
    ulong new_size = (ulong) d_maxlength(pdict);
    /* Adobe does this */
    if (new_size < 20)
        new_size += 10;
    else if (new_size < 200)
        new_size *= 2;
    else
        new_size += new_size / 2;
#if ARCH_SIZEOF_INT < ARCH_SIZEOF_LONG
    if (new_size > max_uint)
        new_size = max_uint;
#endif
    if (new_size > npairs(pdict)) {
        int code = dict_resize(pdref, (uint) new_size, pds);

        if (code >= 0)
            return code;
        /* new_size was too big. */
        if (npairs(pdict) < dict_max_size) {
            code = dict_resize(pdref, dict_max_size, pds);
            if (code >= 0)
                return code;
        }
        if (npairs(pdict) == d_maxlength(pdict)) {	/* Can't do it. */
            return code;
        }
        /* We can't grow to new_size, but we can grow to npairs. */
        new_size = npairs(pdict);
    }
    /* maxlength < npairs, we can grow in place */
    ref_save_in(dict_memory(pdict), pdref, &pdict->maxlength,
                "dict_put(maxlength)");
    d_set_maxlength(pdict, new_size);
    return 0;
}
예제 #7
0
/* Return the maximum index of a slot within a dictionary. */
uint
dict_max_index(const ref * pdref /* t_dictionary */ )
{
    return npairs(pdref->value.pdict) - 1;
}
예제 #8
0
/*
 * Look up a key in a dictionary.  Store a pointer to the value slot
 * where found, or to the (value) slot for inserting.
 * See idict.h for the possible return values.
 */
int
dict_find(const ref * pdref, const ref * pkey,
          ref ** ppvalue /* result is stored here */ )
{
    dict *pdict = pdref->value.pdict;
    uint size = npairs(pdict);
    register int etype;
    uint nidx;
    ref_packed kpack;
    uint hash;
    int ktype;
    const gs_memory_t *mem = dict_mem(pdict);

    /* Compute hash.  The only types we bother with are strings, */
    /* names, and (unlikely, but worth checking for) integers. */
    switch (r_type(pkey)) {
    case t_name:
        nidx = name_index(mem, pkey);
    nh:
        hash = dict_name_index_hash(nidx);
        kpack = packed_name_key(nidx);
        ktype = t_name;
        break;
    case t_string:		/* convert to a name first */
        {
            ref nref;
            int code;

            if (!r_has_attr(pkey, a_read))
                return_error(gs_error_invalidaccess);
            code = name_ref(mem, pkey->value.bytes, r_size(pkey), &nref, 1);
            if (code < 0)
                return code;
            nidx = name_index(mem, &nref);
        }
        goto nh;
    case t_real:
        /*
         * Make sure that equal reals and integers hash the same.
         */
        {
            int expt, i;
            double mant = frexp(pkey->value.realval, &expt);
            /*
             * The value is mant * 2^expt, where 0.5 <= mant < 1,
             * or else expt == mant == 0.
             */

            if (expt < sizeof(long) * 8 || pkey->value.realval == min_long)
                i = (int)pkey->value.realval;
            else
                i = (int)(mant * min_long); /* MSVC 6.00.8168.0 cannot compile this */
            hash = (uint)i * 30503;         /*   with -O2 as a single expression    */
        }
        goto ih;
    case t_integer:
        hash = (uint)pkey->value.intval * 30503;
    ih:
        kpack = packed_key_impossible;
        ktype = -1;
        nidx = 0;		/* only to pacify gcc */
        break;
    case t_null:		/* not allowed as a key */
        return_error(gs_error_typecheck);
    default:
        hash = r_btype(pkey) * 99;	/* yech */
        kpack = packed_key_impossible;
        ktype = -1;
        nidx = 0;		/* only to pacify gcc */
    }
    /* Search the dictionary */
    if (dict_is_packed(pdict)) {
        const ref_packed *pslot = 0;

#	define found *ppvalue = packed_search_value_pointer; return 1
#	define deleted if (pslot == 0) pslot = kp
#	define missing goto miss
#	include "idicttpl.h"
#	undef missing
#	undef deleted
#	undef found
        /*
         * Double wraparound, dict is full.
         * Note that even if there was an empty slot (pslot != 0),
         * we must return dictfull if length = maxlength.
         */
        if (pslot == 0 || d_length(pdict) == d_maxlength(pdict))
            return_error(gs_error_dictfull);
        *ppvalue = pdict->values.value.refs + (pslot - kbot);
        return 0;
      miss:			/* Key is missing, not double wrap.  See above re dictfull. */
        if (d_length(pdict) == d_maxlength(pdict))
            return_error(gs_error_dictfull);
        if (pslot == 0)
            pslot = kp;
        *ppvalue = pdict->values.value.refs + (pslot - kbot);
        return 0;
    } else {
        ref *kbot = pdict->keys.value.refs;
        register ref *kp;
        ref *pslot = 0;
        int wrap = 0;

        for (kp = kbot + dict_hash_mod(hash, size) + 2;;) {
            --kp;
            if ((etype = r_type(kp)) == ktype) {	/* Fast comparison if both keys are names */
                if (name_index(mem, kp) == nidx) {
                    *ppvalue = pdict->values.value.refs + (kp - kbot);
                    return 1;
                }
            } else if (etype == t_null) {	/* Empty, deleted, or wraparound. */
                /* Figure out which. */
                if (kp == kbot) {	/* wrap */
                    if (wrap++) {	/* wrapped twice */
                        if (pslot == 0)
                            return_error(gs_error_dictfull);
                        break;
                    }
                    kp += size + 1;
                } else if (r_has_attr(kp, a_executable)) {	/* Deleted entry, save the slot. */
                    if (pslot == 0)
                        pslot = kp;
                } else		/* key not found */
                    break;
            } else {
                if (obj_eq(mem, kp, pkey)) {
                    *ppvalue = pdict->values.value.refs + (kp - kbot);
                    return 1;
                }
            }
        }
        if (d_length(pdict) == d_maxlength(pdict))
            return_error(gs_error_dictfull);
        *ppvalue = pdict->values.value.refs +
            ((pslot != 0 ? pslot : kp) - kbot);
        return 0;
    }
}
예제 #9
0
파일: idstack.c 프로젝트: 99years/plan9
/*
 * Look up a name on the dictionary stack.
 * Return the pointer to the value if found, 0 if not.
 */
ref *
dstack_find_name_by_index(dict_stack_t * pds, uint nidx)
{
    ds_ptr pdref = pds->stack.p;

/* Since we know the hash function is the identity function, */
/* there's no point in allocating a separate variable for it. */
#define hash dict_name_index_hash(nidx)
    ref_packed kpack = packed_name_key(nidx);

    do {
	dict *pdict = pdref->value.pdict;
	uint size = npairs(pdict);
	const gs_memory_t *mem = dict_mem(pdict);
#ifdef DEBUG
	if (gs_debug_c('D')) {
	    ref dnref;

	    name_index_ref(mem, nidx, &dnref);
	    dlputs("[D]lookup ");
	    debug_print_name(mem, &dnref);
	    dprintf3(" in 0x%lx(%u/%u)\n",
		     (ulong) pdict, dict_length(pdref),
		     dict_maxlength(pdref));
	}
#endif
#define INCR_DEPTH(pdref)\
  INCR(depth[min(MAX_STATS_DEPTH, pds->stack.p - pdref)])
	if (dict_is_packed(pdict)) {
	    packed_search_1(INCR_DEPTH(pdref),
			    return packed_search_value_pointer,
			    DO_NOTHING, goto miss);
	    packed_search_2(INCR_DEPTH(pdref),
			    return packed_search_value_pointer,
			    DO_NOTHING, break);
	  miss:;
	} else {
	    ref *kbot = pdict->keys.value.refs;
	    register ref *kp;
	    int wrap = 0;

	    /* Search the dictionary */
	    for (kp = kbot + dict_hash_mod(hash, size) + 2;;) {
		--kp;
		if (r_has_type(kp, t_name)) {
		    if (name_index(mem, kp) == nidx) {
			INCR_DEPTH(pdref);
			return pdict->values.value.refs + (kp - kbot);
		    }
		} else if (r_has_type(kp, t_null)) {	/* Empty, deleted, or wraparound. */
		    /* Figure out which. */
		    if (!r_has_attr(kp, a_executable))
			break;
		    if (kp == kbot) {	/* wrap */
			if (wrap++)
			    break;	/* 2 wraps */
			kp += size + 1;
		    }
		}
	    }
	}
#undef INCR_DEPTH
    }
void qsearch_fulltree_swap_nodes(FullTree *tree, int A, int B, const gsl_matrix *dm) {
   FullNode *ctm = get_nodes(tree);

   if (A == B) return; // no point in doing anything
    
   int interiorA = ctm[A].connections[ ctm[A].node_branch[B] ];
   int interiorB = ctm[B].connections[ (int) ctm[B].node_branch[A] ];
   
   if (interiorA == interiorB || interiorA == B) return; // swap does not change score
   
   int node_count = tree->node_count;
   int leaf_count = (node_count + 2)/2;

   int aToInteriorBranch = ctm[A].node_branch[interiorA];
   int bToInteriorBranch = ctm[B].node_branch[interiorB];
   
   int countA = leaf_count - ctm[A].leaf_count[aToInteriorBranch];
   int countB = leaf_count - ctm[B].leaf_count[bToInteriorBranch];
   
   int interiorToABranch = ctm[interiorA].node_branch[A];
   int interiorToBBranch = ctm[interiorB].node_branch[B];
     
   // loop over internal nodes, swap node_branches from A <-> B
   int node = interiorA;
   
   //printf("Score before %f\n", tree->raw_score);
    
   // store the nodes that need to be updated
   GArray *aNodes = get_tmpA(tree); //g_array_sized_new(FALSE, FALSE, sizeof(guint32), countA*2 - 1);
   GArray *bNodes = get_tmpB(tree); //g_array_sized_new(FALSE, FALSE, sizeof(guint32), countB*2 - 1);
    
   g_array_set_size(aNodes, 0);
   g_array_set_size(bNodes, 0);

   int i,j;
   for (i = 0; i < node_count; ++i) {
        if (i == A || ctm[A].node_branch[i] != aToInteriorBranch) {
            g_array_append_val(aNodes, i);
        }
        if (i == B || ctm[B].node_branch[i] != bToInteriorBranch) {
            g_array_append_val(bNodes, i);
        }
   }

   // move towards B 
   while (node != B) {

        int aBranch = ctm[node].node_branch[A];
        int bBranch = ctm[node].node_branch[B];
        int cBranch = 3 - aBranch - bBranch;
        
        tree->raw_score -= npairs(ctm[node].leaf_count[0]) * ctm[node].dist[0];
        tree->raw_score -= npairs(ctm[node].leaf_count[1]) * ctm[node].dist[1];
        tree->raw_score -= npairs(ctm[node].leaf_count[2]) * ctm[node].dist[2];
        
        //printf("Node %d\n", node);
        //printf("Score now %f, distances %f %f %f\n", tree->raw_score, ctm[node].dist[0], ctm[node].dist[1], ctm[node].dist[2]);
        
        ctm[node].leaf_count[aBranch] += countB - countA;
        ctm[node].leaf_count[bBranch] += countA - countB;
       
        // update the branches that point to elements from A 
        for (i = 0; i < aNodes->len; ++i) {
            guint32 aNode = g_array_index(aNodes, guint32, i);
            g_assert(ctm[node].node_branch[aNode] == aBranch);
            ctm[node].node_branch[aNode] = bBranch;
           
            // update distances 
            if (aNode < leaf_count) { // it's  a leaf
                for (j = 0; j < leaf_count; ++j) {
                    if (aNode==j) continue;
                    
                    double d = gsl_matrix_get(dm, aNode, j);

                    if (ctm[node].node_branch[j] == cBranch) {
                        ctm[node].dist[aBranch] += d;
                        ctm[node].dist[bBranch] -= d;
                    } else if (ctm[node].node_branch[j] == aBranch) {
                        ctm[node].dist[cBranch] += d;
                    } else {
                        ctm[node].dist[cBranch] -= d;
                    }
                }
            }
        } 
        
            
        // update the branches that point to elements from B
        for (i = 0; i < bNodes->len; ++i) {
            guint32 bNode = g_array_index(bNodes, guint32, i);

            g_assert(ctm[node].node_branch[bNode] == bBranch);
            ctm[node].node_branch[bNode] = aBranch;
                
            if (bNode < leaf_count) { // it's  a leaf
                for (j = 0; j < leaf_count; ++j) {
                    if (bNode==j) continue;
                    
                    double d = gsl_matrix_get(dm, bNode, j);

                    if (ctm[node].node_branch[j] == cBranch) {
                        ctm[node].dist[bBranch] += d;
                        ctm[node].dist[aBranch] -= d;
                    } else if (ctm[node].node_branch[j] == bBranch) {
                        ctm[node].dist[cBranch] += d;
                    } else {
                        ctm[node].dist[cBranch] -= d;
                    }
                }
            }
        }

        tree->raw_score += npairs(ctm[node].leaf_count[0]) * ctm[node].dist[0];
        tree->raw_score += npairs(ctm[node].leaf_count[1]) * ctm[node].dist[1];
        tree->raw_score += npairs(ctm[node].leaf_count[2]) * ctm[node].dist[2];
        
        //printf("Score now2 %f, distances %f %f %f\n", tree->raw_score, ctm[node].dist[0], ctm[node].dist[1], ctm[node].dist[2]);
        
        node = ctm[node].connections[ bBranch ];
   }
     
   // swap directions for A and B
   ctm[interiorA].connections[ interiorToABranch ] = B;
   ctm[interiorB].connections[ interiorToBBranch ] = A;
    
   // swap connections for A and b
   ctm[A].connections[ aToInteriorBranch ] = interiorB;
   ctm[B].connections[ bToInteriorBranch ] = interiorA;
}