Skip to content

Commit

Permalink
prepare code for large matrix generation refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Hannes Gredler committed Aug 31, 2024
1 parent c4a5295 commit 6a4e3d4
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 59 deletions.
6 changes: 3 additions & 3 deletions code/lspgen/src/lspgen_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ lspgen_ctrl_write_cb(timer_s *timer)
return;
}
json_header = malloc(128);
snprintf(json_header, 128,
"{\n\"command\": \"%s\",\n\"arguments\": {\n\"instance\": %u,\n\"pdu\": [",
snprintf(json_header, 128-1,
"{\n\"command\": \"%s\",\n\"arguments\": {\n\"instance\": %u,\n\"pdu\": [",
json_command, ctx->ctrl_instance);
push_data(&ctx->ctrl_io_buf, (uint8_t *)json_header, strlen(json_header));
free(json_header);
Expand Down Expand Up @@ -412,4 +412,4 @@ lspgen_ctrl_connect_cb(timer_s *timer)
close(ctx->ctrl_socket_sockfd);
ctx->ctrl_socket_sockfd = 0;
LOG(ERROR, "Error connecting to %s, %s\n", ctx->ctrl_socket_path, strerror(errno));
}
}
128 changes: 72 additions & 56 deletions code/lspgen/src/lspgen_forest.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ init_array(int *a, int end)
}
}

void
print_graph(lsdb_ctx_t *ctx, int v, int e, int *adj_matrix)
unsigned int
convert_matrix_graph(lsdb_ctx_t *ctx, int v, int *adj_matrix)
{
struct lsdb_node_ node_template;
struct lsdb_link_ link_template;
Expand All @@ -83,8 +83,6 @@ print_graph(lsdb_ctx_t *ctx, int v, int e, int *adj_matrix)
unsigned int root = 0;
__uint128_t addr;

UNUSED(e);

memset(&node_template, 0, sizeof(node_template));
memset(&link_template, 0, sizeof(link_template));

Expand Down Expand Up @@ -166,52 +164,31 @@ print_graph(lsdb_ctx_t *ctx, int v, int e, int *adj_matrix)
}
}

/*
* Store root.
*/
switch (ctx->protocol_id) {
case PROTO_ISIS:
/* BCD notation for IS-IS */
addr = lspgen_load_addr((uint8_t*)&ctx->ipv4_node_prefix.address, sizeof(ipv4addr_t)) + root - 1;
lspgen_store_bcd_addr(addr, ctx->root_node_id, 4);
break;
default:
/* dotted decimal notation for everybody else */
memcpy(&ctx->root_node_id, &ctx->ipv4_node_prefix.address, 4);
break;
}
return root;
}

/*
* This function generates a random connected simple graph with v vertices and max(v-1,e) edges. The graph can be
* weighted (weight_flag == 1) or unweighted (weight_flag != 1). If it is weighted, the weights are in the range 1 to
* max_wgt. It is assumed that e <= v(v-1)/2. (In this program, this assured because of the call to
* fix_imbalanced_graph.)
* This function generates a random connected simple graph with v vertices and max(v-1,e) edges.
* The graph can be weighted (weight_flag == 1) or unweighted (weight_flag != 1).
* If it is weighted, the weights are in the range 1 to max_wgt.
* It is assumed that e <= v(v-1)/2. (In this program, this assured because of the call to fix_imbalanced_graph.)
*
* To generate a random connected graph, we begin by generating a random spanning tree.
* To generate a random spanning tree, we first generate a random permutation tree[0],...,tree[v-1].
* (v = number of vertices.) We then iteratively add edges to form a tree.
* We begin with the tree consisting of vertex tree[0] and no edges. At the iterative step,
* we assume that tree[0],tree[1],...,tree[i-1] are in the tree.
* We then add vertex tree[i] to the tree by adding the edge (tree[i],tree[rand(i)]).
* (This construction is similar to that of Prim's algorithm.)
* Finally, we add random edges to produce the desired number of edges.
*
* To generate a random connected graph, we begin by generating a random spanning tree. To generate a random spanning
* tree, we first generate a random permutation tree[0],...,tree[v-1]. (v = number of vertices.) We then iteratively
* add edges to form a tree. We begin with the tree consisting of vertex tree[0] and no edges. At the iterative step,
* we assume that tree[0],tree[1],...,tree[i-1] are in the tree. We then add vertex tree[i] to the tree by adding the
* edge (tree[i],tree[rand(i)]). (This construction is similar to that of Prim's algorithm.) Finally, we add random
* edges to produce the desired number of edges.
* Returns root node index.
*/
static void
lsdb_random_connected_graph(lsdb_ctx_t *ctx, int v, int e, int max_wgt, int weight_flag)
unsigned int
lsdb_random_connected_graph(lsdb_ctx_t *ctx, int *tree, int *adj_matrix,
int v, int e, int max_wgt, int weight_flag)
{
int i, j, count, index, *adj_matrix, *tree;

LOG(NORMAL, "Generating a graph of %d nodes and %d links\n", v, e);

if ((adj_matrix = (int *) calloc(v * v, sizeof(int))) == NULL) {
LOG(ERROR, "Not enough room for %d nodes %d links graph\n", v, e);
return;
}

if ((tree = (int *) calloc(v, sizeof(int))) == NULL) {
LOG(ERROR, "Not enough room for %d nodes %d links graph\n", v, e);
free(adj_matrix);
return;
}
int i, j, count, index;

/*
* Generate a random permutation in the array tree.
Expand All @@ -222,12 +199,14 @@ lsdb_random_connected_graph(lsdb_ctx_t *ctx, int v, int e, int max_wgt, int weig
/*
* Next generate a random spanning tree. The algorithm is:
*
* Assume that vertices tree[ 0 ],...,tree[ i - 1 ] are in the tree. Add an edge incident on tree[ i ] and a
* Assume that vertices tree[ 0 ],...,tree[ i - 1 ] are in the tree.
* Add an edge incident on tree[ i ] and a
* random vertex in the set {tree[ 0 ],...,tree[ i - 1 ]}.
*/
for (i = 1; i < v; i++) {
j = ran(i);
adj_matrix[tree[i] * v + tree[j]] = adj_matrix[tree[j] * v + tree[i]] = weight_flag ? 1 + ran(max_wgt) : 1;
adj_matrix[tree[i] * v + tree[j]] =
adj_matrix[tree[j] * v + tree[i]] = weight_flag ? 1 + ran(max_wgt) : 1;
}

/*
Expand All @@ -237,11 +216,13 @@ lsdb_random_connected_graph(lsdb_ctx_t *ctx, int v, int e, int max_wgt, int weig
i = ran(v);
j = ran(v);

if (i == j)
if (i == j) {
continue;
}

if (i > j)
if (i > j) {
swap(&i, &j);
}

index = i * v + j;
if (!adj_matrix[index]) {
Expand All @@ -250,24 +231,53 @@ lsdb_random_connected_graph(lsdb_ctx_t *ctx, int v, int e, int max_wgt, int weig
}
}

print_graph(ctx, v, count, adj_matrix);

free(tree);
free(adj_matrix);
return (convert_matrix_graph(ctx, v, adj_matrix));
}

void
lsdb_init_graph(lsdb_ctx_t *ctx)
{
int v, e, *adj_matrix, *tree;
struct lsdb_node_ node_template;
struct lsdb_link_ link_template;
struct lsdb_node_ *node;
uint32_t idx;
uint32_t idx, root;
__uint128_t addr;

srand(ctx->seed);

lsdb_random_connected_graph(ctx, ctx->num_nodes, ctx->num_nodes << 1,
sizeof(weights) / sizeof(int) - 1, 1);
v = ctx->num_nodes;
e = ctx->num_nodes*2;

LOG(NORMAL, "Generating a graph of %d nodes and %d links\n", v, e);

if ((adj_matrix = (int *) calloc(v * v, sizeof(int))) == NULL) {
LOG(ERROR, "Not enough room for %d nodes %d links graph\n", v, e);
return;
}

if ((tree = (int *) calloc(v, sizeof(int))) == NULL) {
LOG(ERROR, "Not enough room for %d nodes %d links graph\n", v, e);
free(adj_matrix);
return;
}

root = lsdb_random_connected_graph(ctx, tree, adj_matrix, v, e,
sizeof(weights) / sizeof(int) - 1, 1);
/*
* Store root.
*/
switch (ctx->protocol_id) {
case PROTO_ISIS:
/* BCD notation for IS-IS */
addr = lspgen_load_addr((uint8_t*)&ctx->ipv4_node_prefix.address, sizeof(ipv4addr_t)) + root - 1;
lspgen_store_bcd_addr(addr, ctx->root_node_id, 4);
break;
default:
/* dotted decimal notation for everybody else */
memcpy(&ctx->root_node_id, &ctx->ipv4_node_prefix.address, 4);
break;
}

/*
* First lookup the root node.
Expand All @@ -277,7 +287,7 @@ lsdb_init_graph(lsdb_ctx_t *ctx)
node = lsdb_get_node(ctx, &node_template);
if (!node) {
LOG(ERROR, "Could not find root node %s\n", lsdb_format_node_id(node_template.key.node_id));
return;
goto cleanup;
}

LOG(NORMAL, " Root node %s\n", lsdb_format_node(node));
Expand All @@ -304,4 +314,10 @@ lsdb_init_graph(lsdb_ctx_t *ctx)
lsdb_add_link(ctx, node, &link_template);
}
}

cleanup:

free(tree);
free(adj_matrix);

}

0 comments on commit 6a4e3d4

Please sign in to comment.