diff --git a/Makefile.am b/Makefile.am index c735106..a8d050c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,2 +1,2 @@ -SUBDIRS = src tests +SUBDIRS = src tests examples EXTRA_DIST = cmph.spec configure.ac diff --git a/configure.ac b/configure.ac index 9986da0..f3b0bb1 100644 --- a/configure.ac +++ b/configure.ac @@ -35,4 +35,4 @@ dnl Checks for library functions. AC_CHECK_SPOON dnl AC_OUTPUT(Makefile tests/Makefile samples/Makefile) -AC_OUTPUT(Makefile src/Makefile tests/Makefile) +AC_OUTPUT(Makefile src/Makefile tests/Makefile examples/Makefile) diff --git a/examples/Makefile.am b/examples/Makefile.am new file mode 100755 index 0000000..812919f --- /dev/null +++ b/examples/Makefile.am @@ -0,0 +1,10 @@ +noinst_PROGRAMS = vector_adapter_ex1 file_adapter_ex2 + +INCLUDES = -I../src/ + +vector_adapter_ex1_LDADD = ../src/libcmph.la +vector_adapter_ex1_SOURCES = vector_adapter_ex1.c + +file_adapter_ex2_LDADD = ../src/libcmph.la +file_adapter_ex2_SOURCES = file_adapter_ex2.c + diff --git a/examples/file_adapter_ex2.c b/examples/file_adapter_ex2.c new file mode 100644 index 0000000..57ec5b6 --- /dev/null +++ b/examples/file_adapter_ex2.c @@ -0,0 +1,32 @@ +#include +#include + + // Create minimal perfect hash function from in-disk keys using BMZ algorithm +int main(int argc, char **argv) +{ + //Open file with newline separated list of keys + FILE * keys_fd = fopen("keys.txt", "r"); + cmph_t *hash = NULL; + if (keys_fd == NULL) + { + fprintf(stderr, "File \"keys.txt\" not found\n"); + exit(1); + } + // Source of keys + cmph_io_adapter_t *source = cmph_io_nlfile_adapter(keys_fd); + + cmph_config_t *config = cmph_config_new(source); + cmph_config_set_algo(config, CMPH_BMZ); + hash = cmph_new(config); + cmph_config_destroy(config); + + //Find key + const char *key = "jjjjjjjjjj"; + unsigned int id = cmph_search(hash, key, strlen(key)); + fprintf(stderr, "Id:%u\n", id); + //Destroy hash + cmph_destroy(hash); + free(source); + fclose(keys_fd); + return 0; +} diff --git a/examples/keys.txt b/examples/keys.txt new file mode 100644 index 0000000..e1edd7c --- /dev/null +++ b/examples/keys.txt @@ -0,0 +1,10 @@ +aaaaaaaaaa +bbbbbbbbbb +cccccccccc +dddddddddd +eeeeeeeeee +ffffffffff +gggggggggg +hhhhhhhhhh +iiiiiiiiii +jjjjjjjjjj diff --git a/examples/vector_adapter_ex1.c b/examples/vector_adapter_ex1.c new file mode 100755 index 0000000..1ae8abb --- /dev/null +++ b/examples/vector_adapter_ex1.c @@ -0,0 +1,26 @@ +#include + +// Create minimal perfect hash function from in-memory vector +int main(int argc, char **argv) +{ + // Creating a filled vector + const char *vector[] = {"aaaaaaaaaa", "bbbbbbbbbb", "cccccccccc", "dddddddddd", "eeeeeeeeee", + "ffffffffff", "gggggggggg", "hhhhhhhhhh", "iiiiiiiiii", "jjjjjjjjjj"}; + unsigned int nkeys = 10; + // Source of keys + cmph_io_adapter_t *source = cmph_io_vector_adapter(vector, nkeys); + + //Create minimal perfect hash function using the default (chm) algorithm. + cmph_config_t *config = cmph_config_new(source); + cmph_t *hash = cmph_new(config); + cmph_config_destroy(config); + + //Find key + const char *key = "jjjjjjjjjj"; + unsigned int id = cmph_search(hash, key, strlen(key)); + fprintf(stderr, "Id:%u\n", id); + //Destroy hash + cmph_destroy(hash); + free(source); + return 0; +} diff --git a/src/cmph.c b/src/cmph.c index 490db0e..18ac502 100644 --- a/src/cmph.c +++ b/src/cmph.c @@ -12,6 +12,8 @@ const char *cmph_names[] = { "bmz", "chm", NULL }; /* included -- Fabiano */ +static cmph_uint32 position; // access position when data is a vector + static int key_nlfile_read(void *data, char **key, cmph_uint32 *keylen) { FILE *fd = (FILE *)data; @@ -37,16 +39,34 @@ static int key_nlfile_read(void *data, char **key, cmph_uint32 *keylen) return *keylen; } +static int key_vector_read(void *data, char **key, cmph_uint32 *keylen) +{ + char **keys = (char **)data; + if (keys + position == NULL) return -1; + *keylen = strlen(*(keys + position)); + *key = (char *)malloc(*keylen); + strcpy(*key, *(keys + position)); + position ++; + return *keylen; +} + + static void key_nlfile_dispose(void *data, char *key, cmph_uint32 keylen) { free(key); } + static void key_nlfile_rewind(void *data) { FILE *fd = (FILE *)data; rewind(fd); } +static void key_vector_rewind(void *data) +{ + position = 0; +} + static cmph_uint32 count_nlfile_keys(FILE *fd) { cmph_uint32 count = 0; @@ -89,7 +109,14 @@ cmph_io_adapter_t *cmph_io_nlnkfile_adapter(FILE * keys_fd, cmph_uint32 nkeys) cmph_io_adapter_t *cmph_io_vector_adapter(const char ** vector, cmph_uint32 nkeys) { - return NULL; + cmph_io_adapter_t * key_source = malloc(sizeof(cmph_io_adapter_t)); + assert(key_source); + key_source->data = (void *)vector; + key_source->nkeys = nkeys; + key_source->read = key_vector_read; + key_source->dispose = key_nlfile_dispose; + key_source->rewind = key_vector_rewind; + return key_source; } cmph_config_t *cmph_config_new(cmph_io_adapter_t *key_source) diff --git a/src/cmph.h b/src/cmph.h index f457736..a7de997 100644 --- a/src/cmph.h +++ b/src/cmph.h @@ -27,7 +27,7 @@ typedef struct /* please call free() in the created adapters */ cmph_io_adapter_t *cmph_io_nlfile_adapter(FILE * keys_fd); cmph_io_adapter_t *cmph_io_nlnkfile_adapter(FILE * keys_fd, cmph_uint32 nkeys); -/*cmph_io_adapter_t *cmph_io_vector_adapter(const char ** vector, cmph_uint32 nkeys);*/ +cmph_io_adapter_t *cmph_io_vector_adapter(const char ** vector, cmph_uint32 nkeys); /** Hash configuration API **/ cmph_config_t *cmph_config_new(cmph_io_adapter_t *key_source);