Exemplo n.º 1
0
/*
 * Convert a tapelist into a parseable string of tape labels and file numbers.
 */
char *
marshal_tapelist(
    tapelist_t *tapelist,
    int		do_escape,
    int         with_storage)
{
    tapelist_t *cur_tape;
    char *str;
    GPtrArray *strarray = g_ptr_array_new();
    GString *strbuf;
    gchar **strings;

    for (cur_tape = tapelist; cur_tape; cur_tape = cur_tape->next) {
        GPtrArray *array = g_ptr_array_new();
        char *p;
	int c;

	strbuf = g_string_new("");
	if (with_storage) {
            p = escape_label(cur_tape->storage);
	    g_string_append(strbuf, p);
	    g_free(p);
	    g_string_append_c(strbuf, ':');
	}

        p = (do_escape) ? escape_label(cur_tape->label)
            : g_strdup(cur_tape->label);
        g_string_append(strbuf, p);
        g_free(p);

        g_string_append_c(strbuf, ':');

        for (c = 0; c < cur_tape->numfiles; c++) {
            p = g_strdup_printf("%lld", (long long)cur_tape->files[c]);
            g_ptr_array_add(array, p);
        }

        g_ptr_array_add(array, NULL);

        strings = (gchar **)g_ptr_array_free(array, FALSE);
        p = g_strjoinv(",", strings);
        g_strfreev(strings);

        g_string_append(strbuf, p);
        g_free(p);

        g_ptr_array_add(strarray, g_string_free(strbuf, FALSE));
    }

    g_ptr_array_add(strarray, NULL);

    strings = (gchar **)g_ptr_array_free(strarray, FALSE);
    str = g_strjoinv(";", strings);
    g_strfreev(strings);

    return str;
}
Exemplo n.º 2
0
void dump_network_graph(simulation const& s, std::string filename)
{
	// all edges (directed).
	std::set<std::pair<std::shared_ptr<sink>, std::shared_ptr<sink>>> edges;

	// all network nodes
	std::unordered_set<std::shared_ptr<sink>> nodes;

	// local nodes (subgrapgs)
	std::vector<std::unordered_set<std::shared_ptr<sink>>> local_nodes;

	const std::vector<asio::io_service*> io_services = s.get_all_io_services();

	for (auto ios : io_services)
	{
		std::shared_ptr<sink> ep = std::make_shared<endpoint>(*ios);
		local_nodes.push_back(std::unordered_set<std::shared_ptr<sink>>());
		local_nodes.back().insert(ep);

		for (auto const& ip : ios->get_ips())
		{
			route in = ios->get_incoming_route(ip);
			route out = ios->get_outgoing_route(ip);

			// this is the outgoing node for this endpoint. This is
			// how it connects to the network.
			const std::shared_ptr<sink> egress = out.empty() ? ep : out.last();

			// first add both the incoming and outgoing chains
			std::shared_ptr<sink> prev;
			while (!in.empty())
			{
				auto node = in.pop_front();
				local_nodes.back().insert(node);
				if (prev) edges.insert({prev, node});
				prev = node;
			}
			if (prev) edges.insert({prev, ep});

			prev = ep;
			while (!out.empty())
			{
				auto node = out.pop_front();
				local_nodes.back().insert(node);
				edges.insert({prev, node});
				prev = node;
			}

			// then connect the endpoint of those chains to the rest of the network.
			// Since the network may be arbitrarily complex, we actually have to
			// completely iterate over all other endpoints

			for (auto ios2 : io_services)
			{
				for (auto const& ip2 : ios2->get_ips())
				{
					route network = s.config().channel_route(
						ip, ip2);

					std::shared_ptr<sink> last = ios2->get_incoming_route(ip2).next_hop();

					prev = egress;
					while (!network.empty())
					{
						auto node = network.pop_front();
						nodes.insert(node);
						edges.insert({prev, node});
						prev = node;
					}
					edges.insert({prev, last});
				}
			}
		}
	}

	// by now, the nodes and edges should represent the complete graph. Render it
	// into dot.

	FILE* f = fopen(filename.c_str(), "w+");

	fprintf(f, "digraph network {\n"
		"concentrate=true;\n"
		"overlap=scale;\n"
		"splines=true;\n");

	fprintf(f, "\n// nodes\n\n");

	for (auto n : nodes)
	{
		std::string attributes = n->attributes();
		fprintf(f, " \"%p\" [label=\"%s\",style=\"filled\",color=\"red\"%s%s];\n"
			, n.get()
			, escape_label(n->label()).c_str()
			, attributes.empty() ? "" : ", "
			, attributes.c_str());
	}

	fprintf(f, "\n// local networks\n\n");

	int idx = 0;
	for (auto ln : local_nodes)
	{
		fprintf(f, "subgraph cluster_%d {\n", idx++);

		for (auto n : ln)
		{
			std::string attributes = n->attributes();
			fprintf(f, " \"%p\" [label=\"%s\",style=\"filled\",color=\"green\"%s%s];\n"
				, n.get()
				, escape_label(n->label()).c_str()
				, attributes.empty() ? "" : ", "
				, attributes.c_str());
		}

		fprintf(f, "}\n");
	}

	fprintf(f, "\n// edges\n\n");

	while (!edges.empty())
	{
		auto edge = *edges.begin();
		edges.erase(edges.begin());

		fprintf(f, "\"%p\" -> \"%p\"\n"
			, edge.first.get()
			, edge.second.get());
	}

	fprintf(f, "}\n");
	fclose(f);
}