From bda9c466182c5917c12405e834c5e3967a7692a9 Mon Sep 17 00:00:00 2001 From: fc_botelho Date: Mon, 3 Jan 2005 20:47:21 +0000 Subject: [PATCH] using less space to store the used_edges and critical_nodes arrays --- src/bmz.c | 26 +++++++++++++++++--------- src/graph.c | 36 ++++++++++++++++++++---------------- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/bmz.c b/src/bmz.c index 61a1b5b..c0bfd0c 100644 --- a/src/bmz.c +++ b/src/bmz.c @@ -16,10 +16,16 @@ static uint32 UNDEFINED = UINT_MAX; +static const char bitmask[8] = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 }; +#define GETBIT(array, i) (array[(i) / 8] & bitmask[(i) % 8]) +#define SETBIT(array, i) (array[(i) / 8] |= bitmask[(i) % 8]) +#define UNSETBIT(array, i) (array[(i) / 8] &= (~(bitmask[(i) % 8]))) + static int bmz_gen_edges(mph_t *mph); static void bmz_traverse_critical_nodes(bmz_mph_data_t *bmz, uint32 v, uint32 * biggest_g_value, uint32 * biggest_edge_value, uint8 * used_edges); static void bmz_traverse_non_critical_nodes(bmz_mph_data_t *bmz, uint8 * used_edges); + mph_t *bmz_mph_new(key_source_t *key_source) { mph_t *mph = NULL; @@ -70,7 +76,6 @@ mphf_t *bmz_mph_create(mph_t *mph, float bmz_c) uint32 i; uint32 iterations = 10; uint8 *used_edges = NULL; - uint32 unused_edge_index = 0; uint32 biggest_g_value = 0; uint32 biggest_edge_value = 1; DEBUGP("bmz_c: %f\n", bmz_c); @@ -131,12 +136,13 @@ mphf_t *bmz_mph_create(mph_t *mph, float bmz_c) // Searching step if (mph->verbosity) { - fprintf(stderr, "Starting Searching step\n"); + fprintf(stderr, "Starting Searching step.\n"); fprintf(stderr, "\tTraversing critical vertices.\n"); } DEBUGP("Searching step\n"); - used_edges = (uint8 *)malloc(bmz->m*sizeof(uint8)); - memset(used_edges, 0, bmz->m); + + used_edges = (uint8 *)malloc((bmz->m*sizeof(uint8))/8 + 1); + memset(used_edges, 0, bmz->m/8 + 1); free(bmz->g); bmz->g = malloc(bmz->n * sizeof(uint32)); assert(bmz->g); @@ -211,7 +217,7 @@ static void bmz_traverse_critical_nodes(bmz_mph_data_t *bmz, uint32 v, uint32 * if (graph_node_is_critical(bmz->graph, lav) && (bmz->g[lav] != UNDEFINED)) { assert(next_g + bmz->g[lav] < bmz->m); - if (used_edges[next_g + bmz->g[lav]]) + if (GETBIT(used_edges, next_g + bmz->g[lav])) { collision = 1; break; @@ -226,7 +232,7 @@ static void bmz_traverse_critical_nodes(bmz_mph_data_t *bmz, uint32 v, uint32 * { if (graph_node_is_critical(bmz->graph, lav) && (bmz->g[lav] != UNDEFINED)) { - used_edges[next_g + bmz->g[lav]] = 1; + SETBIT(used_edges,next_g + bmz->g[lav]); if(next_g + bmz->g[lav] > *biggest_edge_value) *biggest_edge_value = next_g + bmz->g[lav]; } } @@ -245,7 +251,7 @@ static uint32 next_unused_edge(bmz_mph_data_t *bmz, uint8 * used_edges, uint32 u while(1) { assert(unused_edge_index < bmz->m); - if(used_edges[unused_edge_index]) unused_edge_index ++; + if(GETBIT(used_edges, unused_edge_index)) unused_edge_index ++; else break; } return unused_edge_index; @@ -259,16 +265,18 @@ static void bmz_traverse(bmz_mph_data_t *bmz, uint8 * used_edges, uint32 v, uint { DEBUGP("Visiting neighbor %u\n", neighbor); if(bmz->g[neighbor] != UNDEFINED) continue; - *unused_edge_index = next_unused_edge(bmz, used_edges, *unused_edge_index + 1); + *unused_edge_index = next_unused_edge(bmz, used_edges, *unused_edge_index); bmz->g[neighbor] = *unused_edge_index - bmz->g[v]; + (*unused_edge_index)++; bmz_traverse(bmz, used_edges, neighbor, unused_edge_index); + } } static void bmz_traverse_non_critical_nodes(bmz_mph_data_t *bmz, uint8 * used_edges) { - uint32 i, v1, v2, unused_edge_index = -1; + uint32 i, v1, v2, unused_edge_index = 0; DEBUGP("Labelling non critical vertices\n"); for(i = 0; i < bmz->m; i++) { diff --git a/src/graph.c b/src/graph.c index a2a927a..00b3fca 100644 --- a/src/graph.c +++ b/src/graph.c @@ -10,6 +10,11 @@ //#define DEBUG #include "debug.h" +static const char bitmask[8] = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 }; +#define GETBIT(array, i) (array[(i) / 8] & bitmask[(i) % 8]) +#define SETBIT(array, i) (array[(i) / 8] |= bitmask[(i) % 8]) +#define UNSETBIT(array, i) (array[(i) / 8] &= (~(bitmask[(i) % 8]))) + #define abs_edge(e, i) (e % g->nedges + i * g->nedges) struct __graph_t @@ -172,7 +177,7 @@ static int find_degree1_edge(graph_t *g, uint32 v, char *deleted, uint32 *e) char found = 0; DEBUGP("Checking degree of vertex %u\n", v); if (edge == EMPTY) return 0; - else if (!deleted[abs_edge(edge, 0)]) + else if (!(GETBIT(deleted, abs_edge(edge, 0)))) { found = 1; *e = edge; @@ -181,7 +186,7 @@ static int find_degree1_edge(graph_t *g, uint32 v, char *deleted, uint32 *e) { edge = g->next[edge]; if (edge == EMPTY) break; - if (deleted[abs_edge(edge, 0)]) continue; + if (GETBIT(deleted, abs_edge(edge, 0))) continue; if (found) return 0; DEBUGP("Found first edge\n"); *e = edge; @@ -203,7 +208,7 @@ static void cyclic_del_edge(graph_t *g, uint32 v, char *deleted) while(1) { DEBUGP("Deleting edge %u (%u->%u)\n", e, g->edges[abs_edge(e, 0)], g->edges[abs_edge(e, 1)]); - deleted[abs_edge(e, 0)] = 1; + SETBIT(deleted, abs_edge(e, 0)); v2 = g->edges[abs_edge(e, 0)]; if (v2 == v1) v2 = g->edges[abs_edge(e, 1)]; @@ -223,8 +228,8 @@ int graph_is_cyclic(graph_t *g) { uint32 i; uint32 v; - char *deleted = (char *)malloc(g->nedges*sizeof(char)); - memset(deleted, 0, g->nedges); + char *deleted = (char *)malloc((g->nedges*sizeof(char))/8 + 1); + memset(deleted, 0, g->nedges/8 + 1); DEBUGP("Looking for cycles in graph with %u vertices and %u edges\n", g->nnodes, g->nedges); for (v = 0; v < g->nnodes; ++v) @@ -233,7 +238,7 @@ int graph_is_cyclic(graph_t *g) } for (i = 0; i < g->nedges; ++i) { - if (!(deleted[i])) + if (!(GETBIT(deleted, i))) { DEBUGP("Edge %u %u->%u was not deleted\n", i, g->edges[i], g->edges[i + g->nedges]); free(deleted); @@ -246,17 +251,16 @@ int graph_is_cyclic(graph_t *g) uint8 graph_node_is_critical(graph_t * g, uint32 v) /* included -- Fabiano */ { - return g->critical_nodes[v]; + return GETBIT(g->critical_nodes,v); } void graph_obtain_critical_nodes(graph_t *g) /* included -- Fabiano*/ { uint32 i; uint32 v; - char *deleted = (char *)malloc(g->nedges*sizeof(char)); - memset(deleted, 0, g->nedges); -/* g->critical_nodes = (uint8 *)malloc((size_t)(ceil(g->nnodes*sizeof(uint8)/8.))); */ - g->critical_nodes = (uint8 *)malloc(g->nnodes*sizeof(uint8)); + char *deleted = (char *)malloc((g->nedges*sizeof(char))/8+1); + memset(deleted, 0, g->nedges/8 + 1); + g->critical_nodes = (uint8 *)malloc((g->nnodes*sizeof(uint8))/8 + 1); g->ncritical_nodes = 0; DEBUGP("Looking for the 2-core in graph with %u vertices and %u edges\n", g->nnodes, g->nedges); for (v = 0; v < g->nnodes; ++v) @@ -266,18 +270,18 @@ void graph_obtain_critical_nodes(graph_t *g) /* included -- Fabiano*/ for (i = 0; i < g->nedges; ++i) { - if (!(deleted[i])) + if (!(GETBIT(deleted,i))) { DEBUGP("Edge %u %u->%u belongs to the 2-core\n", i, g->edges[i], g->edges[i + g->nedges]); - if(!(g->critical_nodes[g->edges[i]])) + if(!(GETBIT(g->critical_nodes,g->edges[i]))) { g->ncritical_nodes ++; - g->critical_nodes[g->edges[i]] = 1; + SETBIT(g->critical_nodes,g->edges[i]); } - if(!(g->critical_nodes[g->edges[i + g->nedges]])) + if(!(GETBIT(g->critical_nodes,g->edges[i + g->nedges]))) { g->ncritical_nodes ++; - g->critical_nodes[g->edges[i + g->nedges]] = 1; + SETBIT(g->critical_nodes,g->edges[i + g->nedges]); } } }