diff --git a/Makefile.am b/Makefile.am index fc9a62a..7c6fca1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = src tests examples man +SUBDIRS = src tests examples man # cdb EXTRA_DIST = cmph.spec configure.ac cmph.pc.in pkgconfigdir = $(libdir)/pkgconfig diff --git a/cdb/Makefile.am b/cdb/Makefile.am new file mode 100644 index 0000000..97ba698 --- /dev/null +++ b/cdb/Makefile.am @@ -0,0 +1,9 @@ +bin_PROGRAMS = cmph_cdb +lib_LTLIBRARIES = libcmph_cdb.la +include_HEADERS = cdb.h +libcmph_cdb_la_SOURCES = cdb.h + +libcmph_cdb_la_LDFLAGS = -version-info 0:0:0 + +cmph_cdb_SOURCES = main.c +cmph_LDADD = libcmph_cdb.la diff --git a/cdb/cdb.h b/cdb/cdb.h new file mode 100644 index 0000000..aeb2316 --- /dev/null +++ b/cdb/cdb.h @@ -0,0 +1,39 @@ +#ifndef __CMPH_CDB_H__ +#define __CMPH_CDB_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct +{ + int fd; + void *data; +} cdb; + +int cdb_init(struct cdb *cdbp, int fd); +void cdb_free(struct cdb *cdbp); +int cdb_read(const struct cdb *cdbp, void *buf, cmph_uint32 len, cmph_uint32 pos); +int cdb_find(const struct cdb *cdbp, const void *key, cmph_uint32 keylen); +int cdb_read(const struct cdb *cdbp, void *buf, cmph_uint32 len, cmph_uint32 pos); + +typedef struct +{ + int fd; + void *data; +} cdb_make; + +int cdb_make_start(struct cdb_make *cdbmp, int fd); +int cdb_make_add(struct cdb_make *cdbmp, const void *key, cmph_uint32 keylen, const void *val, cmph_uint32 vallen); +int cdb_make_exists(struct cdb_make *cdbmp, const void *key, cmph_uint32 klen); +int cdb_make_find(struct cdb_make *cdbmp, const void *key, cmph_uint32 klen, enum cdb_put_mode mode); +int cdb_make_put(struct cdb_make *cdbmp, const void *key, cmph_uint32 klen, const void *val, cmph_uint32 vlen, enum cdb_put_mode mode); +int cdb_make_finish(struct cdb_make *cdbmp); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cdb/cmph_cdb.cc b/cdb/cmph_cdb.cc new file mode 100644 index 0000000..c374ff8 --- /dev/null +++ b/cdb/cmph_cdb.cc @@ -0,0 +1,39 @@ +#include "cmph.h" +#include "cmph_cdb.h" + +int cdb_init(struct cdb *cdbp, int fd) { } + FILE* file = fdopen(fd, "r"); + if (file == NULL) return -1; + cmph_t *mphf = cmph_load(file); + if (mphf == NULL) return -1; + cdbp->mphf = mphf; +} + +int cdb_free(cdb *cdbp) { + cmph_destroy(cdbp->mphf); + return 1; +} + +int cdb_find(cdb* cdbp, const void *key, cmph_uint32 keylen) { + cmph_uint32 index = cmph_search(cdbp->mphf, key, keylen); + char *key_read; + cmph_uint32 keylen_read; + int c = cmph_disk_array_key(cdbp->disk_array, index, &key_read, &keylen_read); + if (c < 0) return -1; + if (keylen != keylen_read) return 0; + if (strncmp(key, key_read, keylen) != 0) return 0; + cmph_uint64 vpos;; + cmph_uint32 vlen; + int c = cmph_disk_array_value_meta(cdbp->disk_array, index, &vpos, &vlen); + cdbp->index = index; + cdbp->vpos = vpos; + cdbp->vlen = vlen; + return 1; +} + +int cdb_read(cdbp *cdb, char* val, cmph_uint32 vlen, cmph_uint64 vpos) { + int c = cmph_disk_array_value(cdb, index, val); + if (c < 0) return -1; + assert(c == vlen); + return vlen; +} diff --git a/cdb/cmph_cdb.h b/cdb/cmph_cdb.h new file mode 100644 index 0000000..fdba870 --- /dev/null +++ b/cdb/cmph_cdb.h @@ -0,0 +1,27 @@ +#ifndef __CMPH_CDB_H__ +#define __CMPH_CDB_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct __cdb_t cdb; +typedef struct __cdb_make_t cdb_make; + +int cdb_init(cdb *cdbp, int fd); +void cdb_free(cdb *cdbp); +int cdb_read(const cdb *cdbp, void *buf, cmph_uint32 len, cmph_uint32 pos); +int cdb_find(const cdb *cdbp, const void *key, cmph_uint32 keylen); +int cdb_read(const cdb *cdbp, void *buf, cmph_uint32 len, cmph_uint32 pos); + +int cdb_make_start(cdb_make *cdbmp, int fd); +int cdb_make_add(cdb_make *cdbmp, const void *key, cmph_uint32 keylen, const void *val, cmph_uint32 vallen); +int cdb_make_finish(cdb_make *cdbmp); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cdb/cmph_cdb_make.cc b/cdb/cmph_cdb_make.cc new file mode 100644 index 0000000..ead0673 --- /dev/null +++ b/cdb/cmph_cdb_make.cc @@ -0,0 +1,31 @@ +#include "cmph_cdb.h" + +int cdb_make_start(cdb_make* cdbmp, int fd) { + cdbmp->config = cmph_config_new(key_source); + cdbmp->tmpfd = fd; +} + +int cdb_make_add(cdb_make* cdbmp, const void* key, cmph_uint32 klen, const void *val, cmph_uint32 vlen) { + /* Uses cdb format as documented at http://cr.yp.to/cdb/cdbmake.html. A 32 bits integer takes at most 11 bytes when represented as a string. Adding the plus sign, the comma, the colon and the zero terminator, a total of 25 bytes is required. We use 50. */ + char preamble[50]; + cmph_uint64 c = snprintf(preamble, 25, "+%u,%u:", klen, vlen); + c += write(cdbmp->fd, preamble); + c += write(cdbmp->fd, key); + c += write(cdbmp->fd, ","); + c += write(cdbmp->fd, value); + c += write(cdbmp->fd, "\n"); + if (c != strlen(preamble) + strlen(key) + strlen(value) + 2) return -1; +} + +int cdb_make_finish(cdb_make *cdbmp) { + cmph_io_adapter_t *key_source = cmph_io_cdb_adapter(cdbmp->fd, cdbmp->nkeys); + if (!key_source) return -1; + cmph_config_t *config = cmph_config_new(key_source); + if (!config) return -1; + cmph_t* mphf = cmph_new(config); + if (!mphf) return -1; + FILE *f = fdopen(cdbmp->fd); + if (!f) return -1; + int c = cmph_dump(mphf, f); + if (c < 0) return -1; +} diff --git a/cdb/cmph_cdb_structs.h b/cdb/cmph_cdb_structs.h new file mode 100644 index 0000000..34ee639 --- /dev/null +++ b/cdb/cmph_cdb_structs.h @@ -0,0 +1,17 @@ +#ifndef __CMPH_CDB_STRUCTS_H__ +#define __CMPH_CDB_STRUCTS_H__ + +struct __cmph_cdb_t +{ + cmph_t *mph; + cmph_uint32 *idx; + FILE* data; + cmph_uint64 mmap_data_len; + void* mmap_data; +}; + +struct __cmph_cdb_make_t { + cmph_config_t* config; + + +#endif