⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpgraph.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    DO_VLIST(v, ordered_vset)	if (v->scc_members != NULL) {	    print_cycle_information(v, f, total_bytes);	    print_separator(f);	    print_normal_vertex(v, f, total_bytes);	} else if (v->in_cycle != NULL) {	    print_vertex_in_cycle(v, f, total_bytes);	} else {	    print_normal_vertex(v, f, total_bytes);	}	print_separator(f);    END_DO          fflush(f);}    graphread_graph(){    mpsym	s;    int		i, count;    mpcell	chain;    mpcell	rest;    mpcell	p;    int		v_count, e_count;    vecell	vset, eset;    /*     * First count the nodes and allocate space for them.     */    v_count = mp_count_nodes();    e_count = 0;    vset = NULL;    eset = NULL;    hcreate(2 * v_count);    /*     * Read in each vertex and store associated information.     */    count = 0;    for (i = 0; i < MP_HASH_SIZE; i++) {	chain = hmem[i];	while (!mp_null(chain)) {	    vertex	v;	    s = (mpsym) mp_car(chain);	    v = make_vertex(fn_name(s), count, fn_lcount(s), fn_parents(s));	    vpush(v, vset);	    count += 1;	    chain = (mpcell) mp_cdr(chain);	}    }    /*     * Create the backedges     */    DO_VLIST (vto, vset)	vecell	elist = NULL; 	mpcell	rest;        /*	 * The parent list is stored in the scratch slot of the         * vertex.	 */        rest = (mpcell) vto->scratch;	while (!mp_null(rest)) {	    char	*parent_name;	    mpdata	parent_data;	    mpcell	parent = (mpcell) mp_car(rest);	    vertex	vfrom;	    edge	e;	    	    parent_name = fn_name((mpsym) mp_car(parent));	    parent_data = (mpdata) mp_cdr(parent);	    vfrom = hlookup(parent_name);	    if (vfrom == vto) {		vto->srefs += 1;	    } else {		e = make_edge(vfrom, vto, parent_data);		e_count +=  1;		epush(e, eset);		epush(e, elist);	    }   	    rest = mp_cdr(rest);	}        vto->backedges = elist;    END_DO    DO_VLIST (v, vset)	DO_ELIST (e, v->backedges)	    vertex	vfrom = e->from;	    epush(e, vfrom->edges);        END_DO    END_DO    return make_graph(v_count, vset, e_count, eset);}edgesame_edge(from_v, to_v, elist)vertex	from_v, to_v;vecell	elist;{    DO_ELIST (e, elist)	if ((e->to == to_v) && (e->from == from_v)) {	    return e;	}    END_DO    return NULL;}int	edge_less_compar(e1, e2)edge	*e1, *e2;{    char	*e1_from, *e1_to, *e2_from, *e2_to;    e1_from = (*e1)->from->name;    e1_to = (*e1)->to->name;    e2_from = (*e2)->from->name;    e2_to = (*e2)->to->name;    if (strcmp(e1_from, e2_from) == 0) {	return strcmp(e1_to, e2_to);    } else {	return strcmp(e1_from, e2_from);    }}intvdata_compar(v1p, v2p)vertex	*v1p, *v2p;{    int		d1 = mp_sum_data((*v1p)->data);    int		d2 = mp_sum_data((*v2p)->data);    if (d1 < d2) {	return 1;    } else if (d1 > d2) {	return -1;    } else {	return 0;    }}intvbytes_compar(v1p, v2p)vertex	*v1p, *v2p;{    int		d1 = sum_vertex_bytes1(*v1p);    int		d2 = sum_vertex_bytes1(*v2p);    if (d1 < d2) {	return 1;    } else if (d1 > d2) {	return -1;    } else {	return 0;    }}vecellvsort(vlist, compar)vecell	vlist;int 	(*compar)();{    int	llength = velength(vlist);    vertex	*vvec = (vertex *) calloc(llength, sizeof(vertex));    int		i;    vecell	newvlist = NULL;    i = 0;    DO_VLIST (v, vlist)        vvec[i] = v;        i += 1;    END_DO    qsort((char *) vvec, llength, sizeof(vertex), compar);    for (i = (llength - 1); i >= 0; i--) {	epush(vvec[i], newvlist);    }    return newvlist;}vecellesort(elist, compar)vecell	elist;int 	(*compar)();{    int	llength = velength(elist);    edge	*evec = (edge *) calloc(llength, sizeof(edge));    int		i;    vecell	newelist = NULL;    i = 0;    DO_ELIST (e, elist)        evec[i] = e;        i += 1;    END_DO    qsort((char *) evec, llength, sizeof(edge), compar);    for (i = (llength - 1); i >= 0; i--) {	epush(evec[i], newelist);    }    return newelist;}graphmerge_scc(g)graph	g;{    graph	newg = copy_graph(g);    vecell	vset = NULL, eset = NULL, added_eset = NULL;    int	cycle_count = 0;    vecell	cc_list = scc(newg);/*    print_graph(stdout, newg);*/    /*     * Create vertices corresponding to each of the cycles.     */    DO_LIST (cc, cc_list)	if (velength(cc) != 1) {	    vertex newv;	    /*	     * Create a vertex to represent the SCC.	     */	    cycle_count += 1;	    newv = make_vertex(new_cycle_name(cycle_count),			       cycle_count + newg->v_count - 1,			       mp_new_data(),			       NULL);	    vpush(newv, vset);	    newv->scc_members = cc;	    DO_VLIST(v, cc)		vpush(v, vset);		v->in_cycle = newv;		newv->data = mp_add_data(newv->data, v->data);	    END_DO	} else {	    vpush((vertex) vehd(cc), vset);	}    END_DO    /*     * Look at all the edges and create a new edge set.     */    DO_ELIST (e, newg->eset) 	/*	 * Cases --	 * 1. Either vertex is part of a cycle.	 * 2. Neither vertex is in a cycle.	 */	vertex	from_v = (e->from)->in_cycle;	vertex	to_v = (e->to)->in_cycle;		if ((from_v != NULL) || (to_v != NULL)) {	    if (from_v == NULL) {		from_v = e->from;	    }	    if (to_v == NULL) {		to_v = e->to;	    }	    if (from_v != to_v) {		edge newe = same_edge(from_v, to_v, added_eset);		if (newe != NULL) {		    newe->data = mp_add_data(newe->data, e->data);		} else {		    mpdata	newdata = mp_new_data();		    		    newdata = mp_add_data(newdata, e->data);		    newe = make_edge(from_v, to_v, newdata);		    epush(newe, added_eset);		}	    } else {		from_v->srefs += 1;	    }	}	epush(e, eset);    END_DO    DO_ELIST (e, added_eset)	epush(e, eset);    END_DO    eset = esort(eset, edge_less_compar);    /*     * Remove the old edges and add the new ones.     */    DO_VLIST(v, vset) 	v->edges = NULL;	v->backedges = NULL;    END_DO    DO_ELIST(e, eset)	vertex	vfrom = e->from;	vertex	vto = e->to;	epush(e, vfrom->edges);	epush(e, vto->backedges);    END_DO    newg->v_count = velength(vset);    newg->vset = vereverse(vset);    newg->e_count = velength(eset);    newg->eset = eset;    return newg;}boolno_unused_incident_edges_from(v)vertex	v;{    vecell	elist = v->edges;    DO_ELIST (e, elist)	if (e->mark == UNUSED) {	    return FALSE;	}    END_DO    return TRUE;}edgefirst_unused_edge(elist)vecell	elist;{    DO_ELIST (e, elist)	if (e->mark == UNUSED) {	    return e;	}    END_DO    fprintf(stderr, "first_unused_edge -- no unused edges present:\n");    print_vecons(stderr, elist);    return NULL;}vertexfind_vertex_with_k_equal_zero(vlist)vecell	vlist;{    DO_VLIST (v, vlist)	if (v->k == 0) {	    return v;	}    END_DO;    return NULL;}  /* * Find the strongly connected components in the graph. */vecellscc(g)graph	g;{    vecell	vset = g->vset;    vecell	eset = g->eset;    vecell	scc_vset = NULL;    vecell	S = NULL;    int		i = 0;    vertex	v = (vertex) vehd(vset);    vertex	u, new_u;    edge	e;    DO_ELIST (e, eset)	e->mark = UNUSED;    END_DO    DO_VLIST (v, vset)        v->father = (vertex) UNDEFINED;        v->k = 0;    END_DO step2:    i += 1;    v->k = i;    v->L = i;    vpush(v, S);    v->on_S = TRUE; step3:    if (no_unused_incident_edges_from(v)) {	goto step7;    } step4:    e = first_unused_edge(v->edges);    u = e->to;    e->mark = USED;    if (u->k == 0) {	u->father = v;	v = u;	goto step2;    } step5:    if (u->k > v->k) {	goto step3;    }    if (!(u->on_S)) {	goto step3;    } step6:    if (!((u->k < v->k) && u->on_S)) {	fprintf(stderr, "assertion at step6 failed\n");    }    v->L = min(v->L, u->k);    goto step3; step7:    if (v->L == v->k) {	vecell	comp = NULL;	vertex	topv;	do {	    topv = (vertex) vehd(S);	    S = vetl(S);	    vpush(topv, comp);	    topv->on_S = FALSE;	} while (topv != v);	cpush(comp, scc_vset);    } step8:    if (v->father != (vertex) UNDEFINED) {	(v->father)->L = min(v->L, (v->father)->L);	v = v->father;	goto step3;    } step9:    if (v->father != (vertex) UNDEFINED) {	fprintf(stderr, "assertion at step9 failed\n");    }    new_u = find_vertex_with_k_equal_zero(vset);    if (new_u != NULL) {	v = new_u;	goto step2;    }    if (S != NULL) {	cpush(S, scc_vset);    }    return scc_vset;}intmp_count_nodes(){    int		i, count;    mpcell	chain;    count = 0;    for (i = 0; i < MP_HASH_SIZE; i++) {	chain = hmem[i];	while (!mp_null(chain)) {	    count += 1;	    chain = (mpcell) mp_cdr(chain);	}    }    return count;}char *new_cycle_name(n)int	n;{    char	chars[255];    sprintf(chars, "<cycle %d>", n);    return strdup(chars);}char *int1_sprintf(fmt, n)char	*fmt;int	n;{    char	chars[255];    sprintf(chars, fmt, n);    return strdup(chars);}char *s1_sprintf(fmt, s)char	*fmt;char	*s;{    char	chars[255];    sprintf(chars, fmt, s);    return strdup(chars);}char *f1_sprintf(fmt, d)char	*fmt;double	d;{    char	chars[255];    sprintf(chars, fmt, d);    return strdup(chars);}char *vertex_name_string(v)vertex	v;{    char	chars[255];    if (v->in_cycle == NULL) {	sprintf(chars, "%s [%d]", v->name, v->index);    } else {	sprintf(chars, "%s [%d] in %s", v->name, v->index, v->in_cycle->name);    }    return strdup(chars);}	voidprint_dynamic_graph_header(f)FILE	*f;{    fprintf(f, "\f\n\n");    fprintf(f, template2,	    "",	    "self",	    "",	    "",	    "     /ances",	    "     /ances",	    "called",	    "/total ",	    "    ancestors");    fprintf(f, template2,	    "index",	    "+  ",	    "self",	    "(%)",	    " size-func",	    " frac",	    "called",	    "/recur",	    "name [index]");    fprintf(f, template2,	    "",	    "desc",	    "",	    "",	    "     \\desc",	    "     \\desc",	    "called",	    "/total",	    "    descendents");    print_separator(f);}#define template3 \"\n-------------------------------s--m--l--x----s--m--l--x----------\n\n"  voidprint_separator(f)FILE	*f;{    fprintf(f, template3, "", "");}vecellfilter_cycle_edges(elist)vecell	elist;{    vecell	result = NULL;        DO_ELIST(e, elist)	if (!((e->to->scc_members != NULL) ||	      (e->from->scc_members != NULL))) {	    epush(e, result);	}    END_DO    return vereverse(result);}mpdata    add_data_over(elist)vecell	elist;{    mpdata	result = mp_new_data();        DO_ELIST(e, elist)	result = mp_add_data(result, e->data);    END_DO    return result;}voidprint_normal_vertex(v, f, nbytes)vertex	v;FILE	*f;int	nbytes;{    vecell	plist = v->backedges;    vecell	clist = v->edges;    vecell	filt_plist, filt_clist;    int		pbytesum = sum_data_over_edges(plist);    int		cbytesum = sum_data_over_edges(clist);    mpdata	all_pdata;    mpdata	all_cdata;    if (v->scc_members != NULL) {	filt_plist = plist;	filt_clist = clist;    } else {	filt_plist = filter_cycle_edges(plist);	filt_clist = filter_cycle_edges(clist);    }    all_pdata = add_data_over(filt_plist);    all_cdata = add_data_over(filt_clist);    /*     * Parent listings.     */    if (velength(filt_plist) > 1) {	fprintf(f, template2p1,		"", "all",		mp_sum_data(all_pdata),		"",		type_fraction_string(all_pdata),		"", "", "", "");    }        DO_ELIST(e, filt_plist)	mpdata	edata = e->data;	int	pcallsum = sum_vertex_outgoing_calls(e->from);	int	ecallsum = mp_sum_calls(edata);	int	ebytesum = mp_sum_data(edata);	fprintf(f, template2p2,		"", "",		ebytesum,		percent_string(ebytesum, pbytesum),		type_fraction_string(edata),		relative_type_string(edata, all_pdata),		ecallsum,		int1_sprintf("/%d", pcallsum),		s1_sprintf("    %s", vertex_name_string(e->from)));    END_DO    /*     * Self listing.     */    print_self_line(f, v, nbytes, FALSE);    /*     * Children listings.     */	    DO_ELIST(e, filt_clist)	mpdata	edata = e->data;	int	ccallsum = sum_vertex_incoming_calls(e->to);	int	ecallsum = mp_sum_calls(edata);	int	ebytesum = mp_sum_data(edata);	fprintf(f, template2p2,		"", "",		ebytesum,		percent_string(ebytesum, cbytesum),		type_fraction_string(edata),		relative_type_string(edata, all_cdata),		ecallsum,		int1_sprintf("/%d", ccallsum),		s1_sprintf("    %s", vertex_name_string(e->to)));    END_DO          if (velength(filt_clist) > 1) {	fprintf(f, template2p1,		"", "all",		mp_sum_data(all_cdata),		"",		type_fraction_string(all_cdata),		"", "", "", "");    }}voidprint_self_line(f, v, nbytes, cyclep)FILE	*f;vertex	v;int	nbytes;bool	cyclep;{    vecell	plist = v->backedges;    vecell	clist = v->edges;    int		pcallsum = sum_calls_over_edges(plist);    int		cbytesum = sum_data_over_edges(clist);    int		self_bytesum = mp_sum_data(v->data);    int		fbytesum = self_bytesum + cbytesum;    fprintf(f, template2p2,	    int1_sprintf("[%d]", v->index),	    f1_sprintf("%7.1f", dpercent(fbytesum, nbytes)),	    self_bytesum,	    percent_string(self_bytesum, fbytesum),	    type_fraction_string(v->data),	    " -----------",	    pcallsum,	    ((v->srefs == 0) ? "" : int1_sprintf("+%d", v->srefs)),	    ((cyclep != 0) ? s1_sprintf("%s as a whole", vertex_name_string(v))	     : vertex_name_string(v)));}    voidprint_vertex_in_cycle(v, f, nbytes)vertex	v;FILE	*f;int	nbytes;{    vecell	plist = filter_cycle_edges(v->backedges);    vecell	clist = filter_cycle_edges(v->edges);    int		pcallsum = 0;    int		self_bytesum = mp_sum_data(v->data);    /*     * Parent listings.     */        DO_ELIST(e, plist)	mpdata	edata = e->data;	int	ecallsum = mp_sum_calls(edata);            pcallsum += ecallsum;	fprintf(f, template2c1,		"", "", "", "", "", "", 		ecallsum,		"",		s1_sprintf("    %s", vertex_name_string(e->from)));    END_DO    /*     * Self listing.     */    fprintf(f, template2p2,	    int1_sprintf("[%d]", v->index),	    f1_sprintf("%7.1f", dpercent(self_bytesum, nbytes)),	    self_bytesum,	    "",	    type_fraction_string(v->data),	    " -----------",	    pcallsum,	    ((v->srefs == 0) ? "" : int1_sprintf("+%d", v->srefs)),	    vertex_name_string(v));    /*     * Children listings.     */	    DO_ELIST(e, clist)	mpdata	edata = e->data;	int	ecallsum = mp_sum_calls(edata);    	fprintf(f, template2c1,		"", "", "", "", "", "", 		ecallsum,		"",		s1_sprintf("    %s", vertex_name_string(e->to)));    END_DO}voidprint_cycle_information(v, f, nbytes)vertex	v;FILE	*f;int	nbytes;{    vecell	members = v->scc_members;    mpdata	mdata = v->data;    int		mbytesum = mp_sum_data(mdata);    /*     * Self listing.     */    print_self_line(f, v, nbytes, TRUE);    /*     * Members listing.     */    DO_VLIST(v, members)	mpdata	vdata = v->data;	int	vbytesum = mp_sum_data(vdata);	fprintf(f, template2p1,		"", "",		vbytesum,		percent_string(vbytesum, (mbytesum == 0 ? 1 : mbytesum)),		type_fraction_string(vdata),		relative_type_string(vdata, mdata),		"", "", s1_sprintf("    %s", vertex_name_string(v)));    END_DO}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -