using less space to store the used_edges and critical_nodes arrays
This commit is contained in:
parent
03519cc9c8
commit
bda9c46618
26
src/bmz.c
26
src/bmz.c
|
@ -16,10 +16,16 @@
|
||||||
|
|
||||||
static uint32 UNDEFINED = UINT_MAX;
|
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 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_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);
|
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 *bmz_mph_new(key_source_t *key_source)
|
||||||
{
|
{
|
||||||
mph_t *mph = NULL;
|
mph_t *mph = NULL;
|
||||||
|
@ -70,7 +76,6 @@ mphf_t *bmz_mph_create(mph_t *mph, float bmz_c)
|
||||||
uint32 i;
|
uint32 i;
|
||||||
uint32 iterations = 10;
|
uint32 iterations = 10;
|
||||||
uint8 *used_edges = NULL;
|
uint8 *used_edges = NULL;
|
||||||
uint32 unused_edge_index = 0;
|
|
||||||
uint32 biggest_g_value = 0;
|
uint32 biggest_g_value = 0;
|
||||||
uint32 biggest_edge_value = 1;
|
uint32 biggest_edge_value = 1;
|
||||||
DEBUGP("bmz_c: %f\n", bmz_c);
|
DEBUGP("bmz_c: %f\n", bmz_c);
|
||||||
|
@ -131,12 +136,13 @@ mphf_t *bmz_mph_create(mph_t *mph, float bmz_c)
|
||||||
// Searching step
|
// Searching step
|
||||||
if (mph->verbosity)
|
if (mph->verbosity)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Starting Searching step\n");
|
fprintf(stderr, "Starting Searching step.\n");
|
||||||
fprintf(stderr, "\tTraversing critical vertices.\n");
|
fprintf(stderr, "\tTraversing critical vertices.\n");
|
||||||
}
|
}
|
||||||
DEBUGP("Searching step\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);
|
free(bmz->g);
|
||||||
bmz->g = malloc(bmz->n * sizeof(uint32));
|
bmz->g = malloc(bmz->n * sizeof(uint32));
|
||||||
assert(bmz->g);
|
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))
|
if (graph_node_is_critical(bmz->graph, lav) && (bmz->g[lav] != UNDEFINED))
|
||||||
{
|
{
|
||||||
assert(next_g + bmz->g[lav] < bmz->m);
|
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;
|
collision = 1;
|
||||||
break;
|
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))
|
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];
|
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)
|
while(1)
|
||||||
{
|
{
|
||||||
assert(unused_edge_index < bmz->m);
|
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;
|
else break;
|
||||||
}
|
}
|
||||||
return unused_edge_index;
|
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);
|
DEBUGP("Visiting neighbor %u\n", neighbor);
|
||||||
if(bmz->g[neighbor] != UNDEFINED) continue;
|
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];
|
bmz->g[neighbor] = *unused_edge_index - bmz->g[v];
|
||||||
|
(*unused_edge_index)++;
|
||||||
bmz_traverse(bmz, used_edges, neighbor, 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)
|
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");
|
DEBUGP("Labelling non critical vertices\n");
|
||||||
for(i = 0; i < bmz->m; i++)
|
for(i = 0; i < bmz->m; i++)
|
||||||
{
|
{
|
||||||
|
|
36
src/graph.c
36
src/graph.c
|
@ -10,6 +10,11 @@
|
||||||
//#define DEBUG
|
//#define DEBUG
|
||||||
#include "debug.h"
|
#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)
|
#define abs_edge(e, i) (e % g->nedges + i * g->nedges)
|
||||||
|
|
||||||
struct __graph_t
|
struct __graph_t
|
||||||
|
@ -172,7 +177,7 @@ static int find_degree1_edge(graph_t *g, uint32 v, char *deleted, uint32 *e)
|
||||||
char found = 0;
|
char found = 0;
|
||||||
DEBUGP("Checking degree of vertex %u\n", v);
|
DEBUGP("Checking degree of vertex %u\n", v);
|
||||||
if (edge == EMPTY) return 0;
|
if (edge == EMPTY) return 0;
|
||||||
else if (!deleted[abs_edge(edge, 0)])
|
else if (!(GETBIT(deleted, abs_edge(edge, 0))))
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
*e = edge;
|
*e = edge;
|
||||||
|
@ -181,7 +186,7 @@ static int find_degree1_edge(graph_t *g, uint32 v, char *deleted, uint32 *e)
|
||||||
{
|
{
|
||||||
edge = g->next[edge];
|
edge = g->next[edge];
|
||||||
if (edge == EMPTY) break;
|
if (edge == EMPTY) break;
|
||||||
if (deleted[abs_edge(edge, 0)]) continue;
|
if (GETBIT(deleted, abs_edge(edge, 0))) continue;
|
||||||
if (found) return 0;
|
if (found) return 0;
|
||||||
DEBUGP("Found first edge\n");
|
DEBUGP("Found first edge\n");
|
||||||
*e = edge;
|
*e = edge;
|
||||||
|
@ -203,7 +208,7 @@ static void cyclic_del_edge(graph_t *g, uint32 v, char *deleted)
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
DEBUGP("Deleting edge %u (%u->%u)\n", e, g->edges[abs_edge(e, 0)], g->edges[abs_edge(e, 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)];
|
v2 = g->edges[abs_edge(e, 0)];
|
||||||
if (v2 == v1) v2 = g->edges[abs_edge(e, 1)];
|
if (v2 == v1) v2 = g->edges[abs_edge(e, 1)];
|
||||||
|
@ -223,8 +228,8 @@ int graph_is_cyclic(graph_t *g)
|
||||||
{
|
{
|
||||||
uint32 i;
|
uint32 i;
|
||||||
uint32 v;
|
uint32 v;
|
||||||
char *deleted = (char *)malloc(g->nedges*sizeof(char));
|
char *deleted = (char *)malloc((g->nedges*sizeof(char))/8 + 1);
|
||||||
memset(deleted, 0, g->nedges);
|
memset(deleted, 0, g->nedges/8 + 1);
|
||||||
|
|
||||||
DEBUGP("Looking for cycles in graph with %u vertices and %u edges\n", g->nnodes, g->nedges);
|
DEBUGP("Looking for cycles in graph with %u vertices and %u edges\n", g->nnodes, g->nedges);
|
||||||
for (v = 0; v < g->nnodes; ++v)
|
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)
|
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]);
|
DEBUGP("Edge %u %u->%u was not deleted\n", i, g->edges[i], g->edges[i + g->nedges]);
|
||||||
free(deleted);
|
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 */
|
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*/
|
void graph_obtain_critical_nodes(graph_t *g) /* included -- Fabiano*/
|
||||||
{
|
{
|
||||||
uint32 i;
|
uint32 i;
|
||||||
uint32 v;
|
uint32 v;
|
||||||
char *deleted = (char *)malloc(g->nedges*sizeof(char));
|
char *deleted = (char *)malloc((g->nedges*sizeof(char))/8+1);
|
||||||
memset(deleted, 0, g->nedges);
|
memset(deleted, 0, g->nedges/8 + 1);
|
||||||
/* g->critical_nodes = (uint8 *)malloc((size_t)(ceil(g->nnodes*sizeof(uint8)/8.))); */
|
g->critical_nodes = (uint8 *)malloc((g->nnodes*sizeof(uint8))/8 + 1);
|
||||||
g->critical_nodes = (uint8 *)malloc(g->nnodes*sizeof(uint8));
|
|
||||||
g->ncritical_nodes = 0;
|
g->ncritical_nodes = 0;
|
||||||
DEBUGP("Looking for the 2-core in graph with %u vertices and %u edges\n", g->nnodes, g->nedges);
|
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)
|
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)
|
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]);
|
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->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->ncritical_nodes ++;
|
||||||
g->critical_nodes[g->edges[i + g->nedges]] = 1;
|
SETBIT(g->critical_nodes,g->edges[i + g->nedges]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue