1
Fork 0

Only public symbols were prefixed with cmph, and the API was changed to agree with the initial txt2html documentation

This commit is contained in:
fc_botelho 2005-01-21 20:42:33 +00:00
parent a050a62857
commit d3788d43a8
28 changed files with 475 additions and 493 deletions

232
src/bmz.c
View File

@ -1,8 +1,10 @@
#include "graph.h"
#include "bmz.h" #include "bmz.h"
#include "cmph_structs.h" #include "cmph_structs.h"
#include "bmz_structs.h" #include "bmz_structs.h"
#include "hash.h" #include "hash.h"
#include "vqueue.h" #include "vqueue.h"
#include "bitbool.h"
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
@ -15,49 +17,39 @@
//static cmph_uint32 UNDEFINED = UINT_MAX; //static cmph_uint32 UNDEFINED = UINT_MAX;
static const char bitmask[8] = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 }; /* 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 GETBIT(array, i) (array[(i) / 8] & bitmask[(i) % 8]) */
#define SETBIT(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 UNSETBIT(array, i) (array[(i) / 8] &= (~(bitmask[(i) % 8]))) */
static int bmz_gen_edges(cmph_mph_t *mph); static int bmz_gen_edges(cmph_config_t *mph);
static cmph_uint8 bmz_traverse_critical_nodes(cmph_bmz_mph_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited); static cmph_uint8 bmz_traverse_critical_nodes(bmz_config_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited);
static cmph_uint8 bmz_traverse_critical_nodes_heuristic(cmph_bmz_mph_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited); static cmph_uint8 bmz_traverse_critical_nodes_heuristic(bmz_config_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited);
static void bmz_traverse_non_critical_nodes(cmph_bmz_mph_data_t *bmz, cmph_uint8 * used_edges, cmph_uint8 * visited); static void bmz_traverse_non_critical_nodes(bmz_config_data_t *bmz, cmph_uint8 * used_edges, cmph_uint8 * visited);
bmz_config_data_t *bmz_config_new(cmph_key_source_t *key_source)
cmph_mph_t *cmph_bmz_mph_new(cmph_key_source_t *key_source)
{ {
cmph_mph_t *mph = NULL; bmz_config_data_t *bmz = NULL;
cmph_bmz_mph_data_t *bmz = NULL; bmz = (bmz_config_data_t *)malloc(sizeof(bmz_config_data_t));
mph = cmph__mph_new(CMPH_BMZ, key_source);
if (mph == NULL) return NULL;
bmz = (cmph_bmz_mph_data_t *)malloc(sizeof(cmph_bmz_mph_data_t));
if (bmz == NULL)
{
cmph__mph_destroy(mph);
return NULL;
}
bmz->hashfuncs[0] = CMPH_HASH_JENKINS; bmz->hashfuncs[0] = CMPH_HASH_JENKINS;
bmz->hashfuncs[1] = CMPH_HASH_JENKINS; bmz->hashfuncs[1] = CMPH_HASH_JENKINS;
bmz->g = NULL; bmz->g = NULL;
bmz->graph = NULL; bmz->graph = NULL;
bmz->hashes = NULL; bmz->hashes = NULL;
mph->data = bmz; assert(bmz);
assert(mph->data); return bmz;
return mph;
}
void cmph_bmz_mph_destroy(cmph_mph_t *mph)
{
cmph_bmz_mph_data_t *data = (cmph_bmz_mph_data_t *)mph->data;
DEBUGP("Destroying algorithm dependent data\n");
free(data);
cmph__mph_destroy(mph);
} }
void cmph_bmz_mph_set_hashfuncs(cmph_mph_t *mph, CMPH_HASH *hashfuncs) void bmz_config_destroy(cmph_config_t *mph)
{ {
cmph_bmz_mph_data_t *bmz = (cmph_bmz_mph_data_t *)mph->data; bmz_config_data_t *data = (bmz_config_data_t *)mph->data;
DEBUGP("Destroying algorithm dependent data\n");
free(data);
}
void bmz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs)
{
bmz_config_data_t *bmz = (bmz_config_data_t *)mph->data;
CMPH_HASH *hashptr = hashfuncs; CMPH_HASH *hashptr = hashfuncs;
cmph_uint32 i = 0; cmph_uint32 i = 0;
while(*hashptr != CMPH_HASH_COUNT) while(*hashptr != CMPH_HASH_COUNT)
@ -68,10 +60,10 @@ void cmph_bmz_mph_set_hashfuncs(cmph_mph_t *mph, CMPH_HASH *hashfuncs)
} }
} }
cmph_mphf_t *cmph_bmz_mph_create(cmph_mph_t *mph, float bmz_c) cmph_t *bmz_new(cmph_config_t *mph, float c)
{ {
cmph_mphf_t *mphf = NULL; cmph_t *mphf = NULL;
cmph_bmz_mphf_data_t *bmzf = NULL; bmz_data_t *bmzf = NULL;
cmph_uint32 i; cmph_uint32 i;
cmph_uint32 iterations; cmph_uint32 iterations;
cmph_uint32 iterations_map = 20; cmph_uint32 iterations_map = 20;
@ -79,15 +71,15 @@ cmph_mphf_t *cmph_bmz_mph_create(cmph_mph_t *mph, float bmz_c)
cmph_uint8 restart_mapping = 0; cmph_uint8 restart_mapping = 0;
cmph_uint8 * visited = NULL; cmph_uint8 * visited = NULL;
DEBUGP("bmz_c: %f\n", bmz_c); DEBUGP("c: %f\n", c);
cmph_bmz_mph_data_t *bmz = (cmph_bmz_mph_data_t *)mph->data; bmz_config_data_t *bmz = (bmz_config_data_t *)mph->data;
bmz->m = mph->key_source->nkeys; bmz->m = mph->key_source->nkeys;
bmz->n = ceil(bmz_c * mph->key_source->nkeys); bmz->n = ceil(c * mph->key_source->nkeys);
DEBUGP("m (edges): %u n (vertices): %u bmz_c: %f\n", bmz->m, bmz->n, bmz_c); DEBUGP("m (edges): %u n (vertices): %u c: %f\n", bmz->m, bmz->n, c);
bmz->graph = cmph_graph_new(bmz->n, bmz->m); bmz->graph = graph_new(bmz->n, bmz->m);
DEBUGP("Created graph\n"); DEBUGP("Created graph\n");
bmz->hashes = (cmph_hash_state_t **)malloc(sizeof(cmph_hash_state_t *)*3); bmz->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*3);
for(i = 0; i < 3; ++i) bmz->hashes[i] = NULL; for(i = 0; i < 3; ++i) bmz->hashes[i] = NULL;
do do
@ -104,17 +96,17 @@ cmph_mphf_t *cmph_bmz_mph_create(cmph_mph_t *mph, float bmz_c)
{ {
int ok; int ok;
DEBUGP("hash function 1\n"); DEBUGP("hash function 1\n");
bmz->hashes[0] = cmph_hash_state_new(bmz->hashfuncs[0], bmz->n); bmz->hashes[0] = hash_state_new(bmz->hashfuncs[0], bmz->n);
DEBUGP("hash function 2\n"); DEBUGP("hash function 2\n");
bmz->hashes[1] = cmph_hash_state_new(bmz->hashfuncs[1], bmz->n); bmz->hashes[1] = hash_state_new(bmz->hashfuncs[1], bmz->n);
DEBUGP("Generating edges\n"); DEBUGP("Generating edges\n");
ok = bmz_gen_edges(mph); ok = bmz_gen_edges(mph);
if (!ok) if (!ok)
{ {
--iterations; --iterations;
cmph_hash_state_destroy(bmz->hashes[0]); hash_state_destroy(bmz->hashes[0]);
bmz->hashes[0] = NULL; bmz->hashes[0] = NULL;
cmph_hash_state_destroy(bmz->hashes[1]); hash_state_destroy(bmz->hashes[1]);
bmz->hashes[1] = NULL; bmz->hashes[1] = NULL;
DEBUGP("%u iterations remaining\n", iterations); DEBUGP("%u iterations remaining\n", iterations);
if (mph->verbosity) if (mph->verbosity)
@ -127,7 +119,7 @@ cmph_mphf_t *cmph_bmz_mph_create(cmph_mph_t *mph, float bmz_c)
} }
if (iterations == 0) if (iterations == 0)
{ {
cmph_graph_destroy(bmz->graph); graph_destroy(bmz->graph);
return NULL; return NULL;
} }
@ -137,7 +129,7 @@ cmph_mphf_t *cmph_bmz_mph_create(cmph_mph_t *mph, float bmz_c)
fprintf(stderr, "Starting ordering step\n"); fprintf(stderr, "Starting ordering step\n");
} }
cmph_graph_obtain_critical_nodes(bmz->graph); graph_obtain_critical_nodes(bmz->graph);
// Searching step // Searching step
if (mph->verbosity) if (mph->verbosity)
@ -155,9 +147,9 @@ cmph_mphf_t *cmph_bmz_mph_create(cmph_mph_t *mph, float bmz_c)
assert(bmz->g); assert(bmz->g);
for (i = 0; i < bmz->n; ++i) // critical nodes for (i = 0; i < bmz->n; ++i) // critical nodes
{ {
if (cmph_graph_node_is_critical(bmz->graph, i) && (!GETBIT(visited,i))) if (graph_node_is_critical(bmz->graph, i) && (!GETBIT(visited,i)))
{ {
if(bmz_c > 1.14) restart_mapping = bmz_traverse_critical_nodes(bmz, i, &biggest_g_value, &biggest_edge_value, used_edges, visited); if(c > 1.14) restart_mapping = bmz_traverse_critical_nodes(bmz, i, &biggest_g_value, &biggest_edge_value, used_edges, visited);
else restart_mapping = bmz_traverse_critical_nodes_heuristic(bmz, i, &biggest_g_value, &biggest_edge_value, used_edges, visited); else restart_mapping = bmz_traverse_critical_nodes_heuristic(bmz, i, &biggest_g_value, &biggest_edge_value, used_edges, visited);
if(restart_mapping) break; if(restart_mapping) break;
} }
@ -178,12 +170,12 @@ cmph_mphf_t *cmph_bmz_mph_create(cmph_mph_t *mph, float bmz_c)
free(used_edges); free(used_edges);
free(visited); free(visited);
}while(restart_mapping && iterations_map > 0); }while(restart_mapping && iterations_map > 0);
cmph_graph_destroy(bmz->graph); graph_destroy(bmz->graph);
bmz->graph = NULL; bmz->graph = NULL;
if (iterations_map == 0) return NULL; if (iterations_map == 0) return NULL;
mphf = (cmph_mphf_t *)malloc(sizeof(cmph_mphf_t)); mphf = (cmph_t *)malloc(sizeof(cmph_t));
mphf->algo = mph->algo; mphf->algo = mph->algo;
bmzf = (cmph_bmz_mphf_data_t *)malloc(sizeof(cmph_bmz_mph_data_t)); bmzf = (bmz_data_t *)malloc(sizeof(bmz_config_data_t));
bmzf->g = bmz->g; bmzf->g = bmz->g;
bmz->g = NULL; //transfer memory ownership bmz->g = NULL; //transfer memory ownership
bmzf->hashes = bmz->hashes; bmzf->hashes = bmz->hashes;
@ -200,41 +192,41 @@ cmph_mphf_t *cmph_bmz_mph_create(cmph_mph_t *mph, float bmz_c)
return mphf; return mphf;
} }
static cmph_uint8 bmz_traverse_critical_nodes(cmph_bmz_mph_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited) static cmph_uint8 bmz_traverse_critical_nodes(bmz_config_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited)
{ {
cmph_uint32 next_g; cmph_uint32 next_g;
cmph_uint32 u; /* Auxiliary vertex */ cmph_uint32 u; /* Auxiliary vertex */
cmph_uint32 lav; /* lookahead vertex */ cmph_uint32 lav; /* lookahead vertex */
cmph_uint8 collision; cmph_uint8 collision;
cmph_vqueue_t * q = cmph_vqueue_new((cmph_uint32)(0.5*cmph_graph_ncritical_nodes(bmz->graph)) + 1); vqueue_t * q = vqueue_new((cmph_uint32)(0.5*graph_ncritical_nodes(bmz->graph)) + 1);
cmph_graph_iterator_t it, it1; graph_iterator_t it, it1;
DEBUGP("Labelling critical vertices\n"); DEBUGP("Labelling critical vertices\n");
bmz->g[v] = (cmph_uint32)ceil ((double)(*biggest_edge_value)/2) - 1; bmz->g[v] = (cmph_uint32)ceil ((double)(*biggest_edge_value)/2) - 1;
SETBIT(visited, v); SETBIT(visited, v);
next_g = (cmph_uint32)floor((double)(*biggest_edge_value/2)); /* next_g is incremented in the do..while statement*/ next_g = (cmph_uint32)floor((double)(*biggest_edge_value/2)); /* next_g is incremented in the do..while statement*/
cmph_vqueue_insert(q, v); vqueue_insert(q, v);
while(!cmph_vqueue_is_empty(q)) while(!vqueue_is_empty(q))
{ {
v = cmph_vqueue_remove(q); v = vqueue_remove(q);
it = cmph_graph_neighbors_it(bmz->graph, v); it = graph_neighbors_it(bmz->graph, v);
while ((u = cmph_graph_next_neighbor(bmz->graph, &it)) != CMPH_GRAPH_NO_NEIGHBOR) while ((u = graph_next_neighbor(bmz->graph, &it)) != GRAPH_NO_NEIGHBOR)
{ {
if (cmph_graph_node_is_critical(bmz->graph, u) && (!GETBIT(visited,u))) if (graph_node_is_critical(bmz->graph, u) && (!GETBIT(visited,u)))
{ {
collision = 1; collision = 1;
while(collision) // lookahead to resolve collisions while(collision) // lookahead to resolve collisions
{ {
next_g = *biggest_g_value + 1; next_g = *biggest_g_value + 1;
it1 = cmph_graph_neighbors_it(bmz->graph, u); it1 = graph_neighbors_it(bmz->graph, u);
collision = 0; collision = 0;
while((lav = cmph_graph_next_neighbor(bmz->graph, &it1)) != CMPH_GRAPH_NO_NEIGHBOR) while((lav = graph_next_neighbor(bmz->graph, &it1)) != GRAPH_NO_NEIGHBOR)
{ {
if (cmph_graph_node_is_critical(bmz->graph, lav) && GETBIT(visited,lav)) if (graph_node_is_critical(bmz->graph, lav) && GETBIT(visited,lav))
{ {
if(next_g + bmz->g[lav] >= bmz->m) if(next_g + bmz->g[lav] >= bmz->m)
{ {
cmph_vqueue_destroy(q); vqueue_destroy(q);
return 1; // restart mapping step. return 1; // restart mapping step.
} }
if (GETBIT(used_edges, next_g + bmz->g[lav])) if (GETBIT(used_edges, next_g + bmz->g[lav]))
@ -247,10 +239,10 @@ static cmph_uint8 bmz_traverse_critical_nodes(cmph_bmz_mph_data_t *bmz, cmph_uin
if (next_g > *biggest_g_value) *biggest_g_value = next_g; if (next_g > *biggest_g_value) *biggest_g_value = next_g;
} }
// Marking used edges... // Marking used edges...
it1 = cmph_graph_neighbors_it(bmz->graph, u); it1 = graph_neighbors_it(bmz->graph, u);
while((lav = cmph_graph_next_neighbor(bmz->graph, &it1)) != CMPH_GRAPH_NO_NEIGHBOR) while((lav = graph_next_neighbor(bmz->graph, &it1)) != GRAPH_NO_NEIGHBOR)
{ {
if (cmph_graph_node_is_critical(bmz->graph, lav) && GETBIT(visited, lav)) if (graph_node_is_critical(bmz->graph, lav) && GETBIT(visited, lav))
{ {
SETBIT(used_edges,next_g + bmz->g[lav]); 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];
@ -258,16 +250,16 @@ static cmph_uint8 bmz_traverse_critical_nodes(cmph_bmz_mph_data_t *bmz, cmph_uin
} }
bmz->g[u] = next_g; // Labelling vertex u. bmz->g[u] = next_g; // Labelling vertex u.
SETBIT(visited,u); SETBIT(visited,u);
cmph_vqueue_insert(q, u); vqueue_insert(q, u);
} }
} }
} }
cmph_vqueue_destroy(q); vqueue_destroy(q);
return 0; return 0;
} }
static cmph_uint8 bmz_traverse_critical_nodes_heuristic(cmph_bmz_mph_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited) static cmph_uint8 bmz_traverse_critical_nodes_heuristic(bmz_config_data_t *bmz, cmph_uint32 v, cmph_uint32 * biggest_g_value, cmph_uint32 * biggest_edge_value, cmph_uint8 * used_edges, cmph_uint8 * visited)
{ {
cmph_uint32 next_g; cmph_uint32 next_g;
cmph_uint32 u; /* Auxiliary vertex */ cmph_uint32 u; /* Auxiliary vertex */
@ -276,21 +268,21 @@ static cmph_uint8 bmz_traverse_critical_nodes_heuristic(cmph_bmz_mph_data_t *bmz
cmph_uint32 * unused_g_values = NULL; cmph_uint32 * unused_g_values = NULL;
cmph_uint32 unused_g_values_capacity = 0; cmph_uint32 unused_g_values_capacity = 0;
cmph_uint32 nunused_g_values = 0; cmph_uint32 nunused_g_values = 0;
cmph_vqueue_t * q = cmph_vqueue_new((cmph_uint32)(0.5*cmph_graph_ncritical_nodes(bmz->graph))+1); vqueue_t * q = vqueue_new((cmph_uint32)(0.5*graph_ncritical_nodes(bmz->graph))+1);
cmph_graph_iterator_t it, it1; graph_iterator_t it, it1;
DEBUGP("Labelling critical vertices\n"); DEBUGP("Labelling critical vertices\n");
bmz->g[v] = (cmph_uint32)ceil ((double)(*biggest_edge_value)/2) - 1; bmz->g[v] = (cmph_uint32)ceil ((double)(*biggest_edge_value)/2) - 1;
SETBIT(visited, v); SETBIT(visited, v);
next_g = (cmph_uint32)floor((double)(*biggest_edge_value/2)); /* next_g is incremented in the do..while statement*/ next_g = (cmph_uint32)floor((double)(*biggest_edge_value/2)); /* next_g is incremented in the do..while statement*/
cmph_vqueue_insert(q, v); vqueue_insert(q, v);
while(!cmph_vqueue_is_empty(q)) while(!vqueue_is_empty(q))
{ {
v = cmph_vqueue_remove(q); v = vqueue_remove(q);
it = cmph_graph_neighbors_it(bmz->graph, v); it = graph_neighbors_it(bmz->graph, v);
while ((u = cmph_graph_next_neighbor(bmz->graph, &it)) != CMPH_GRAPH_NO_NEIGHBOR) while ((u = graph_next_neighbor(bmz->graph, &it)) != GRAPH_NO_NEIGHBOR)
{ {
if (cmph_graph_node_is_critical(bmz->graph, u) && (!GETBIT(visited,u))) if (graph_node_is_critical(bmz->graph, u) && (!GETBIT(visited,u)))
{ {
cmph_uint32 next_g_index = 0; cmph_uint32 next_g_index = 0;
collision = 1; collision = 1;
@ -305,15 +297,15 @@ static cmph_uint8 bmz_traverse_critical_nodes_heuristic(cmph_bmz_mph_data_t *bmz
next_g = *biggest_g_value + 1; next_g = *biggest_g_value + 1;
next_g_index = UINT_MAX; next_g_index = UINT_MAX;
} }
it1 = cmph_graph_neighbors_it(bmz->graph, u); it1 = graph_neighbors_it(bmz->graph, u);
collision = 0; collision = 0;
while((lav = cmph_graph_next_neighbor(bmz->graph, &it1)) != CMPH_GRAPH_NO_NEIGHBOR) while((lav = graph_next_neighbor(bmz->graph, &it1)) != GRAPH_NO_NEIGHBOR)
{ {
if (cmph_graph_node_is_critical(bmz->graph, lav) && GETBIT(visited,lav)) if (graph_node_is_critical(bmz->graph, lav) && GETBIT(visited,lav))
{ {
if(next_g + bmz->g[lav] >= bmz->m) if(next_g + bmz->g[lav] >= bmz->m)
{ {
cmph_vqueue_destroy(q); vqueue_destroy(q);
free(unused_g_values); free(unused_g_values);
return 1; // restart mapping step. return 1; // restart mapping step.
} }
@ -340,10 +332,10 @@ static cmph_uint8 bmz_traverse_critical_nodes_heuristic(cmph_bmz_mph_data_t *bmz
if (next_g_index < nunused_g_values) unused_g_values[next_g_index] = unused_g_values[--nunused_g_values]; if (next_g_index < nunused_g_values) unused_g_values[next_g_index] = unused_g_values[--nunused_g_values];
// Marking used edges... // Marking used edges...
it1 = cmph_graph_neighbors_it(bmz->graph, u); it1 = graph_neighbors_it(bmz->graph, u);
while((lav = cmph_graph_next_neighbor(bmz->graph, &it1)) != CMPH_GRAPH_NO_NEIGHBOR) while((lav = graph_next_neighbor(bmz->graph, &it1)) != GRAPH_NO_NEIGHBOR)
{ {
if (cmph_graph_node_is_critical(bmz->graph, lav) && GETBIT(visited, lav)) if (graph_node_is_critical(bmz->graph, lav) && GETBIT(visited, lav))
{ {
SETBIT(used_edges,next_g + bmz->g[lav]); 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];
@ -351,17 +343,17 @@ static cmph_uint8 bmz_traverse_critical_nodes_heuristic(cmph_bmz_mph_data_t *bmz
} }
bmz->g[u] = next_g; // Labelling vertex u. bmz->g[u] = next_g; // Labelling vertex u.
SETBIT(visited, u); SETBIT(visited, u);
cmph_vqueue_insert(q, u); vqueue_insert(q, u);
} }
} }
} }
cmph_vqueue_destroy(q); vqueue_destroy(q);
free(unused_g_values); free(unused_g_values);
return 0; return 0;
} }
static cmph_uint32 next_unused_edge(cmph_bmz_mph_data_t *bmz, cmph_uint8 * used_edges, cmph_uint32 unused_edge_index) static cmph_uint32 next_unused_edge(bmz_config_data_t *bmz, cmph_uint8 * used_edges, cmph_uint32 unused_edge_index)
{ {
while(1) while(1)
{ {
@ -372,11 +364,11 @@ static cmph_uint32 next_unused_edge(cmph_bmz_mph_data_t *bmz, cmph_uint8 * used_
return unused_edge_index; return unused_edge_index;
} }
static void bmz_traverse(cmph_bmz_mph_data_t *bmz, cmph_uint8 * used_edges, cmph_uint32 v, cmph_uint32 * unused_edge_index, cmph_uint8 * visited) static void bmz_traverse(bmz_config_data_t *bmz, cmph_uint8 * used_edges, cmph_uint32 v, cmph_uint32 * unused_edge_index, cmph_uint8 * visited)
{ {
cmph_graph_iterator_t it = cmph_graph_neighbors_it(bmz->graph, v); graph_iterator_t it = graph_neighbors_it(bmz->graph, v);
cmph_uint32 neighbor = 0; cmph_uint32 neighbor = 0;
while((neighbor = cmph_graph_next_neighbor(bmz->graph, &it)) != CMPH_GRAPH_NO_NEIGHBOR) while((neighbor = graph_next_neighbor(bmz->graph, &it)) != GRAPH_NO_NEIGHBOR)
{ {
if(GETBIT(visited,neighbor)) continue; if(GETBIT(visited,neighbor)) continue;
DEBUGP("Visiting neighbor %u\n", neighbor); DEBUGP("Visiting neighbor %u\n", neighbor);
@ -389,15 +381,15 @@ static void bmz_traverse(cmph_bmz_mph_data_t *bmz, cmph_uint8 * used_edges, cmph
} }
} }
static void bmz_traverse_non_critical_nodes(cmph_bmz_mph_data_t *bmz, cmph_uint8 * used_edges, cmph_uint8 * visited) static void bmz_traverse_non_critical_nodes(bmz_config_data_t *bmz, cmph_uint8 * used_edges, cmph_uint8 * visited)
{ {
cmph_uint32 i, v1, v2, unused_edge_index = 0; cmph_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++)
{ {
v1 = cmph_graph_vertex_id(bmz->graph, i, 0); v1 = graph_vertex_id(bmz->graph, i, 0);
v2 = cmph_graph_vertex_id(bmz->graph, i, 1); v2 = graph_vertex_id(bmz->graph, i, 1);
if((GETBIT(visited,v1) && GETBIT(visited,v2)) || (!GETBIT(visited,v1) && !GETBIT(visited,v2))) continue; if((GETBIT(visited,v1) && GETBIT(visited,v2)) || (!GETBIT(visited,v1) && !GETBIT(visited,v2))) continue;
if(GETBIT(visited,v1)) bmz_traverse(bmz, used_edges, v1, &unused_edge_index, visited); if(GETBIT(visited,v1)) bmz_traverse(bmz, used_edges, v1, &unused_edge_index, visited);
else bmz_traverse(bmz, used_edges, v2, &unused_edge_index, visited); else bmz_traverse(bmz, used_edges, v2, &unused_edge_index, visited);
@ -416,14 +408,14 @@ static void bmz_traverse_non_critical_nodes(cmph_bmz_mph_data_t *bmz, cmph_uint8
} }
static int bmz_gen_edges(cmph_mph_t *mph) static int bmz_gen_edges(cmph_config_t *mph)
{ {
cmph_uint32 e; cmph_uint32 e;
cmph_bmz_mph_data_t *bmz = (cmph_bmz_mph_data_t *)mph->data; bmz_config_data_t *bmz = (bmz_config_data_t *)mph->data;
cmph_uint8 multiple_edges = 0; cmph_uint8 multiple_edges = 0;
DEBUGP("Generating edges for %u vertices\n", bmz->n); DEBUGP("Generating edges for %u vertices\n", bmz->n);
cmph_graph_clear_edges(bmz->graph); graph_clear_edges(bmz->graph);
mph->key_source->rewind(mph->key_source->data); mph->key_source->rewind(mph->key_source->data);
for (e = 0; e < mph->key_source->nkeys; ++e) for (e = 0; e < mph->key_source->nkeys; ++e)
{ {
@ -431,8 +423,8 @@ static int bmz_gen_edges(cmph_mph_t *mph)
cmph_uint32 keylen; cmph_uint32 keylen;
char *key; char *key;
mph->key_source->read(mph->key_source->data, &key, &keylen); mph->key_source->read(mph->key_source->data, &key, &keylen);
h1 = cmph_hash(bmz->hashes[0], key, keylen) % bmz->n; h1 = hash(bmz->hashes[0], key, keylen) % bmz->n;
h2 = cmph_hash(bmz->hashes[1], key, keylen) % bmz->n; h2 = hash(bmz->hashes[1], key, keylen) % bmz->n;
if (h1 == h2) if (++h2 >= bmz->n) h2 = 0; if (h1 == h2) if (++h2 >= bmz->n) h2 = 0;
if (h1 == h2) if (h1 == h2)
{ {
@ -442,34 +434,34 @@ static int bmz_gen_edges(cmph_mph_t *mph)
} }
DEBUGP("Adding edge: %u -> %u for key %s\n", h1, h2, key); DEBUGP("Adding edge: %u -> %u for key %s\n", h1, h2, key);
mph->key_source->dispose(mph->key_source->data, key, keylen); mph->key_source->dispose(mph->key_source->data, key, keylen);
multiple_edges = cmph_graph_contains_edge(bmz->graph, h1, h2); multiple_edges = graph_contains_edge(bmz->graph, h1, h2);
if (mph->verbosity && multiple_edges) fprintf(stderr, "A non simple graph was generated\n"); if (mph->verbosity && multiple_edges) fprintf(stderr, "A non simple graph was generated\n");
if (multiple_edges) return 0; // checking multiple edge restriction. if (multiple_edges) return 0; // checking multiple edge restriction.
cmph_graph_add_edge(bmz->graph, h1, h2); graph_add_edge(bmz->graph, h1, h2);
} }
return !multiple_edges; return !multiple_edges;
} }
int cmph_bmz_mphf_dump(cmph_mphf_t *mphf, FILE *fd) int bmz_dump(cmph_t *mphf, FILE *fd)
{ {
char *buf = NULL; char *buf = NULL;
cmph_uint32 buflen; cmph_uint32 buflen;
cmph_uint32 nbuflen; cmph_uint32 nbuflen;
cmph_uint32 i; cmph_uint32 i;
cmph_uint32 two = 2; //number of hash functions cmph_uint32 two = 2; //number of hash functions
cmph_bmz_mphf_data_t *data = (cmph_bmz_mphf_data_t *)mphf->data; bmz_data_t *data = (bmz_data_t *)mphf->data;
cmph_uint32 nn, nm; cmph_uint32 nn, nm;
cmph__mphf_dump(mphf, fd); __cmph_dump(mphf, fd);
fwrite(&two, sizeof(cmph_uint32), 1, fd); fwrite(&two, sizeof(cmph_uint32), 1, fd);
cmph_hash_state_dump(data->hashes[0], &buf, &buflen); hash_state_dump(data->hashes[0], &buf, &buflen);
DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); DEBUGP("Dumping hash state with %u bytes to disk\n", buflen);
fwrite(&buflen, sizeof(cmph_uint32), 1, fd); fwrite(&buflen, sizeof(cmph_uint32), 1, fd);
fwrite(buf, buflen, 1, fd); fwrite(buf, buflen, 1, fd);
free(buf); free(buf);
cmph_hash_state_dump(data->hashes[1], &buf, &buflen); hash_state_dump(data->hashes[1], &buf, &buflen);
DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); DEBUGP("Dumping hash state with %u bytes to disk\n", buflen);
fwrite(&buflen, sizeof(cmph_uint32), 1, fd); fwrite(&buflen, sizeof(cmph_uint32), 1, fd);
fwrite(buf, buflen, 1, fd); fwrite(buf, buflen, 1, fd);
@ -487,28 +479,28 @@ int cmph_bmz_mphf_dump(cmph_mphf_t *mphf, FILE *fd)
return 1; return 1;
} }
void cmph_bmz_mphf_load(FILE *f, cmph_mphf_t *mphf) void bmz_load(FILE *f, cmph_t *mphf)
{ {
cmph_uint32 nhashes; cmph_uint32 nhashes;
char *buf = NULL; char *buf = NULL;
cmph_uint32 buflen; cmph_uint32 buflen;
cmph_uint32 i; cmph_uint32 i;
cmph_bmz_mphf_data_t *bmz = (cmph_bmz_mphf_data_t *)malloc(sizeof(cmph_bmz_mphf_data_t)); bmz_data_t *bmz = (bmz_data_t *)malloc(sizeof(bmz_data_t));
DEBUGP("Loading bmz mphf\n"); DEBUGP("Loading bmz mphf\n");
mphf->data = bmz; mphf->data = bmz;
fread(&nhashes, sizeof(cmph_uint32), 1, f); fread(&nhashes, sizeof(cmph_uint32), 1, f);
bmz->hashes = (cmph_hash_state_t **)malloc(sizeof(cmph_hash_state_t *)*(nhashes + 1)); bmz->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*(nhashes + 1));
bmz->hashes[nhashes] = NULL; bmz->hashes[nhashes] = NULL;
DEBUGP("Reading %u hashes\n", nhashes); DEBUGP("Reading %u hashes\n", nhashes);
for (i = 0; i < nhashes; ++i) for (i = 0; i < nhashes; ++i)
{ {
cmph_hash_state_t *state = NULL; hash_state_t *state = NULL;
fread(&buflen, sizeof(cmph_uint32), 1, f); fread(&buflen, sizeof(cmph_uint32), 1, f);
DEBUGP("Hash state has %u bytes\n", buflen); DEBUGP("Hash state has %u bytes\n", buflen);
buf = (char *)malloc(buflen); buf = (char *)malloc(buflen);
fread(buf, buflen, 1, f); fread(buf, buflen, 1, f);
state = cmph_hash_state_load(buf, buflen); state = hash_state_load(buf, buflen);
bmz->hashes[i] = state; bmz->hashes[i] = state;
free(buf); free(buf);
} }
@ -528,22 +520,22 @@ void cmph_bmz_mphf_load(FILE *f, cmph_mphf_t *mphf)
} }
cmph_uint32 cmph_bmz_mphf_search(cmph_mphf_t *mphf, const char *key, cmph_uint32 keylen) cmph_uint32 bmz_search(cmph_t *mphf, const char *key, cmph_uint32 keylen)
{ {
cmph_bmz_mphf_data_t *bmz = mphf->data; bmz_data_t *bmz = mphf->data;
cmph_uint32 h1 = cmph_hash(bmz->hashes[0], key, keylen) % bmz->n; cmph_uint32 h1 = hash(bmz->hashes[0], key, keylen) % bmz->n;
cmph_uint32 h2 = cmph_hash(bmz->hashes[1], key, keylen) % bmz->n; cmph_uint32 h2 = hash(bmz->hashes[1], key, keylen) % bmz->n;
DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2);
if (h1 == h2 && ++h2 > bmz->n) h2 = 0; if (h1 == h2 && ++h2 > bmz->n) h2 = 0;
DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, bmz->g[h1], bmz->g[h2], bmz->m); DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, bmz->g[h1], bmz->g[h2], bmz->m);
return bmz->g[h1] + bmz->g[h2]; return bmz->g[h1] + bmz->g[h2];
} }
void cmph_bmz_mphf_destroy(cmph_mphf_t *mphf) void bmz_destroy(cmph_t *mphf)
{ {
cmph_bmz_mphf_data_t *data = (cmph_bmz_mphf_data_t *)mphf->data; bmz_data_t *data = (bmz_data_t *)mphf->data;
free(data->g); free(data->g);
cmph_hash_state_destroy(data->hashes[0]); hash_state_destroy(data->hashes[0]);
cmph_hash_state_destroy(data->hashes[1]); hash_state_destroy(data->hashes[1]);
free(data->hashes); free(data->hashes);
free(data); free(data);
free(mphf); free(mphf);

View File

@ -1,19 +1,18 @@
#ifndef __BMZ_H__ #ifndef __CMPH_BMZ_H__
#define __BMZ_H__ #define __CMPH_BMZ_H__
#include "graph.h"
#include "cmph.h" #include "cmph.h"
typedef struct cmph__bmz_mphf_data_t cmph_bmz_mphf_data_t; typedef struct __bmz_data_t bmz_data_t;
typedef struct cmph__bmz_mph_data_t cmph_bmz_mph_data_t; typedef struct __bmz_config_data_t bmz_config_data_t;
cmph_mph_t *cmph_bmz_mph_new(cmph_key_source_t *key_source); bmz_config_data_t *bmz_config_new(cmph_key_source_t *key_source);
void cmph_bmz_mph_set_hashfuncs(cmph_mph_t *mph, CMPH_HASH *hashfuncs); void bmz_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs);
void cmph_bmz_mph_destroy(cmph_mph_t *mph); void bmz_config_destroy(cmph_config_t *mph);
cmph_mphf_t *cmph_bmz_mph_create(cmph_mph_t *mph, float bmz_c); cmph_t *bmz_new(cmph_config_t *mph, float c);
void cmph_bmz_mphf_load(FILE *f, cmph_mphf_t *mphf); void bmz_load(FILE *f, cmph_t *mphf);
int cmph_bmz_mphf_dump(cmph_mphf_t *mphf, FILE *f); int bmz_dump(cmph_t *mphf, FILE *f);
void cmph_bmz_mphf_destroy(cmph_mphf_t *mphf); void bmz_destroy(cmph_t *mphf);
cmph_uint32 cmph_bmz_mphf_search(cmph_mphf_t *mphf, const char *key, cmph_uint32 keylen); cmph_uint32 bmz_search(cmph_t *mphf, const char *key, cmph_uint32 keylen);
#endif #endif

View File

@ -1,24 +1,24 @@
#ifndef __BMZ_STRUCTS_H__ #ifndef __CMPH_BMZ_STRUCTS_H__
#define __BMZ_STRUCTS_H__ #define __CMPH_BMZ_STRUCTS_H__
#include "hash_state.h" #include "hash_state.h"
struct cmph__bmz_mphf_data_t struct __bmz_data_t
{ {
cmph_uint32 m; //edges (words) count cmph_uint32 m; //edges (words) count
cmph_uint32 n; //vertex count cmph_uint32 n; //vertex count
cmph_uint32 *g; cmph_uint32 *g;
cmph_hash_state_t **hashes; hash_state_t **hashes;
}; };
struct cmph__bmz_mph_data_t struct __bmz_config_data_t
{ {
CMPH_HASH hashfuncs[2]; CMPH_HASH hashfuncs[2];
cmph_uint32 m; //edges (words) count cmph_uint32 m; //edges (words) count
cmph_uint32 n; //vertex count cmph_uint32 n; //vertex count
cmph_graph_t *graph; graph_t *graph;
cmph_uint32 *g; cmph_uint32 *g;
cmph_hash_state_t **hashes; hash_state_t **hashes;
}; };
#endif #endif

View File

@ -10,85 +10,84 @@
//#define DEBUG //#define DEBUG
#include "debug.h" #include "debug.h"
const char *cmph_names[] = { "czech", "bmz", NULL }; /* included -- Fabiano */ const char *cmph_names[] = { "bmz", "czech", NULL }; /* included -- Fabiano */
cmph_mph_t *cmph_mph_new(CMPH_ALGO algo, cmph_key_source_t *key_source) cmph_config_t *cmph_config_new(cmph_key_source_t *key_source)
{ {
cmph_mph_t *mph = NULL; cmph_config_t *mph = NULL;
DEBUGP("Creating mph with algorithm %s\n", cmph_names[algo]); mph = __config_new(key_source);
switch (algo)
{
case CMPH_CZECH:
mph = cmph_czech_mph_new(key_source);
break;
case CMPH_BMZ: /* included -- Fabiano */
DEBUGP("new bmz algorithm \n");
mph = cmph_bmz_mph_new(key_source);
break;
default:
assert(0);
}
assert(mph); assert(mph);
mph->algo = CMPH_CZECH; // default value
return mph; return mph;
} }
void cmph_mph_destroy(cmph_mph_t *mph) void cmph_config_set_algo(cmph_config_t *mph, CMPH_ALGO algo)
{
mph->algo = algo;
}
void cmph_config_destroy(cmph_config_t *mph)
{ {
DEBUGP("Destroying mph with algo %s\n", cmph_names[mph->algo]); DEBUGP("Destroying mph with algo %s\n", cmph_names[mph->algo]);
switch (mph->algo) switch (mph->algo)
{ {
case CMPH_CZECH: case CMPH_CZECH:
cmph_czech_mph_destroy(mph); czech_config_destroy(mph);
break; break;
case CMPH_BMZ: /* included -- Fabiano */ case CMPH_BMZ: /* included -- Fabiano */
cmph_bmz_mph_destroy(mph); bmz_config_destroy(mph);
break; break;
default: default:
assert(0); assert(0);
} }
__config_destroy(mph);
} }
void cmph_mph_set_verbosity(cmph_mph_t *mph, cmph_uint32 verbosity) void cmph_config_set_verbosity(cmph_config_t *mph, cmph_uint32 verbosity)
{ {
mph->verbosity = verbosity; mph->verbosity = verbosity;
} }
void cmph_mph_set_hashfuncs(cmph_mph_t *mph, CMPH_HASH *hashfuncs) void cmph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs)
{ {
switch (mph->algo) switch (mph->algo)
{ {
case CMPH_CZECH: case CMPH_CZECH:
cmph_czech_mph_set_hashfuncs(mph, hashfuncs); czech_config_set_hashfuncs(mph, hashfuncs);
break; break;
case CMPH_BMZ: /* included -- Fabiano */ case CMPH_BMZ: /* included -- Fabiano */
cmph_bmz_mph_set_hashfuncs(mph, hashfuncs); bmz_config_set_hashfuncs(mph, hashfuncs);
break; break;
default: default:
break; break;
} }
return; return;
} }
void cmph_mph_set_graphsize(cmph_mph_t *mph, float c) void cmph_config_set_graphsize(cmph_config_t *mph, float c)
{ {
mph->c = c; mph->c = c;
return; return;
} }
cmph_mphf_t *cmph_mph_create(cmph_mph_t *mph) cmph_t *cmph_new(cmph_config_t *mph)
{ {
cmph_mphf_t *mphf = NULL; cmph_t *mphf = NULL;
float c = mph->c; float c = mph->c;
DEBUGP("Creating mph with algorithm %s\n", cmph_names[mph->algo]);
switch (mph->algo) switch (mph->algo)
{ {
case CMPH_CZECH: case CMPH_CZECH:
DEBUGP("Creating czech hash\n"); DEBUGP("Creating czech hash\n");
mph->data = czech_config_new(mph->key_source);
if (c == 0) c = 2.09; if (c == 0) c = 2.09;
mphf = cmph_czech_mph_create(mph, c); mphf = czech_new(mph, c);
break; break;
case CMPH_BMZ: /* included -- Fabiano */ case CMPH_BMZ: /* included -- Fabiano */
DEBUGP("Creating bmz hash\n"); DEBUGP("Creating bmz hash\n");
mph->data = bmz_config_new(mph->key_source);
if (c == 0) c = 1.15; if (c == 0) c = 1.15;
mphf = cmph_bmz_mph_create(mph, c); mphf = bmz_new(mph, c);
break; break;
default: default:
assert(0); assert(0);
@ -96,15 +95,15 @@ cmph_mphf_t *cmph_mph_create(cmph_mph_t *mph)
return mphf; return mphf;
} }
int cmph_mphf_dump(cmph_mphf_t *mphf, FILE *f) int cmph_dump(cmph_t *mphf, FILE *f)
{ {
switch (mphf->algo) switch (mphf->algo)
{ {
case CMPH_CZECH: case CMPH_CZECH:
return cmph_czech_mphf_dump(mphf, f); return czech_dump(mphf, f);
break; break;
case CMPH_BMZ: /* included -- Fabiano */ case CMPH_BMZ: /* included -- Fabiano */
return cmph_bmz_mphf_dump(mphf, f); return bmz_dump(mphf, f);
break; break;
default: default:
assert(0); assert(0);
@ -112,22 +111,22 @@ int cmph_mphf_dump(cmph_mphf_t *mphf, FILE *f)
assert(0); assert(0);
return 0; return 0;
} }
cmph_mphf_t *cmph_mphf_load(FILE *f) cmph_t *cmph_load(FILE *f)
{ {
cmph_mphf_t *mphf = NULL; cmph_t *mphf = NULL;
DEBUGP("Loading mphf generic parts\n"); DEBUGP("Loading mphf generic parts\n");
mphf = cmph__mphf_load(f); mphf = __cmph_load(f);
if (mphf == NULL) return NULL; if (mphf == NULL) return NULL;
DEBUGP("Loading mphf algorithm dependent parts\n"); DEBUGP("Loading mphf algorithm dependent parts\n");
switch (mphf->algo) switch (mphf->algo)
{ {
case CMPH_CZECH: case CMPH_CZECH:
cmph_czech_mphf_load(f, mphf); czech_load(f, mphf);
break; break;
case CMPH_BMZ: /* included -- Fabiano */ case CMPH_BMZ: /* included -- Fabiano */
DEBUGP("Loading bmz algorithm dependent parts\n"); DEBUGP("Loading bmz algorithm dependent parts\n");
cmph_bmz_mphf_load(f, mphf); bmz_load(f, mphf);
break; break;
default: default:
assert(0); assert(0);
@ -137,16 +136,16 @@ cmph_mphf_t *cmph_mphf_load(FILE *f)
} }
cmph_uint32 cmph_mphf_search(cmph_mphf_t *mphf, const char *key, cmph_uint32 keylen) cmph_uint32 cmph_search(cmph_t *mphf, const char *key, cmph_uint32 keylen)
{ {
DEBUGP("mphf algorithm: %u \n", mphf->algo); DEBUGP("mphf algorithm: %u \n", mphf->algo);
switch(mphf->algo) switch(mphf->algo)
{ {
case CMPH_CZECH: case CMPH_CZECH:
return cmph_czech_mphf_search(mphf, key, keylen); return czech_search(mphf, key, keylen);
case CMPH_BMZ: /* included -- Fabiano */ case CMPH_BMZ: /* included -- Fabiano */
DEBUGP("bmz algorithm search\n"); DEBUGP("bmz algorithm search\n");
return cmph_bmz_mphf_search(mphf, key, keylen); return bmz_search(mphf, key, keylen);
default: default:
assert(0); assert(0);
} }
@ -154,20 +153,20 @@ cmph_uint32 cmph_mphf_search(cmph_mphf_t *mphf, const char *key, cmph_uint32 key
return 0; return 0;
} }
cmph_uint32 cmph_mphf_size(cmph_mphf_t *mphf) cmph_uint32 cmph_size(cmph_t *mphf)
{ {
return mphf->size; return mphf->size;
} }
void cmph_mphf_destroy(cmph_mphf_t *mphf) void cmph_destroy(cmph_t *mphf)
{ {
switch(mphf->algo) switch(mphf->algo)
{ {
case CMPH_CZECH: case CMPH_CZECH:
cmph_czech_mphf_destroy(mphf); czech_destroy(mphf);
return; return;
case CMPH_BMZ: /* included -- Fabiano */ case CMPH_BMZ: /* included -- Fabiano */
cmph_bmz_mphf_destroy(mphf); bmz_destroy(mphf);
return; return;
default: default:
assert(0); assert(0);

View File

@ -11,8 +11,8 @@ extern "C"
#include "cmph_types.h" #include "cmph_types.h"
typedef struct cmph__mph_t cmph_mph_t; typedef struct __config_t cmph_config_t;
typedef struct cmph__mphf_t cmph_mphf_t; typedef struct __cmph_t cmph_t;
typedef struct typedef struct
{ {
@ -24,19 +24,20 @@ typedef struct
} cmph_key_source_t; } cmph_key_source_t;
/** Hash generation API **/ /** Hash generation API **/
cmph_mph_t *cmph_mph_new(CMPH_ALGO algo, cmph_key_source_t *key_source); cmph_config_t *cmph_config_new(cmph_key_source_t *key_source);
void cmph_mph_set_hashfuncs(cmph_mph_t *mph, CMPH_HASH *hashfuncs); void cmph_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs);
void cmph_mph_set_verbosity(cmph_mph_t *mph, cmph_uint32 verbosity); void cmph_config_set_verbosity(cmph_config_t *mph, cmph_uint32 verbosity);
void cmph_mph_set_graphsize(cmph_mph_t *mph, float c); void cmph_config_set_graphsize(cmph_config_t *mph, float c);
void cmph_mph_destroy(cmph_mph_t *mph); void cmph_config_set_algo(cmph_config_t *mph, CMPH_ALGO algo);
cmph_mphf_t *cmph_mph_create(cmph_mph_t *mph); void cmph_config_destroy(cmph_config_t *mph);
cmph_t *cmph_new(cmph_config_t *mph);
/** Hash querying API **/ /** Hash querying API **/
cmph_mphf_t *cmph_mphf_load(FILE *f); cmph_t *cmph_load(FILE *f);
int cmph_mphf_dump(cmph_mphf_t *mphf, FILE *f); int cmph_dump(cmph_t *mphf, FILE *f);
cmph_uint32 cmph_mphf_search(cmph_mphf_t *mphf, const char *key, cmph_uint32 keylen); cmph_uint32 cmph_search(cmph_t *mphf, const char *key, cmph_uint32 keylen);
cmph_uint32 cmph_mphf_size(cmph_mphf_t *mphf); cmph_uint32 cmph_size(cmph_t *mphf);
void cmph_mphf_destroy(cmph_mphf_t *mphf); void cmph_destroy(cmph_t *mphf);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -5,32 +5,31 @@
//#define DEBUG //#define DEBUG
#include "debug.h" #include "debug.h"
cmph_mph_t *cmph__mph_new(CMPH_ALGO algo, cmph_key_source_t *key_source) cmph_config_t *__config_new(cmph_key_source_t *key_source)
{ {
cmph_mph_t *mph = (cmph_mph_t *)malloc(sizeof(cmph_mph_t)); cmph_config_t *mph = (cmph_config_t *)malloc(sizeof(cmph_config_t));
DEBUGP("Creating mph with algorithm %s\n", cmph_names[algo]); DEBUGP("Creating mph with algorithm %s\n", cmph_names[algo]);
if (mph == NULL) return NULL; if (mph == NULL) return NULL;
mph->algo = algo;
mph->key_source = key_source; mph->key_source = key_source;
mph->verbosity = 0; mph->verbosity = 0;
float c = 0; float c = 0;
return mph; return mph;
} }
void cmph__mph_destroy(cmph_mph_t *mph) void __config_destroy(cmph_config_t *mph)
{ {
free(mph); free(mph);
} }
void cmph__mphf_dump(cmph_mphf_t *mphf, FILE *fd) void __cmph_dump(cmph_t *mphf, FILE *fd)
{ {
cmph_uint32 nsize = htonl(mphf->size); cmph_uint32 nsize = htonl(mphf->size);
fwrite(cmph_names[mphf->algo], (cmph_uint32)(strlen(cmph_names[mphf->algo]) + 1), 1, fd); fwrite(cmph_names[mphf->algo], (cmph_uint32)(strlen(cmph_names[mphf->algo]) + 1), 1, fd);
fwrite(&nsize, sizeof(mphf->size), 1, fd); fwrite(&nsize, sizeof(mphf->size), 1, fd);
} }
cmph_mphf_t *cmph__mphf_load(FILE *f) cmph_t *__cmph_load(FILE *f)
{ {
cmph_mphf_t *mphf = NULL; cmph_t *mphf = NULL;
cmph_uint32 i; cmph_uint32 i;
char algo_name[BUFSIZ]; char algo_name[BUFSIZ];
char *ptr = algo_name; char *ptr = algo_name;
@ -56,7 +55,7 @@ cmph_mphf_t *cmph__mphf_load(FILE *f)
DEBUGP("Algorithm %s not found\n", algo_name); DEBUGP("Algorithm %s not found\n", algo_name);
return NULL; return NULL;
} }
mphf = (cmph_mphf_t *)malloc(sizeof(cmph_mphf_t)); mphf = (cmph_t *)malloc(sizeof(cmph_t));
mphf->algo = algo; mphf->algo = algo;
fread(&(mphf->size), sizeof(mphf->size), 1, f); fread(&(mphf->size), sizeof(mphf->size), 1, f);
mphf->size = ntohl(mphf->size); mphf->size = ntohl(mphf->size);

View File

@ -5,7 +5,7 @@
/** Hash generation algorithm data /** Hash generation algorithm data
*/ */
struct cmph__mph_t struct __config_t
{ {
CMPH_ALGO algo; CMPH_ALGO algo;
cmph_key_source_t *key_source; cmph_key_source_t *key_source;
@ -16,7 +16,7 @@ struct cmph__mph_t
/** Hash querying algorithm data /** Hash querying algorithm data
*/ */
struct cmph__mphf_t struct __cmph_t
{ {
CMPH_ALGO algo; CMPH_ALGO algo;
cmph_uint32 size; cmph_uint32 size;
@ -24,10 +24,10 @@ struct cmph__mphf_t
void *data; //algorithm dependent data void *data; //algorithm dependent data
}; };
cmph_mph_t *cmph__mph_new(CMPH_ALGO algo, cmph_key_source_t *key_source); cmph_config_t *__config_new(cmph_key_source_t *key_source);
void cmph__mph_destroy(); void __config_destroy();
void cmph__mphf_dump(cmph_mphf_t *mphf, FILE *); void __cmph_dump(cmph_t *mphf, FILE *);
cmph_mphf_t *cmph__mphf_load(FILE *f); cmph_t *__cmph_load(FILE *f);
#endif #endif

View File

@ -1,7 +1,9 @@
#include "graph.h"
#include "czech.h" #include "czech.h"
#include "cmph_structs.h" #include "cmph_structs.h"
#include "czech_structs.h" #include "czech_structs.h"
#include "hash.h" #include "hash.h"
#include "bitbool.h"
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
@ -13,46 +15,36 @@
//#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 }; /* 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 GETBIT(array, i) (array[(i) / 8] & bitmask[(i) % 8]) */
#define SETBIT(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 UNSETBIT(array, i) (array[(i) / 8] &= (~(bitmask[(i) % 8]))) */
static int czech_gen_edges(cmph_mph_t *mph); static int czech_gen_edges(cmph_config_t *mph);
static void czech_traverse(cmph_czech_mph_data_t *czech, cmph_uint8 *visited, cmph_uint32 v); static void czech_traverse(czech_config_data_t *czech, cmph_uint8 *visited, cmph_uint32 v);
cmph_mph_t *cmph_czech_mph_new(cmph_key_source_t *key_source) czech_config_data_t *czech_config_new(cmph_key_source_t *key_source)
{ {
cmph_mph_t *mph = NULL; czech_config_data_t *czech = NULL;
cmph_czech_mph_data_t *czech = NULL; czech = (czech_config_data_t *)malloc(sizeof(czech_config_data_t));
mph = cmph__mph_new(CMPH_CZECH, key_source);
if (mph == NULL) return NULL;
czech = (cmph_czech_mph_data_t *)malloc(sizeof(cmph_czech_mph_data_t));
if (czech == NULL)
{
cmph__mph_destroy(mph);
return NULL;
}
czech->hashfuncs[0] = CMPH_HASH_JENKINS; czech->hashfuncs[0] = CMPH_HASH_JENKINS;
czech->hashfuncs[1] = CMPH_HASH_JENKINS; czech->hashfuncs[1] = CMPH_HASH_JENKINS;
czech->g = NULL; czech->g = NULL;
czech->graph = NULL; czech->graph = NULL;
czech->hashes = NULL; czech->hashes = NULL;
mph->data = czech; assert(czech);
assert(mph->data); return czech;
return mph;
} }
void cmph_czech_mph_destroy(cmph_mph_t *mph) void czech_config_destroy(cmph_config_t *mph)
{ {
cmph_czech_mph_data_t *data = (cmph_czech_mph_data_t *)mph->data; czech_config_data_t *data = (czech_config_data_t *)mph->data;
DEBUGP("Destroying algorithm dependent data\n"); DEBUGP("Destroying algorithm dependent data\n");
free(data); free(data);
cmph__mph_destroy(mph);
} }
void cmph_czech_mph_set_hashfuncs(cmph_mph_t *mph, CMPH_HASH *hashfuncs) void czech_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs)
{ {
cmph_czech_mph_data_t *czech = (cmph_czech_mph_data_t *)mph->data; czech_config_data_t *czech = (czech_config_data_t *)mph->data;
CMPH_HASH *hashptr = hashfuncs; CMPH_HASH *hashptr = hashfuncs;
cmph_uint32 i = 0; cmph_uint32 i = 0;
while(*hashptr != CMPH_HASH_COUNT) while(*hashptr != CMPH_HASH_COUNT)
@ -63,22 +55,22 @@ void cmph_czech_mph_set_hashfuncs(cmph_mph_t *mph, CMPH_HASH *hashfuncs)
} }
} }
cmph_mphf_t *cmph_czech_mph_create(cmph_mph_t *mph, float c) cmph_t *czech_new(cmph_config_t *mph, float c)
{ {
cmph_mphf_t *mphf = NULL; cmph_t *mphf = NULL;
cmph_czech_mphf_data_t *czechf = NULL; czech_data_t *czechf = NULL;
cmph_uint32 i; cmph_uint32 i;
cmph_uint32 iterations = 20; cmph_uint32 iterations = 20;
cmph_uint8 *visited = NULL; cmph_uint8 *visited = NULL;
cmph_czech_mph_data_t *czech = (cmph_czech_mph_data_t *)mph->data; czech_config_data_t *czech = (czech_config_data_t *)mph->data;
czech->m = mph->key_source->nkeys; czech->m = mph->key_source->nkeys;
czech->n = ceil(c * mph->key_source->nkeys); czech->n = ceil(c * mph->key_source->nkeys);
DEBUGP("m (edges): %u n (vertices): %u c: %f\n", czech->m, czech->n, c); DEBUGP("m (edges): %u n (vertices): %u c: %f\n", czech->m, czech->n, c);
czech->graph = cmph_graph_new(czech->n, czech->m); czech->graph = graph_new(czech->n, czech->m);
DEBUGP("Created graph\n"); DEBUGP("Created graph\n");
czech->hashes = (cmph_hash_state_t **)malloc(sizeof(cmph_hash_state_t *)*3); czech->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*3);
for(i = 0; i < 3; ++i) czech->hashes[i] = NULL; for(i = 0; i < 3; ++i) czech->hashes[i] = NULL;
//Mapping step //Mapping step
if (mph->verbosity) if (mph->verbosity)
@ -88,15 +80,15 @@ cmph_mphf_t *cmph_czech_mph_create(cmph_mph_t *mph, float c)
while(1) while(1)
{ {
int ok; int ok;
czech->hashes[0] = cmph_hash_state_new(czech->hashfuncs[0], czech->n); czech->hashes[0] = hash_state_new(czech->hashfuncs[0], czech->n);
czech->hashes[1] = cmph_hash_state_new(czech->hashfuncs[1], czech->n); czech->hashes[1] = hash_state_new(czech->hashfuncs[1], czech->n);
ok = czech_gen_edges(mph); ok = czech_gen_edges(mph);
if (!ok) if (!ok)
{ {
--iterations; --iterations;
cmph_hash_state_destroy(czech->hashes[0]); hash_state_destroy(czech->hashes[0]);
czech->hashes[0] = NULL; czech->hashes[0] = NULL;
cmph_hash_state_destroy(czech->hashes[1]); hash_state_destroy(czech->hashes[1]);
czech->hashes[1] = NULL; czech->hashes[1] = NULL;
DEBUGP("%u iterations remaining\n", iterations); DEBUGP("%u iterations remaining\n", iterations);
if (mph->verbosity) if (mph->verbosity)
@ -109,7 +101,7 @@ cmph_mphf_t *cmph_czech_mph_create(cmph_mph_t *mph, float c)
} }
if (iterations == 0) if (iterations == 0)
{ {
cmph_graph_destroy(czech->graph); graph_destroy(czech->graph);
return NULL; return NULL;
} }
@ -132,13 +124,13 @@ cmph_mphf_t *cmph_czech_mph_create(cmph_mph_t *mph, float c)
czech_traverse(czech, visited, i); czech_traverse(czech, visited, i);
} }
} }
cmph_graph_destroy(czech->graph); graph_destroy(czech->graph);
free(visited); free(visited);
czech->graph = NULL; czech->graph = NULL;
mphf = (cmph_mphf_t *)malloc(sizeof(cmph_mphf_t)); mphf = (cmph_t *)malloc(sizeof(cmph_t));
mphf->algo = mph->algo; mphf->algo = mph->algo;
czechf = (cmph_czech_mphf_data_t *)malloc(sizeof(cmph_czech_mph_data_t)); czechf = (czech_data_t *)malloc(sizeof(czech_config_data_t));
czechf->g = czech->g; czechf->g = czech->g;
czech->g = NULL; //transfer memory ownership czech->g = NULL; //transfer memory ownership
czechf->hashes = czech->hashes; czechf->hashes = czech->hashes;
@ -155,34 +147,34 @@ cmph_mphf_t *cmph_czech_mph_create(cmph_mph_t *mph, float c)
return mphf; return mphf;
} }
static void czech_traverse(cmph_czech_mph_data_t *czech, cmph_uint8 *visited, cmph_uint32 v) static void czech_traverse(czech_config_data_t *czech, cmph_uint8 *visited, cmph_uint32 v)
{ {
cmph_graph_iterator_t it = cmph_graph_neighbors_it(czech->graph, v); graph_iterator_t it = graph_neighbors_it(czech->graph, v);
cmph_uint32 neighbor = 0; cmph_uint32 neighbor = 0;
SETBIT(visited,v); SETBIT(visited,v);
DEBUGP("Visiting vertex %u\n", v); DEBUGP("Visiting vertex %u\n", v);
while((neighbor = cmph_graph_next_neighbor(czech->graph, &it)) != CMPH_GRAPH_NO_NEIGHBOR) while((neighbor = graph_next_neighbor(czech->graph, &it)) != GRAPH_NO_NEIGHBOR)
{ {
DEBUGP("Visiting neighbor %u\n", neighbor); DEBUGP("Visiting neighbor %u\n", neighbor);
if(GETBIT(visited,neighbor)) continue; if(GETBIT(visited,neighbor)) continue;
DEBUGP("Visiting neighbor %u\n", neighbor); DEBUGP("Visiting neighbor %u\n", neighbor);
DEBUGP("Visiting edge %u->%u with id %u\n", v, neighbor, cmph_graph_edge_id(czech->graph, v, neighbor)); DEBUGP("Visiting edge %u->%u with id %u\n", v, neighbor, graph_edge_id(czech->graph, v, neighbor));
czech->g[neighbor] = cmph_graph_edge_id(czech->graph, v, neighbor) - czech->g[v]; czech->g[neighbor] = graph_edge_id(czech->graph, v, neighbor) - czech->g[v];
DEBUGP("g is %u (%u - %u mod %u)\n", czech->g[neighbor], cmph_graph_edge_id(czech->graph, v, neighbor), czech->g[v], czech->m); DEBUGP("g is %u (%u - %u mod %u)\n", czech->g[neighbor], graph_edge_id(czech->graph, v, neighbor), czech->g[v], czech->m);
czech_traverse(czech, visited, neighbor); czech_traverse(czech, visited, neighbor);
} }
} }
static int czech_gen_edges(cmph_mph_t *mph) static int czech_gen_edges(cmph_config_t *mph)
{ {
cmph_uint32 e; cmph_uint32 e;
cmph_czech_mph_data_t *czech = (cmph_czech_mph_data_t *)mph->data; czech_config_data_t *czech = (czech_config_data_t *)mph->data;
int cycles = 0; int cycles = 0;
DEBUGP("Generating edges for %u vertices\n", czech->n); DEBUGP("Generating edges for %u vertices\n", czech->n);
cmph_graph_clear_edges(czech->graph); graph_clear_edges(czech->graph);
mph->key_source->rewind(mph->key_source->data); mph->key_source->rewind(mph->key_source->data);
for (e = 0; e < mph->key_source->nkeys; ++e) for (e = 0; e < mph->key_source->nkeys; ++e)
{ {
@ -190,8 +182,8 @@ static int czech_gen_edges(cmph_mph_t *mph)
cmph_uint32 keylen; cmph_uint32 keylen;
char *key; char *key;
mph->key_source->read(mph->key_source->data, &key, &keylen); mph->key_source->read(mph->key_source->data, &key, &keylen);
h1 = cmph_hash(czech->hashes[0], key, keylen) % czech->n; h1 = hash(czech->hashes[0], key, keylen) % czech->n;
h2 = cmph_hash(czech->hashes[1], key, keylen) % czech->n; h2 = hash(czech->hashes[1], key, keylen) % czech->n;
if (h1 == h2) if (++h2 >= czech->n) h2 = 0; if (h1 == h2) if (++h2 >= czech->n) h2 = 0;
if (h1 == h2) if (h1 == h2)
{ {
@ -201,36 +193,36 @@ static int czech_gen_edges(cmph_mph_t *mph)
} }
DEBUGP("Adding edge: %u -> %u for key %s\n", h1, h2, key); DEBUGP("Adding edge: %u -> %u for key %s\n", h1, h2, key);
mph->key_source->dispose(mph->key_source->data, key, keylen); mph->key_source->dispose(mph->key_source->data, key, keylen);
cmph_graph_add_edge(czech->graph, h1, h2); graph_add_edge(czech->graph, h1, h2);
} }
cycles = cmph_graph_is_cyclic(czech->graph); cycles = graph_is_cyclic(czech->graph);
if (mph->verbosity && cycles) fprintf(stderr, "Cyclic graph generated\n"); if (mph->verbosity && cycles) fprintf(stderr, "Cyclic graph generated\n");
DEBUGP("Looking for cycles: %u\n", cycles); DEBUGP("Looking for cycles: %u\n", cycles);
return ! cycles; return ! cycles;
} }
int cmph_czech_mphf_dump(cmph_mphf_t *mphf, FILE *fd) int czech_dump(cmph_t *mphf, FILE *fd)
{ {
char *buf = NULL; char *buf = NULL;
cmph_uint32 buflen; cmph_uint32 buflen;
cmph_uint32 nbuflen; cmph_uint32 nbuflen;
cmph_uint32 i; cmph_uint32 i;
cmph_uint32 two = htonl(2); //number of hash functions cmph_uint32 two = htonl(2); //number of hash functions
cmph_czech_mphf_data_t *data = (cmph_czech_mphf_data_t *)mphf->data; czech_data_t *data = (czech_data_t *)mphf->data;
cmph_uint32 nn, nm; cmph_uint32 nn, nm;
cmph__mphf_dump(mphf, fd); __cmph_dump(mphf, fd);
fwrite(&two, sizeof(cmph_uint32), 1, fd); fwrite(&two, sizeof(cmph_uint32), 1, fd);
cmph_hash_state_dump(data->hashes[0], &buf, &buflen); hash_state_dump(data->hashes[0], &buf, &buflen);
DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); DEBUGP("Dumping hash state with %u bytes to disk\n", buflen);
nbuflen = htonl(buflen); nbuflen = htonl(buflen);
fwrite(&nbuflen, sizeof(cmph_uint32), 1, fd); fwrite(&nbuflen, sizeof(cmph_uint32), 1, fd);
fwrite(buf, buflen, 1, fd); fwrite(buf, buflen, 1, fd);
free(buf); free(buf);
cmph_hash_state_dump(data->hashes[1], &buf, &buflen); hash_state_dump(data->hashes[1], &buf, &buflen);
DEBUGP("Dumping hash state with %u bytes to disk\n", buflen); DEBUGP("Dumping hash state with %u bytes to disk\n", buflen);
nbuflen = htonl(buflen); nbuflen = htonl(buflen);
fwrite(&nbuflen, sizeof(cmph_uint32), 1, fd); fwrite(&nbuflen, sizeof(cmph_uint32), 1, fd);
@ -255,32 +247,32 @@ int cmph_czech_mphf_dump(cmph_mphf_t *mphf, FILE *fd)
return 1; return 1;
} }
void cmph_czech_mphf_load(FILE *f, cmph_mphf_t *mphf) void czech_load(FILE *f, cmph_t *mphf)
{ {
cmph_uint32 nhashes; cmph_uint32 nhashes;
char fbuf[BUFSIZ]; char fbuf[BUFSIZ];
char *buf = NULL; char *buf = NULL;
cmph_uint32 buflen; cmph_uint32 buflen;
cmph_uint32 i; cmph_uint32 i;
cmph_hash_state_t *state; hash_state_t *state;
cmph_czech_mphf_data_t *czech = (cmph_czech_mphf_data_t *)malloc(sizeof(cmph_czech_mphf_data_t)); czech_data_t *czech = (czech_data_t *)malloc(sizeof(czech_data_t));
DEBUGP("Loading czech mphf\n"); DEBUGP("Loading czech mphf\n");
mphf->data = czech; mphf->data = czech;
fread(&nhashes, sizeof(cmph_uint32), 1, f); fread(&nhashes, sizeof(cmph_uint32), 1, f);
nhashes = ntohl(nhashes); nhashes = ntohl(nhashes);
czech->hashes = (cmph_hash_state_t **)malloc(sizeof(cmph_hash_state_t *)*(nhashes + 1)); czech->hashes = (hash_state_t **)malloc(sizeof(hash_state_t *)*(nhashes + 1));
czech->hashes[nhashes] = NULL; czech->hashes[nhashes] = NULL;
DEBUGP("Reading %u hashes\n", nhashes); DEBUGP("Reading %u hashes\n", nhashes);
for (i = 0; i < nhashes; ++i) for (i = 0; i < nhashes; ++i)
{ {
cmph_hash_state_t *state = NULL; hash_state_t *state = NULL;
fread(&buflen, sizeof(cmph_uint32), 1, f); fread(&buflen, sizeof(cmph_uint32), 1, f);
buflen = ntohl(buflen); buflen = ntohl(buflen);
DEBUGP("Hash state has %u bytes\n", buflen); DEBUGP("Hash state has %u bytes\n", buflen);
buf = (char *)malloc(buflen); buf = (char *)malloc(buflen);
fread(buf, buflen, 1, f); fread(buf, buflen, 1, f);
state = cmph_hash_state_load(buf, buflen); state = hash_state_load(buf, buflen);
czech->hashes[i] = state; czech->hashes[i] = state;
free(buf); free(buf);
} }
@ -303,22 +295,22 @@ void cmph_czech_mphf_load(FILE *f, cmph_mphf_t *mphf)
} }
cmph_uint32 cmph_czech_mphf_search(cmph_mphf_t *mphf, const char *key, cmph_uint32 keylen) cmph_uint32 czech_search(cmph_t *mphf, const char *key, cmph_uint32 keylen)
{ {
cmph_czech_mphf_data_t *czech = mphf->data; czech_data_t *czech = mphf->data;
cmph_uint32 h1 = cmph_hash(czech->hashes[0], key, keylen) % czech->n; cmph_uint32 h1 = hash(czech->hashes[0], key, keylen) % czech->n;
cmph_uint32 h2 = cmph_hash(czech->hashes[1], key, keylen) % czech->n; cmph_uint32 h2 = hash(czech->hashes[1], key, keylen) % czech->n;
DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2); DEBUGP("key: %s h1: %u h2: %u\n", key, h1, h2);
if (h1 == h2 && ++h2 > czech->n) h2 = 0; if (h1 == h2 && ++h2 > czech->n) h2 = 0;
DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, czech->g[h1], czech->g[h2], czech->m); DEBUGP("key: %s g[h1]: %u g[h2]: %u edges: %u\n", key, czech->g[h1], czech->g[h2], czech->m);
return (czech->g[h1] + czech->g[h2]) % czech->m; return (czech->g[h1] + czech->g[h2]) % czech->m;
} }
void cmph_czech_mphf_destroy(cmph_mphf_t *mphf) void czech_destroy(cmph_t *mphf)
{ {
cmph_czech_mphf_data_t *data = (cmph_czech_mphf_data_t *)mphf->data; czech_data_t *data = (czech_data_t *)mphf->data;
free(data->g); free(data->g);
cmph_hash_state_destroy(data->hashes[0]); hash_state_destroy(data->hashes[0]);
cmph_hash_state_destroy(data->hashes[1]); hash_state_destroy(data->hashes[1]);
free(data->hashes); free(data->hashes);
free(data); free(data);
free(mphf); free(mphf);

View File

@ -1,19 +1,18 @@
#ifndef __CZECH_H__ #ifndef __CMPH_CZECH_H__
#define __CZECH_H__ #define __CMPH_CZECH_H__
#include "graph.h"
#include "cmph.h" #include "cmph.h"
typedef struct cmph__czech_mphf_data_t cmph_czech_mphf_data_t; typedef struct __czech_data_t czech_data_t;
typedef struct cmph__czech_mph_data_t cmph_czech_mph_data_t; typedef struct __czech_config_data_t czech_config_data_t;
cmph_mph_t *cmph_czech_mph_new(cmph_key_source_t *key_source); czech_config_data_t *czech_config_new(cmph_key_source_t *key_source);
void cmph_czech_mph_set_hashfuncs(cmph_mph_t *mph, CMPH_HASH *hashfuncs); void czech_config_set_hashfuncs(cmph_config_t *mph, CMPH_HASH *hashfuncs);
void cmph_czech_mph_destroy(cmph_mph_t *mph); void czech_config_destroy(cmph_config_t *mph);
cmph_mphf_t *cmph_czech_mph_create(cmph_mph_t *mph, float c); cmph_t *czech_new(cmph_config_t *mph, float c);
void cmph_czech_mphf_load(FILE *f, cmph_mphf_t *mphf); void czech_load(FILE *f, cmph_t *mphf);
int cmph_czech_mphf_dump(cmph_mphf_t *mphf, FILE *f); int czech_dump(cmph_t *mphf, FILE *f);
void cmph_czech_mphf_destroy(cmph_mphf_t *mphf); void czech_destroy(cmph_t *mphf);
cmph_uint32 cmph_czech_mphf_search(cmph_mphf_t *mphf, const char *key, cmph_uint32 keylen); cmph_uint32 czech_search(cmph_t *mphf, const char *key, cmph_uint32 keylen);
#endif #endif

View File

@ -1,24 +1,24 @@
#ifndef __CZECH_STRUCTS_H__ #ifndef __CMPH_CZECH_STRUCTS_H__
#define __CZECH_STRUCTS_H__ #define __CMPH_CZECH_STRUCTS_H__
#include "hash_state.h" #include "hash_state.h"
struct cmph__czech_mphf_data_t struct __czech_data_t
{ {
cmph_uint32 m; //edges (words) count cmph_uint32 m; //edges (words) count
cmph_uint32 n; //vertex count cmph_uint32 n; //vertex count
cmph_uint32 *g; cmph_uint32 *g;
cmph_hash_state_t **hashes; hash_state_t **hashes;
}; };
struct cmph__czech_mph_data_t struct __czech_config_data_t
{ {
CMPH_HASH hashfuncs[2]; CMPH_HASH hashfuncs[2];
cmph_uint32 m; //edges (words) count cmph_uint32 m; //edges (words) count
cmph_uint32 n; //vertex count cmph_uint32 n; //vertex count
cmph_graph_t *graph; graph_t *graph;
cmph_uint32 *g; cmph_uint32 *g;
cmph_hash_state_t **hashes; hash_state_t **hashes;
}; };
#endif #endif

View File

@ -1,19 +1,19 @@
#include "djb2_hash.h" #include "djb2_hash.h"
#include <stdlib.h> #include <stdlib.h>
cmph_djb2_state_t *cmph_djb2_state_new() djb2_state_t *djb2_state_new()
{ {
cmph_djb2_state_t *state = (cmph_djb2_state_t *)malloc(sizeof(cmph_djb2_state_t)); djb2_state_t *state = (djb2_state_t *)malloc(sizeof(djb2_state_t));
state->hashfunc = CMPH_HASH_DJB2; state->hashfunc = CMPH_HASH_DJB2;
return state; return state;
} }
void cmph_djb2_state_destroy(cmph_djb2_state_t *state) void djb2_state_destroy(djb2_state_t *state)
{ {
free(state); free(state);
} }
cmph_uint32 cmph_djb2_hash(cmph_djb2_state_t *state, const char *k, cmph_uint32 keylen) cmph_uint32 djb2_hash(djb2_state_t *state, const char *k, cmph_uint32 keylen)
{ {
register cmph_uint32 hash = 5381; register cmph_uint32 hash = 5381;
const unsigned char *ptr = k; const unsigned char *ptr = k;
@ -27,16 +27,16 @@ cmph_uint32 cmph_djb2_hash(cmph_djb2_state_t *state, const char *k, cmph_uint32
} }
void cmph_djb2_state_dump(cmph_djb2_state_t *state, char **buf, cmph_uint32 *buflen) void djb2_state_dump(djb2_state_t *state, char **buf, cmph_uint32 *buflen)
{ {
*buf = NULL; *buf = NULL;
*buflen = 0; *buflen = 0;
return; return;
} }
cmph_djb2_state_t *cmph_djb2_state_load(const char *buf, cmph_uint32 buflen) djb2_state_t *djb2_state_load(const char *buf, cmph_uint32 buflen)
{ {
cmph_djb2_state_t *state = (cmph_djb2_state_t *)malloc(sizeof(cmph_djb2_state_t)); djb2_state_t *state = (djb2_state_t *)malloc(sizeof(djb2_state_t));
state->hashfunc = CMPH_HASH_DJB2; state->hashfunc = CMPH_HASH_DJB2;
return state; return state;
} }

View File

@ -3,15 +3,15 @@
#include "hash.h" #include "hash.h"
typedef struct cmph__djb2_state_t typedef struct __djb2_state_t
{ {
CMPH_HASH hashfunc; CMPH_HASH hashfunc;
} cmph_djb2_state_t; } djb2_state_t;
cmph_djb2_state_t *cmph_djb2_state_new(); djb2_state_t *djb2_state_new();
cmph_uint32 cmph_djb2_hash(cmph_djb2_state_t *state, const char *k, cmph_uint32 keylen); cmph_uint32 djb2_hash(djb2_state_t *state, const char *k, cmph_uint32 keylen);
void cmph_djb2_state_dump(cmph_djb2_state_t *state, char **buf, cmph_uint32 *buflen); void djb2_state_dump(djb2_state_t *state, char **buf, cmph_uint32 *buflen);
cmph_djb2_state_t *cmph_djb2_state_load(const char *buf, cmph_uint32 buflen); djb2_state_t *djb2_state_load(const char *buf, cmph_uint32 buflen);
void cmph_djb2_state_destroy(cmph_djb2_state_t *state); void djb2_state_destroy(djb2_state_t *state);
#endif #endif

View File

@ -1,19 +1,19 @@
#include "fnv_hash.h" #include "fnv_hash.h"
#include <stdlib.h> #include <stdlib.h>
cmph_fnv_state_t *cmph_fnv_state_new() fnv_state_t *fnv_state_new()
{ {
cmph_fnv_state_t *state = (cmph_fnv_state_t *)malloc(sizeof(cmph_fnv_state_t)); fnv_state_t *state = (fnv_state_t *)malloc(sizeof(fnv_state_t));
state->hashfunc = CMPH_HASH_FNV; state->hashfunc = CMPH_HASH_FNV;
return state; return state;
} }
void cmph_fnv_state_destroy(cmph_fnv_state_t *state) void fnv_state_destroy(fnv_state_t *state)
{ {
free(state); free(state);
} }
cmph_uint32 cmph_fnv_hash(cmph_fnv_state_t *state, const char *k, cmph_uint32 keylen) cmph_uint32 fnv_hash(fnv_state_t *state, const char *k, cmph_uint32 keylen)
{ {
const unsigned char *bp = (const unsigned char *)k; const unsigned char *bp = (const unsigned char *)k;
const unsigned char *be = bp + keylen; const unsigned char *be = bp + keylen;
@ -31,16 +31,16 @@ cmph_uint32 cmph_fnv_hash(cmph_fnv_state_t *state, const char *k, cmph_uint32 ke
} }
void cmph_fnv_state_dump(cmph_fnv_state_t *state, char **buf, cmph_uint32 *buflen) void fnv_state_dump(fnv_state_t *state, char **buf, cmph_uint32 *buflen)
{ {
*buf = NULL; *buf = NULL;
*buflen = 0; *buflen = 0;
return; return;
} }
cmph_fnv_state_t *cmph_fnv_state_load(const char *buf, cmph_uint32 buflen) fnv_state_t *fnv_state_load(const char *buf, cmph_uint32 buflen)
{ {
cmph_fnv_state_t *state = (cmph_fnv_state_t *)malloc(sizeof(cmph_fnv_state_t)); fnv_state_t *state = (fnv_state_t *)malloc(sizeof(fnv_state_t));
state->hashfunc = CMPH_HASH_FNV; state->hashfunc = CMPH_HASH_FNV;
return state; return state;
} }

View File

@ -3,15 +3,15 @@
#include "hash.h" #include "hash.h"
typedef struct cmph__fnv_state_t typedef struct __fnv_state_t
{ {
CMPH_HASH hashfunc; CMPH_HASH hashfunc;
} cmph_fnv_state_t; } fnv_state_t;
cmph_fnv_state_t *cmph_fnv_state_new(); fnv_state_t *fnv_state_new();
cmph_uint32 cmph_fnv_hash(cmph_fnv_state_t *state, const char *k, cmph_uint32 keylen); cmph_uint32 fnv_hash(fnv_state_t *state, const char *k, cmph_uint32 keylen);
void cmph_fnv_state_dump(cmph_fnv_state_t *state, char **buf, cmph_uint32 *buflen); void fnv_state_dump(fnv_state_t *state, char **buf, cmph_uint32 *buflen);
cmph_fnv_state_t *cmph_fnv_state_load(const char *buf, cmph_uint32 buflen); fnv_state_t *fnv_state_load(const char *buf, cmph_uint32 buflen);
void cmph_fnv_state_destroy(cmph_fnv_state_t *state); void fnv_state_destroy(fnv_state_t *state);
#endif #endif

View File

@ -6,18 +6,19 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include "vstack.h" #include "vstack.h"
#include "bitbool.h"
//#define DEBUG //#define DEBUG
#include "debug.h" #include "debug.h"
static const cmph_uint8 bitmask[8] = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 }; /* static const cmph_uint8 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 GETBIT(array, i) (array[(i) / 8] & bitmask[(i) % 8]) */
#define SETBIT(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 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 cmph__graph_t struct __graph_t
{ {
cmph_uint32 nnodes; cmph_uint32 nnodes;
cmph_uint32 nedges; cmph_uint32 nedges;
@ -32,9 +33,9 @@ struct cmph__graph_t
static cmph_uint32 EMPTY = UINT_MAX; static cmph_uint32 EMPTY = UINT_MAX;
cmph_graph_t *cmph_graph_new(cmph_uint32 nnodes, cmph_uint32 nedges) graph_t *graph_new(cmph_uint32 nnodes, cmph_uint32 nedges)
{ {
cmph_graph_t *graph = (cmph_graph_t *)malloc(sizeof(cmph_graph_t)); graph_t *graph = (graph_t *)malloc(sizeof(graph_t));
if (!graph) return NULL; if (!graph) return NULL;
graph->edges = (cmph_uint32 *)malloc(sizeof(cmph_uint32) * 2 * nedges); graph->edges = (cmph_uint32 *)malloc(sizeof(cmph_uint32) * 2 * nedges);
@ -45,12 +46,12 @@ cmph_graph_t *cmph_graph_new(cmph_uint32 nnodes, cmph_uint32 nedges)
graph->nnodes = nnodes; graph->nnodes = nnodes;
graph->nedges = nedges; graph->nedges = nedges;
cmph_graph_clear_edges(graph); graph_clear_edges(graph);
return graph; return graph;
} }
void cmph_graph_destroy(cmph_graph_t *graph) void graph_destroy(graph_t *graph)
{ {
DEBUGP("Destroying graph\n"); DEBUGP("Destroying graph\n");
free(graph->edges); free(graph->edges);
@ -61,7 +62,7 @@ void cmph_graph_destroy(cmph_graph_t *graph)
return; return;
} }
void cmph_graph_print(cmph_graph_t *g) void graph_print(graph_t *g)
{ {
cmph_uint32 i, e; cmph_uint32 i, e;
for (i = 0; i < g->nnodes; ++i) for (i = 0; i < g->nnodes; ++i)
@ -81,7 +82,7 @@ void cmph_graph_print(cmph_graph_t *g)
return; return;
} }
void cmph_graph_add_edge(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2) void graph_add_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2)
{ {
cmph_uint32 e = g->cedges; cmph_uint32 e = g->cedges;
@ -101,7 +102,7 @@ void cmph_graph_add_edge(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2)
++(g->cedges); ++(g->cedges);
} }
static int check_edge(cmph_graph_t *g, cmph_uint32 e, cmph_uint32 v1, cmph_uint32 v2) static int check_edge(graph_t *g, cmph_uint32 e, cmph_uint32 v1, cmph_uint32 v2)
{ {
DEBUGP("Checking edge %u %u looking for %u %u\n", g->edges[abs_edge(e, 0)], g->edges[abs_edge(e, 1)], v1, v2); DEBUGP("Checking edge %u %u looking for %u %u\n", g->edges[abs_edge(e, 0)], g->edges[abs_edge(e, 1)], v1, v2);
if (g->edges[abs_edge(e, 0)] == v1 && g->edges[abs_edge(e, 1)] == v2) return 1; if (g->edges[abs_edge(e, 0)] == v1 && g->edges[abs_edge(e, 1)] == v2) return 1;
@ -109,7 +110,7 @@ static int check_edge(cmph_graph_t *g, cmph_uint32 e, cmph_uint32 v1, cmph_uint3
return 0; return 0;
} }
cmph_uint32 cmph_graph_edge_id(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2) cmph_uint32 graph_edge_id(graph_t *g, cmph_uint32 v1, cmph_uint32 v2)
{ {
cmph_uint32 e; cmph_uint32 e;
e = g->first[v1]; e = g->first[v1];
@ -123,7 +124,7 @@ cmph_uint32 cmph_graph_edge_id(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2)
while (!check_edge(g, e, v1, v2)); while (!check_edge(g, e, v1, v2));
return abs_edge(e, 0); return abs_edge(e, 0);
} }
static void del_edge_point(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2) static void del_edge_point(graph_t *g, cmph_uint32 v1, cmph_uint32 v2)
{ {
cmph_uint32 e, prev; cmph_uint32 e, prev;
@ -151,14 +152,14 @@ static void del_edge_point(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2)
} }
void cmph_graph_del_edge(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2) void graph_del_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2)
{ {
g->shrinking = 1; g->shrinking = 1;
del_edge_point(g, v1, v2); del_edge_point(g, v1, v2);
del_edge_point(g, v2, v1); del_edge_point(g, v2, v1);
} }
void cmph_graph_clear_edges(cmph_graph_t *g) void graph_clear_edges(graph_t *g)
{ {
cmph_uint32 i; cmph_uint32 i;
for (i = 0; i < g->nnodes; ++i) g->first[i] = EMPTY; for (i = 0; i < g->nnodes; ++i) g->first[i] = EMPTY;
@ -171,7 +172,7 @@ void cmph_graph_clear_edges(cmph_graph_t *g)
g->shrinking = 0; g->shrinking = 0;
} }
static int find_degree1_edge(cmph_graph_t *g, cmph_uint32 v, char *deleted, cmph_uint32 *e) static int find_degree1_edge(graph_t *g, cmph_uint32 v, char *deleted, cmph_uint32 *e)
{ {
cmph_uint32 edge = g->first[v]; cmph_uint32 edge = g->first[v];
char found = 0; char found = 0;
@ -195,7 +196,7 @@ static int find_degree1_edge(cmph_graph_t *g, cmph_uint32 v, char *deleted, cmph
return found; return found;
} }
static void cyclic_del_edge(cmph_graph_t *g, cmph_uint32 v, char *deleted) static void cyclic_del_edge(graph_t *g, cmph_uint32 v, char *deleted)
{ {
cmph_uint32 e; cmph_uint32 e;
@ -224,7 +225,7 @@ static void cyclic_del_edge(cmph_graph_t *g, cmph_uint32 v, char *deleted)
} }
} }
int cmph_graph_is_cyclic(cmph_graph_t *g) int graph_is_cyclic(graph_t *g)
{ {
cmph_uint32 i; cmph_uint32 i;
cmph_uint32 v; cmph_uint32 v;
@ -249,12 +250,12 @@ int cmph_graph_is_cyclic(cmph_graph_t *g)
return 0; return 0;
} }
cmph_uint8 cmph_graph_node_is_critical(cmph_graph_t * g, cmph_uint32 v) /* included -- Fabiano */ cmph_uint8 graph_node_is_critical(graph_t * g, cmph_uint32 v) /* included -- Fabiano */
{ {
return GETBIT(g->critical_nodes,v); return GETBIT(g->critical_nodes,v);
} }
void cmph_graph_obtain_critical_nodes(cmph_graph_t *g) /* included -- Fabiano*/ void graph_obtain_critical_nodes(graph_t *g) /* included -- Fabiano*/
{ {
cmph_uint32 i; cmph_uint32 i;
cmph_uint32 v; cmph_uint32 v;
@ -290,7 +291,7 @@ void cmph_graph_obtain_critical_nodes(cmph_graph_t *g) /* included -- Fabiano*/
free(deleted); free(deleted);
} }
cmph_uint8 cmph_graph_contains_edge(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2) /* included -- Fabiano*/ cmph_uint8 graph_contains_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2) /* included -- Fabiano*/
{ {
cmph_uint32 e; cmph_uint32 e;
e = g->first[v1]; e = g->first[v1];
@ -305,27 +306,27 @@ cmph_uint8 cmph_graph_contains_edge(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32
return 1; return 1;
} }
cmph_uint32 cmph_graph_vertex_id(cmph_graph_t *g, cmph_uint32 e, cmph_uint32 id) /* included -- Fabiano*/ cmph_uint32 graph_vertex_id(graph_t *g, cmph_uint32 e, cmph_uint32 id) /* included -- Fabiano*/
{ {
return (g->edges[e + id*g->nedges]); return (g->edges[e + id*g->nedges]);
} }
cmph_uint32 cmph_graph_ncritical_nodes(cmph_graph_t *g) /* included -- Fabiano*/ cmph_uint32 graph_ncritical_nodes(graph_t *g) /* included -- Fabiano*/
{ {
return g->ncritical_nodes; return g->ncritical_nodes;
} }
cmph_graph_iterator_t cmph_graph_neighbors_it(cmph_graph_t *g, cmph_uint32 v) graph_iterator_t graph_neighbors_it(graph_t *g, cmph_uint32 v)
{ {
cmph_graph_iterator_t it; graph_iterator_t it;
it.vertex = v; it.vertex = v;
it.edge = g->first[v]; it.edge = g->first[v];
return it; return it;
} }
cmph_uint32 cmph_graph_next_neighbor(cmph_graph_t *g, cmph_graph_iterator_t* it) cmph_uint32 graph_next_neighbor(graph_t *g, graph_iterator_t* it)
{ {
cmph_uint32 ret; cmph_uint32 ret;
if(it->edge == EMPTY) return CMPH_GRAPH_NO_NEIGHBOR; if(it->edge == EMPTY) return GRAPH_NO_NEIGHBOR;
if (g->edges[it->edge] == it->vertex) ret = g->edges[it->edge + g->nedges]; if (g->edges[it->edge] == it->vertex) ret = g->edges[it->edge + g->nedges];
else ret = g->edges[it->edge]; else ret = g->edges[it->edge];
it->edge = g->next[it->edge]; it->edge = g->next[it->edge];

View File

@ -4,11 +4,11 @@
#include <limits.h> #include <limits.h>
#include "cmph_types.h" #include "cmph_types.h"
#define CMPH_GRAPH_NO_NEIGHBOR UINT_MAX #define GRAPH_NO_NEIGHBOR UINT_MAX
typedef struct cmph__graph_t cmph_graph_t; typedef struct __graph_t graph_t;
typedef struct cmph__graph_iterator_t cmph_graph_iterator_t; typedef struct __graph_iterator_t graph_iterator_t;
struct cmph__graph_iterator_t struct __graph_iterator_t
{ {
cmph_uint32 vertex; cmph_uint32 vertex;
cmph_uint32 edge; cmph_uint32 edge;
@ -16,25 +16,25 @@ struct cmph__graph_iterator_t
cmph_graph_t *cmph_graph_new(cmph_uint32 nnodes, cmph_uint32 nedges); graph_t *graph_new(cmph_uint32 nnodes, cmph_uint32 nedges);
void cmph_graph_destroy(cmph_graph_t *graph); void graph_destroy(graph_t *graph);
void cmph_graph_add_edge(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2); void graph_add_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2);
void cmph_graph_del_edge(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2); void graph_del_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2);
void cmph_graph_clear_edges(cmph_graph_t *g); void graph_clear_edges(graph_t *g);
cmph_uint32 cmph_graph_edge_id(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2); cmph_uint32 graph_edge_id(graph_t *g, cmph_uint32 v1, cmph_uint32 v2);
cmph_uint8 cmph_graph_contains_edge(cmph_graph_t *g, cmph_uint32 v1, cmph_uint32 v2); cmph_uint8 graph_contains_edge(graph_t *g, cmph_uint32 v1, cmph_uint32 v2);
cmph_graph_iterator_t cmph_graph_neighbors_it(cmph_graph_t *g, cmph_uint32 v); graph_iterator_t graph_neighbors_it(graph_t *g, cmph_uint32 v);
cmph_uint32 cmph_graph_next_neighbor(cmph_graph_t *g, cmph_graph_iterator_t* it); cmph_uint32 graph_next_neighbor(graph_t *g, graph_iterator_t* it);
void cmph_graph_obtain_critical_nodes(cmph_graph_t *g); /* included -- Fabiano*/ void graph_obtain_critical_nodes(graph_t *g); /* included -- Fabiano*/
cmph_uint8 cmph_graph_node_is_critical(cmph_graph_t * g, cmph_uint32 v); /* included -- Fabiano */ cmph_uint8 graph_node_is_critical(graph_t * g, cmph_uint32 v); /* included -- Fabiano */
cmph_uint32 cmph_graph_ncritical_nodes(cmph_graph_t *g); /* included -- Fabiano*/ cmph_uint32 graph_ncritical_nodes(graph_t *g); /* included -- Fabiano*/
cmph_uint32 cmph_graph_vertex_id(cmph_graph_t *g, cmph_uint32 e, cmph_uint32 id); /* included -- Fabiano*/ cmph_uint32 graph_vertex_id(graph_t *g, cmph_uint32 e, cmph_uint32 id); /* included -- Fabiano*/
int cmph_graph_is_cyclic(cmph_graph_t *g); int graph_is_cyclic(graph_t *g);
void cmph_graph_print(cmph_graph_t *); void graph_print(graph_t *);
#endif #endif

View File

@ -7,26 +7,26 @@
//#define DEBUG //#define DEBUG
#include "debug.h" #include "debug.h"
const char *cmph_hash_names[] = { "jenkins", "djb2", "sdbm", "fnv", "glib", "pjw", NULL }; const char *cmph_hash_names[] = { "djb2", "fnv", "glib", "jenkins", "pjw", "sdbm", NULL };
cmph_hash_state_t *cmph_hash_state_new(CMPH_HASH hashfunc, cmph_uint32 hashsize) hash_state_t *hash_state_new(CMPH_HASH hashfunc, cmph_uint32 hashsize)
{ {
cmph_hash_state_t *state = NULL; hash_state_t *state = NULL;
switch (hashfunc) switch (hashfunc)
{ {
case CMPH_HASH_JENKINS: case CMPH_HASH_JENKINS:
DEBUGP("Jenkins function - %u\n", hashsize); DEBUGP("Jenkins function - %u\n", hashsize);
state = (cmph_hash_state_t *)cmph_jenkins_state_new(hashsize); state = (hash_state_t *)jenkins_state_new(hashsize);
DEBUGP("Jenkins function created\n"); DEBUGP("Jenkins function created\n");
break; break;
case CMPH_HASH_DJB2: case CMPH_HASH_DJB2:
state = (cmph_hash_state_t *)cmph_djb2_state_new(); state = (hash_state_t *)djb2_state_new();
break; break;
case CMPH_HASH_SDBM: case CMPH_HASH_SDBM:
state = (cmph_hash_state_t *)cmph_sdbm_state_new(); state = (hash_state_t *)sdbm_state_new();
break; break;
case CMPH_HASH_FNV: case CMPH_HASH_FNV:
state = (cmph_hash_state_t *)cmph_fnv_state_new(); state = (hash_state_t *)fnv_state_new();
break; break;
default: default:
assert(0); assert(0);
@ -34,18 +34,18 @@ cmph_hash_state_t *cmph_hash_state_new(CMPH_HASH hashfunc, cmph_uint32 hashsize)
state->hashfunc = hashfunc; state->hashfunc = hashfunc;
return state; return state;
} }
cmph_uint32 cmph_hash(cmph_hash_state_t *state, const char *key, cmph_uint32 keylen) cmph_uint32 hash(hash_state_t *state, const char *key, cmph_uint32 keylen)
{ {
switch (state->hashfunc) switch (state->hashfunc)
{ {
case CMPH_HASH_JENKINS: case CMPH_HASH_JENKINS:
return cmph_jenkins_hash((cmph_jenkins_state_t *)state, key, keylen); return jenkins_hash((jenkins_state_t *)state, key, keylen);
case CMPH_HASH_DJB2: case CMPH_HASH_DJB2:
return cmph_djb2_hash((cmph_djb2_state_t *)state, key, keylen); return djb2_hash((djb2_state_t *)state, key, keylen);
case CMPH_HASH_SDBM: case CMPH_HASH_SDBM:
return cmph_sdbm_hash((cmph_sdbm_state_t *)state, key, keylen); return sdbm_hash((sdbm_state_t *)state, key, keylen);
case CMPH_HASH_FNV: case CMPH_HASH_FNV:
return cmph_fnv_hash((cmph_fnv_state_t *)state, key, keylen); return fnv_hash((fnv_state_t *)state, key, keylen);
default: default:
assert(0); assert(0);
} }
@ -53,25 +53,25 @@ cmph_uint32 cmph_hash(cmph_hash_state_t *state, const char *key, cmph_uint32 key
return 0; return 0;
} }
void cmph_hash_state_dump(cmph_hash_state_t *state, char **buf, cmph_uint32 *buflen) void hash_state_dump(hash_state_t *state, char **buf, cmph_uint32 *buflen)
{ {
char *algobuf; char *algobuf;
switch (state->hashfunc) switch (state->hashfunc)
{ {
case CMPH_HASH_JENKINS: case CMPH_HASH_JENKINS:
cmph_jenkins_state_dump((cmph_jenkins_state_t *)state, &algobuf, buflen); jenkins_state_dump((jenkins_state_t *)state, &algobuf, buflen);
if (*buflen == UINT_MAX) return; if (*buflen == UINT_MAX) return;
break; break;
case CMPH_HASH_DJB2: case CMPH_HASH_DJB2:
cmph_djb2_state_dump((cmph_djb2_state_t *)state, &algobuf, buflen); djb2_state_dump((djb2_state_t *)state, &algobuf, buflen);
if (*buflen == UINT_MAX) return; if (*buflen == UINT_MAX) return;
break; break;
case CMPH_HASH_SDBM: case CMPH_HASH_SDBM:
cmph_sdbm_state_dump((cmph_sdbm_state_t *)state, &algobuf, buflen); sdbm_state_dump((sdbm_state_t *)state, &algobuf, buflen);
if (*buflen == UINT_MAX) return; if (*buflen == UINT_MAX) return;
break; break;
case CMPH_HASH_FNV: case CMPH_HASH_FNV:
cmph_fnv_state_dump((cmph_fnv_state_t *)state, &algobuf, buflen); fnv_state_dump((fnv_state_t *)state, &algobuf, buflen);
if (*buflen == UINT_MAX) return; if (*buflen == UINT_MAX) return;
break; break;
default: default:
@ -86,7 +86,7 @@ void cmph_hash_state_dump(cmph_hash_state_t *state, char **buf, cmph_uint32 *buf
return; return;
} }
cmph_hash_state_t *cmph_hash_state_load(const char *buf, cmph_uint32 buflen) hash_state_t *hash_state_load(const char *buf, cmph_uint32 buflen)
{ {
cmph_uint32 i; cmph_uint32 i;
cmph_uint32 offset; cmph_uint32 offset;
@ -104,33 +104,33 @@ cmph_hash_state_t *cmph_hash_state_load(const char *buf, cmph_uint32 buflen)
switch (hashfunc) switch (hashfunc)
{ {
case CMPH_HASH_JENKINS: case CMPH_HASH_JENKINS:
return (cmph_hash_state_t *)cmph_jenkins_state_load(buf + offset, buflen - offset); return (hash_state_t *)jenkins_state_load(buf + offset, buflen - offset);
case CMPH_HASH_DJB2: case CMPH_HASH_DJB2:
return (cmph_hash_state_t *)cmph_djb2_state_load(buf + offset, buflen - offset); return (hash_state_t *)djb2_state_load(buf + offset, buflen - offset);
case CMPH_HASH_SDBM: case CMPH_HASH_SDBM:
return (cmph_hash_state_t *)cmph_sdbm_state_load(buf + offset, buflen - offset); return (hash_state_t *)sdbm_state_load(buf + offset, buflen - offset);
case CMPH_HASH_FNV: case CMPH_HASH_FNV:
return (cmph_hash_state_t *)cmph_fnv_state_load(buf + offset, buflen - offset); return (hash_state_t *)fnv_state_load(buf + offset, buflen - offset);
default: default:
return NULL; return NULL;
} }
return NULL; return NULL;
} }
void cmph_hash_state_destroy(cmph_hash_state_t *state) void hash_state_destroy(hash_state_t *state)
{ {
switch (state->hashfunc) switch (state->hashfunc)
{ {
case CMPH_HASH_JENKINS: case CMPH_HASH_JENKINS:
cmph_jenkins_state_destroy((cmph_jenkins_state_t *)state); jenkins_state_destroy((jenkins_state_t *)state);
break; break;
case CMPH_HASH_DJB2: case CMPH_HASH_DJB2:
cmph_djb2_state_destroy((cmph_djb2_state_t *)state); djb2_state_destroy((djb2_state_t *)state);
break; break;
case CMPH_HASH_SDBM: case CMPH_HASH_SDBM:
cmph_sdbm_state_destroy((cmph_sdbm_state_t *)state); sdbm_state_destroy((sdbm_state_t *)state);
break; break;
case CMPH_HASH_FNV: case CMPH_HASH_FNV:
cmph_fnv_state_destroy((cmph_fnv_state_t *)state); fnv_state_destroy((fnv_state_t *)state);
break; break;
default: default:
assert(0); assert(0);

View File

@ -3,12 +3,12 @@
#include "cmph_types.h" #include "cmph_types.h"
typedef union cmph__hash_state_t cmph_hash_state_t; typedef union __hash_state_t hash_state_t;
cmph_hash_state_t *cmph_hash_state_new(CMPH_HASH, cmph_uint32 hashsize); hash_state_t *hash_state_new(CMPH_HASH, cmph_uint32 hashsize);
cmph_uint32 cmph_hash(cmph_hash_state_t *state, const char *key, cmph_uint32 keylen); cmph_uint32 hash(hash_state_t *state, const char *key, cmph_uint32 keylen);
void cmph_hash_state_dump(cmph_hash_state_t *state, char **buf, cmph_uint32 *buflen); void hash_state_dump(hash_state_t *state, char **buf, cmph_uint32 *buflen);
cmph_hash_state_t *cmph_hash_state_load(const char *buf, cmph_uint32 buflen); hash_state_t *hash_state_load(const char *buf, cmph_uint32 buflen);
void cmph_hash_state_destroy(cmph_hash_state_t *state); void hash_state_destroy(hash_state_t *state);
#endif #endif

View File

@ -6,13 +6,13 @@
#include "djb2_hash.h" #include "djb2_hash.h"
#include "sdbm_hash.h" #include "sdbm_hash.h"
#include "fnv_hash.h" #include "fnv_hash.h"
union cmph__hash_state_t union __hash_state_t
{ {
CMPH_HASH hashfunc; CMPH_HASH hashfunc;
cmph_jenkins_state_t jenkins; jenkins_state_t jenkins;
cmph_djb2_state_t djb2; djb2_state_t djb2;
cmph_sdbm_state_t sdbm; sdbm_state_t sdbm;
cmph_fnv_state_t fnv; fnv_state_t fnv;
}; };
#endif #endif

View File

@ -84,9 +84,9 @@ Use for hash table lookup, or anything where one collision in 2^^32 is
acceptable. Do NOT use for cryptographic purposes. acceptable. Do NOT use for cryptographic purposes.
-------------------------------------------------------------------- --------------------------------------------------------------------
*/ */
cmph_jenkins_state_t *cmph_jenkins_state_new(cmph_uint32 size) //size of hash table jenkins_state_t *jenkins_state_new(cmph_uint32 size) //size of hash table
{ {
cmph_jenkins_state_t *state = (cmph_jenkins_state_t *)malloc(sizeof(cmph_jenkins_state_t)); jenkins_state_t *state = (jenkins_state_t *)malloc(sizeof(jenkins_state_t));
DEBUGP("Initializing jenkins hash\n"); DEBUGP("Initializing jenkins hash\n");
state->seed = rand() % size; state->seed = rand() % size;
state->nbits = (cmph_uint32)ceil(log(size)/M_LOG2E); state->nbits = (cmph_uint32)ceil(log(size)/M_LOG2E);
@ -94,12 +94,12 @@ cmph_jenkins_state_t *cmph_jenkins_state_new(cmph_uint32 size) //size of hash ta
DEBUGP("Initialized jenkins with size %u, nbits %u and seed %u\n", size, state->nbits, state->seed); DEBUGP("Initialized jenkins with size %u, nbits %u and seed %u\n", size, state->nbits, state->seed);
return state; return state;
} }
void cmph_jenkins_state_destroy(cmph_jenkins_state_t *state) void jenkins_state_destroy(jenkins_state_t *state)
{ {
free(state); free(state);
} }
cmph_uint32 cmph_jenkins_hash(cmph_jenkins_state_t *state, const char *k, cmph_uint32 keylen) cmph_uint32 jenkins_hash(jenkins_state_t *state, const char *k, cmph_uint32 keylen)
{ {
cmph_uint32 a, b, c; cmph_uint32 a, b, c;
cmph_uint32 len, length; cmph_uint32 len, length;
@ -162,7 +162,7 @@ cmph_uint32 cmph_jenkins_hash(cmph_jenkins_state_t *state, const char *k, cmph_u
return c; return c;
} }
void cmph_jenkins_state_dump(cmph_jenkins_state_t *state, char **buf, cmph_uint32 *buflen) void jenkins_state_dump(jenkins_state_t *state, char **buf, cmph_uint32 *buflen)
{ {
*buflen = sizeof(cmph_uint32)*3; *buflen = sizeof(cmph_uint32)*3;
*buf = malloc(*buflen); *buf = malloc(*buflen);
@ -178,9 +178,9 @@ void cmph_jenkins_state_dump(cmph_jenkins_state_t *state, char **buf, cmph_uint3
return; return;
} }
cmph_jenkins_state_t *cmph_jenkins_state_load(const char *buf, cmph_uint32 buflen) jenkins_state_t *jenkins_state_load(const char *buf, cmph_uint32 buflen)
{ {
cmph_jenkins_state_t *state = (cmph_jenkins_state_t *)malloc(sizeof(cmph_jenkins_state_t)); jenkins_state_t *state = (jenkins_state_t *)malloc(sizeof(jenkins_state_t));
state->seed = *(cmph_uint32 *)buf; state->seed = *(cmph_uint32 *)buf;
state->nbits = *(((cmph_uint32 *)buf) + 1); state->nbits = *(((cmph_uint32 *)buf) + 1);
state->size = *(((cmph_uint32 *)buf) + 2); state->size = *(((cmph_uint32 *)buf) + 2);

View File

@ -3,18 +3,18 @@
#include "hash.h" #include "hash.h"
typedef struct cmph__jenkins_state_t typedef struct __jenkins_state_t
{ {
CMPH_HASH hashfunc; CMPH_HASH hashfunc;
cmph_uint32 seed; cmph_uint32 seed;
cmph_uint32 nbits; cmph_uint32 nbits;
cmph_uint32 size; cmph_uint32 size;
} cmph_jenkins_state_t; } jenkins_state_t;
cmph_jenkins_state_t *cmph_jenkins_state_new(cmph_uint32 size); //size of hash table jenkins_state_t *jenkins_state_new(cmph_uint32 size); //size of hash table
cmph_uint32 cmph_jenkins_hash(cmph_jenkins_state_t *state, const char *k, cmph_uint32 keylen); cmph_uint32 jenkins_hash(jenkins_state_t *state, const char *k, cmph_uint32 keylen);
void cmph_jenkins_state_dump(cmph_jenkins_state_t *state, char **buf, cmph_uint32 *buflen); void jenkins_state_dump(jenkins_state_t *state, char **buf, cmph_uint32 *buflen);
cmph_jenkins_state_t *cmph_jenkins_state_load(const char *buf, cmph_uint32 buflen); jenkins_state_t *jenkins_state_load(const char *buf, cmph_uint32 buflen);
void cmph_jenkins_state_destroy(cmph_jenkins_state_t *state); void jenkins_state_destroy(jenkins_state_t *state);
#endif #endif

View File

@ -106,8 +106,8 @@ int main(int argc, char **argv)
cmph_uint32 i; cmph_uint32 i;
CMPH_ALGO mph_algo = CMPH_CZECH; CMPH_ALGO mph_algo = CMPH_CZECH;
float c = 2.09; float c = 2.09;
cmph_mph_t *mph = NULL; cmph_config_t *config = NULL;
cmph_mphf_t *mphf = NULL; cmph_t *mphf = NULL;
cmph_key_source_t source; cmph_key_source_t source;
@ -243,18 +243,18 @@ int main(int argc, char **argv)
if (generate) if (generate)
{ {
//Create mphf //Create mphf
config = cmph_config_new(&source);
mph = cmph_mph_new(mph_algo, &source); cmph_config_set_algo(config, mph_algo);
if (nhashes) cmph_mph_set_hashfuncs(mph, hashes); if (nhashes) cmph_config_set_hashfuncs(config, hashes);
cmph_mph_set_verbosity(mph, verbosity); cmph_config_set_verbosity(config, verbosity);
if(mph_algo == CMPH_BMZ && c >= 2.0) c=1.15; if(mph_algo == CMPH_BMZ && c >= 2.0) c=1.15;
if (c != 0) cmph_mph_set_graphsize(mph, c); if (c != 0) cmph_config_set_graphsize(config, c);
mphf = cmph_mph_create(mph); mphf = cmph_new(config);
if (mphf == NULL) if (mphf == NULL)
{ {
fprintf(stderr, "Unable to create minimum perfect hashing function\n"); fprintf(stderr, "Unable to create minimum perfect hashing function\n");
cmph_mph_destroy(mph); cmph_config_destroy(config);
free(mphf_file); free(mphf_file);
return -1; return -1;
} }
@ -266,13 +266,13 @@ int main(int argc, char **argv)
free(mphf_file); free(mphf_file);
return -1; return -1;
} }
cmph_mphf_dump(mphf, mphf_fd); cmph_dump(mphf, mphf_fd);
cmph_mphf_destroy(mphf); cmph_destroy(mphf);
fclose(mphf_fd); fclose(mphf_fd);
} }
else else
{ {
cmph_uint8 * hashtable = NULL; cmph_uint8 * hashtable = NULL;
mphf_fd = fopen(mphf_file, "r"); mphf_fd = fopen(mphf_file, "r");
if (mphf_fd == NULL) if (mphf_fd == NULL)
{ {
@ -280,7 +280,7 @@ int main(int argc, char **argv)
free(mphf_file); free(mphf_file);
return -1; return -1;
} }
mphf = cmph_mphf_load(mphf_fd); mphf = cmph_load(mphf_fd);
fclose(mphf_fd); fclose(mphf_fd);
if (!mphf) if (!mphf)
{ {
@ -297,7 +297,7 @@ int main(int argc, char **argv)
char *buf; char *buf;
cmph_uint32 buflen = 0; cmph_uint32 buflen = 0;
source.read(source.data, &buf, &buflen); source.read(source.data, &buf, &buflen);
h = cmph_mphf_search(mphf, buf, buflen); h = cmph_search(mphf, buf, buflen);
if(hashtable[h])fprintf(stderr, "collision: %u\n",h); if(hashtable[h])fprintf(stderr, "collision: %u\n",h);
assert(hashtable[h]==0); assert(hashtable[h]==0);
hashtable[h] = 1; hashtable[h] = 1;
@ -307,7 +307,7 @@ int main(int argc, char **argv)
} }
source.dispose(source.data, buf, buflen); source.dispose(source.data, buf, buflen);
} }
cmph_mphf_destroy(mphf); cmph_destroy(mphf);
free(hashtable); free(hashtable);
} }
fclose(keys_fd); fclose(keys_fd);

View File

@ -1,19 +1,19 @@
#include "sdbm_hash.h" #include "sdbm_hash.h"
#include <stdlib.h> #include <stdlib.h>
cmph_sdbm_state_t *cmph_sdbm_state_new() sdbm_state_t *sdbm_state_new()
{ {
cmph_sdbm_state_t *state = (cmph_sdbm_state_t *)malloc(sizeof(cmph_sdbm_state_t)); sdbm_state_t *state = (sdbm_state_t *)malloc(sizeof(sdbm_state_t));
state->hashfunc = CMPH_HASH_SDBM; state->hashfunc = CMPH_HASH_SDBM;
return state; return state;
} }
void cmph_sdbm_state_destroy(cmph_sdbm_state_t *state) void sdbm_state_destroy(sdbm_state_t *state)
{ {
free(state); free(state);
} }
cmph_uint32 cmph_sdbm_hash(cmph_sdbm_state_t *state, const char *k, cmph_uint32 keylen) cmph_uint32 sdbm_hash(sdbm_state_t *state, const char *k, cmph_uint32 keylen)
{ {
register cmph_uint32 hash = 0; register cmph_uint32 hash = 0;
const unsigned char *ptr = k; const unsigned char *ptr = k;
@ -27,16 +27,16 @@ cmph_uint32 cmph_sdbm_hash(cmph_sdbm_state_t *state, const char *k, cmph_uint32
} }
void cmph_sdbm_state_dump(cmph_sdbm_state_t *state, char **buf, cmph_uint32 *buflen) void sdbm_state_dump(sdbm_state_t *state, char **buf, cmph_uint32 *buflen)
{ {
*buf = NULL; *buf = NULL;
*buflen = 0; *buflen = 0;
return; return;
} }
cmph_sdbm_state_t *cmph_sdbm_state_load(const char *buf, cmph_uint32 buflen) sdbm_state_t *sdbm_state_load(const char *buf, cmph_uint32 buflen)
{ {
cmph_sdbm_state_t *state = (cmph_sdbm_state_t *)malloc(sizeof(cmph_sdbm_state_t)); sdbm_state_t *state = (sdbm_state_t *)malloc(sizeof(sdbm_state_t));
state->hashfunc = CMPH_HASH_SDBM; state->hashfunc = CMPH_HASH_SDBM;
return state; return state;
} }

View File

@ -3,15 +3,15 @@
#include "hash.h" #include "hash.h"
typedef struct cmph__sdbm_state_t typedef struct __sdbm_state_t
{ {
CMPH_HASH hashfunc; CMPH_HASH hashfunc;
} cmph_sdbm_state_t; } sdbm_state_t;
cmph_sdbm_state_t *cmph_sdbm_state_new(); sdbm_state_t *sdbm_state_new();
cmph_uint32 cmph_sdbm_hash(cmph_sdbm_state_t *state, const char *k, cmph_uint32 keylen); cmph_uint32 sdbm_hash(sdbm_state_t *state, const char *k, cmph_uint32 keylen);
void cmph_sdbm_state_dump(cmph_sdbm_state_t *state, char **buf, cmph_uint32 *buflen); void sdbm_state_dump(sdbm_state_t *state, char **buf, cmph_uint32 *buflen);
cmph_sdbm_state_t *cmph_sdbm_state_load(const char *buf, cmph_uint32 buflen); sdbm_state_t *sdbm_state_load(const char *buf, cmph_uint32 buflen);
void cmph_sdbm_state_destroy(cmph_sdbm_state_t *state); void sdbm_state_destroy(sdbm_state_t *state);
#endif #endif

View File

@ -2,15 +2,15 @@
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
struct cmph__vqueue_t struct __vqueue_t
{ {
cmph_uint32 * values; cmph_uint32 * values;
cmph_uint32 beg, end, capacity; cmph_uint32 beg, end, capacity;
}; };
cmph_vqueue_t * cmph_vqueue_new(cmph_uint32 capacity) vqueue_t * vqueue_new(cmph_uint32 capacity)
{ {
cmph_vqueue_t *q = (cmph_vqueue_t *)malloc(sizeof(cmph_vqueue_t)); vqueue_t *q = (vqueue_t *)malloc(sizeof(vqueue_t));
assert(q); assert(q);
q->values = (cmph_uint32 *)calloc(capacity+1, sizeof(cmph_uint32)); q->values = (cmph_uint32 *)calloc(capacity+1, sizeof(cmph_uint32));
q->beg = q->end = 0; q->beg = q->end = 0;
@ -18,33 +18,33 @@ cmph_vqueue_t * cmph_vqueue_new(cmph_uint32 capacity)
return q; return q;
} }
cmph_uint8 cmph_vqueue_is_empty(cmph_vqueue_t * q) cmph_uint8 vqueue_is_empty(vqueue_t * q)
{ {
return (q->beg == q->end); return (q->beg == q->end);
} }
void cmph_vqueue_insert(cmph_vqueue_t * q, cmph_uint32 val) void vqueue_insert(vqueue_t * q, cmph_uint32 val)
{ {
assert((q->end + 1)%q->capacity != q->beg); // Is queue full? assert((q->end + 1)%q->capacity != q->beg); // Is queue full?
q->end = (q->end + 1)%q->capacity; q->end = (q->end + 1)%q->capacity;
q->values[q->end] = val; q->values[q->end] = val;
} }
cmph_uint32 cmph_vqueue_remove(cmph_vqueue_t * q) cmph_uint32 vqueue_remove(vqueue_t * q)
{ {
assert(!cmph_vqueue_is_empty(q)); // Is queue empty? assert(!vqueue_is_empty(q)); // Is queue empty?
q->beg = (q->beg + 1)%q->capacity; q->beg = (q->beg + 1)%q->capacity;
return q->values[q->beg]; return q->values[q->beg];
} }
void cmph_vqueue_print(cmph_vqueue_t * q) void vqueue_print(vqueue_t * q)
{ {
cmph_uint32 i; cmph_uint32 i;
for (i = q->beg; i != q->end; i = (i + 1)%q->capacity) for (i = q->beg; i != q->end; i = (i + 1)%q->capacity)
fprintf(stderr, "%u\n", q->values[(i + 1)%q->capacity]); fprintf(stderr, "%u\n", q->values[(i + 1)%q->capacity]);
} }
void cmph_vqueue_destroy(cmph_vqueue_t *q) void vqueue_destroy(vqueue_t *q)
{ {
free(q->values); q->values = NULL; free(q->values); q->values = NULL;
} }

View File

@ -2,17 +2,17 @@
#define __CMPH_VQUEUE_H__ #define __CMPH_VQUEUE_H__
#include "cmph_types.h" #include "cmph_types.h"
typedef struct cmph__vqueue_t cmph_vqueue_t; typedef struct __vqueue_t vqueue_t;
cmph_vqueue_t * cmph_vqueue_new(cmph_uint32 capacity); vqueue_t * vqueue_new(cmph_uint32 capacity);
cmph_uint8 cmph_vqueue_is_empty(cmph_vqueue_t * q); cmph_uint8 vqueue_is_empty(vqueue_t * q);
void cmph_vqueue_insert(cmph_vqueue_t * q, cmph_uint32 val); void vqueue_insert(vqueue_t * q, cmph_uint32 val);
cmph_uint32 cmph_vqueue_remove(cmph_vqueue_t * q); cmph_uint32 vqueue_remove(vqueue_t * q);
void cmph_vqueue_print(cmph_vqueue_t * q); void vqueue_print(vqueue_t * q);
void cmph_vqueue_destroy(cmph_vqueue_t * q); void vqueue_destroy(vqueue_t * q);
#endif #endif

View File

@ -6,16 +6,16 @@
//#define DEBUG //#define DEBUG
#include "debug.h" #include "debug.h"
struct cmph__vstack_t struct __vstack_t
{ {
cmph_uint32 pointer; cmph_uint32 pointer;
cmph_uint32 *values; cmph_uint32 *values;
cmph_uint32 capacity; cmph_uint32 capacity;
}; };
cmph_vstack_t *cmph_vstack_new() vstack_t *vstack_new()
{ {
cmph_vstack_t *stack = (cmph_vstack_t *)malloc(sizeof(cmph_vstack_t)); vstack_t *stack = (vstack_t *)malloc(sizeof(vstack_t));
assert(stack); assert(stack);
stack->pointer = 0; stack->pointer = 0;
stack->values = NULL; stack->values = NULL;
@ -23,43 +23,43 @@ cmph_vstack_t *cmph_vstack_new()
return stack; return stack;
} }
void cmph_vstack_destroy(cmph_vstack_t *stack) void vstack_destroy(vstack_t *stack)
{ {
assert(stack); assert(stack);
free(stack->values); free(stack->values);
free(stack); free(stack);
} }
void cmph_vstack_push(cmph_vstack_t *stack, cmph_uint32 val) void vstack_push(vstack_t *stack, cmph_uint32 val)
{ {
assert(stack); assert(stack);
cmph_vstack_reserve(stack, stack->pointer + 1); vstack_reserve(stack, stack->pointer + 1);
stack->values[stack->pointer] = val; stack->values[stack->pointer] = val;
++(stack->pointer); ++(stack->pointer);
} }
void cmph_vstack_pop(cmph_vstack_t *stack) void vstack_pop(vstack_t *stack)
{ {
assert(stack); assert(stack);
assert(stack->pointer > 0); assert(stack->pointer > 0);
--(stack->pointer); --(stack->pointer);
} }
cmph_uint32 cmph_vstack_top(cmph_vstack_t *stack) cmph_uint32 vstack_top(vstack_t *stack)
{ {
assert(stack); assert(stack);
assert(stack->pointer > 0); assert(stack->pointer > 0);
return stack->values[(stack->pointer - 1)]; return stack->values[(stack->pointer - 1)];
} }
int cmph_vstack_empty(cmph_vstack_t *stack) int vstack_empty(vstack_t *stack)
{ {
assert(stack); assert(stack);
return stack->pointer == 0; return stack->pointer == 0;
} }
cmph_uint32 cmph_vstack_size(cmph_vstack_t *stack) cmph_uint32 vstack_size(vstack_t *stack)
{ {
return stack->pointer; return stack->pointer;
} }
void cmph_vstack_reserve(cmph_vstack_t *stack, cmph_uint32 size) void vstack_reserve(vstack_t *stack, cmph_uint32 size)
{ {
assert(stack); assert(stack);
if (stack->capacity < size) if (stack->capacity < size)

View File

@ -2,17 +2,17 @@
#define __CMPH_VSTACK_H__ #define __CMPH_VSTACK_H__
#include "cmph_types.h" #include "cmph_types.h"
typedef struct cmph__vstack_t cmph_vstack_t; typedef struct __vstack_t vstack_t;
cmph_vstack_t *cmph_vstack_new(); vstack_t *vstack_new();
void cmph_vstack_destroy(cmph_vstack_t *stack); void vstack_destroy(vstack_t *stack);
void cmph_vstack_push(cmph_vstack_t *stack, cmph_uint32 val); void vstack_push(vstack_t *stack, cmph_uint32 val);
cmph_uint32 cmph_vstack_top(cmph_vstack_t *stack); cmph_uint32 vstack_top(vstack_t *stack);
void cmph_vstack_pop(cmph_vstack_t *stack); void vstack_pop(vstack_t *stack);
int cmph_vstack_empty(cmph_vstack_t *stack); int vstack_empty(vstack_t *stack);
cmph_uint32 cmph_vstack_size(cmph_vstack_t *stack); cmph_uint32 vstack_size(vstack_t *stack);
void cmph_vstack_reserve(cmph_vstack_t *stack, cmph_uint32 size); void vstack_reserve(vstack_t *stack, cmph_uint32 size);
#endif #endif