From bda9c466182c5917c12405e834c5e3967a7692a9 Mon Sep 17 00:00:00 2001
From: fc_botelho <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]);
 			}
 		}
 	}