diff --git a/cpp/Makefile b/cpp/Makefile index c561c11..c40517c 100644 --- a/cpp/Makefile +++ b/cpp/Makefile @@ -6,20 +6,18 @@ TARGET = libnegentropy.so .PHONY: all clean install-deps -all: negentropy-cpp c-wrapper shared-lib +all: precompiled-header shared-lib #TODO: Need to add compilation flags based on OS install-deps: brew install lmdb openssl -shared-lib: negentropy.o - g++ -shared -fPIC -o $(TARGET) negentropy.o negentropy_wrapper.o +# Generate 'negentropy.h.gch' +precompiled-header: + g++ --std=c++20 -Wall -fexceptions -g negentropy.h -I./ -I./vendor/lmdbxx/include/ -negentropy-cpp: - g++ negentropy.h --std=c++20 -o negentropy.o $(INCS) - -c-wrapper: - g++ negentropy_wrapper.h --std=c++20 -o negentropy_wrapper.o $(INCS) -I./vendor/lmdbxx/include/ +shared-lib: negentropy.h.gch + g++ --std=c++20 -I./ -I./vendor/lmdbxx/include/ -shared -fPIC -o $(TARGET) negentropy_wrapper.c clean: - rm -f negentropy.o negentropy_wrapper.o libnegentropy.so + rm -f $(TARGET) negentropy.h.gch libnegentropy.so diff --git a/cpp/negentropy_wrapper.c b/cpp/negentropy_wrapper.c new file mode 100644 index 0000000..c2d18a1 --- /dev/null +++ b/cpp/negentropy_wrapper.c @@ -0,0 +1,121 @@ + +#include "negentropy_wrapper.h" + +//This is a C-wrapper for the C++ library that helps in integrating negentropy with nim code. +//TODO: Do error handling by catching exceptions + +void* storage_new(const char* db_path, const char* name){ + negentropy::storage::BTreeLMDB* storage; +/* + auto env = lmdb::env::create(); + env.set_max_dbs(64); + env.open(db_path, 0); + + lmdb::dbi btreeDbi; + + { + auto txn = lmdb::txn::begin(env); + btreeDbi = negentropy::storage::BTreeLMDB::setupDB(txn, name); + txn.commit(); + } */ + //TODO: Finish constructor + //storage = new negentropy::storage::BTreeLMDB(); + return storage; +} + +void* negentropy_new(void* storage, uint64_t frameSizeLimit){ + //TODO: Make these typecasts into macros?? + negentropy::storage::BTreeLMDB* lmdbStorage; + //TODO: reinterpret cast is risky, need to use more safe type conversion. + lmdbStorage = reinterpret_cast(storage); + + Negentropy* ne; + try{ + ne = new Negentropy(*lmdbStorage, frameSizeLimit); + }catch(negentropy::err e){ + //TODO:Find a way to return this error + return NULL; + } + return ne; +} + +const char* negentropy_initiate(void* negentropy){ + Negentropy* ngn_inst; + ngn_inst = reinterpret_cast*>(negentropy); + + std::string* output = new std::string(); + try { + *output = ngn_inst->initiate(); + } catch(negentropy::err e){ + //TODO:Find a way to return this error + return NULL; + } + return output->c_str(); +} + +void negentropy_setinitiator(void* negentropy){ + Negentropy *ngn_inst; + ngn_inst = reinterpret_cast*>(negentropy); + + ngn_inst->setInitiator(); + +} + + +bool storage_insert(void* storage, uint64_t createdAt, const char* id){ + negentropy::storage::BTreeLMDB* lmdbStorage; + lmdbStorage = reinterpret_cast(storage); + + //TODO: Error handling. Is it required? + //How does out of memory get handled? + return lmdbStorage->insert(createdAt, id); +} + + +bool storage_erase(void* storage, uint64_t createdAt, const char* id){ + negentropy::storage::BTreeLMDB* lmdbStorage; + lmdbStorage = reinterpret_cast(storage); + + //TODO: Error handling + return lmdbStorage->erase(createdAt, id); +} + + +const char* reconcile(void* negentropy, const char* query){ + Negentropy *ngn_inst; + ngn_inst = reinterpret_cast*>(negentropy); + + std::string* output = new std::string(); + try { + *output = ngn_inst->reconcile(std::string_view(query)); + } catch(negentropy::err e){ + //TODO:Find a way to return this error + return NULL; + } + return output->c_str(); +} + +const char* reconcile_with_ids(void* negentropy, const char* query, const char* have_ids[], + uint64_t have_ids_len, const char* need_ids[], uint64_t need_ids_len){ + Negentropy *ngn_inst; + ngn_inst = reinterpret_cast*>(negentropy); + + std::optional* output; + std::vector haveIds(have_ids, have_ids+have_ids_len); + + std::vector needIds(need_ids, need_ids+need_ids_len); + + try { + *output = ngn_inst->reconcile(std::string_view(query), haveIds, needIds); + } catch(negentropy::err e){ + //TODO:Find a way to return this error + return NULL; + } + if (output->has_value()) { + //TODO: Figure out diff between error and this. + return NULL; + }else { + + return output->value().c_str(); + } +} \ No newline at end of file diff --git a/cpp/negentropy_wrapper.h b/cpp/negentropy_wrapper.h index f766da2..e18ab5f 100644 --- a/cpp/negentropy_wrapper.h +++ b/cpp/negentropy_wrapper.h @@ -1,132 +1,31 @@ -#pragma once -#ifdef __cplusplus -#define EXTERNC extern "C" -#else -#define EXTERNC -#endif +#ifndef _NEGENTROPY_WRAPPER_H +#define _NEGENTROPY_WRAPPER_H #include "negentropy.h" #include "negentropy/storage/BTreeLMDB.h" - #define length(array) ((sizeof(array)) / (sizeof(array[0]))) //This is a C-wrapper for the C++ library that helps in integrating negentropy with nim code. //TODO: Do error handling by catching exceptions -EXTERNC void* storage_new(const char* db_path, const char* name){ - negentropy::storage::BTreeLMDB* storage; -/* - auto env = lmdb::env::create(); - env.set_max_dbs(64); - env.open(db_path, 0); +void* storage_new(const char* db_path, const char* name); - lmdb::dbi btreeDbi; +void* negentropy_new(void* storage, uint64_t frameSizeLimit); - { - auto txn = lmdb::txn::begin(env); - btreeDbi = negentropy::storage::BTreeLMDB::setupDB(txn, name); - txn.commit(); - } */ - //TODO: Finish constructor - //storage = new negentropy::storage::BTreeLMDB(); - return storage; -} +const char* negentropy_initiate(void* negentropy); -EXTERNC void* negentropy_new(void* storage, uint64_t frameSizeLimit){ - //TODO: Make these typecasts into macros?? - negentropy::storage::BTreeLMDB* lmdbStorage; - //TODO: reinterpret cast is risky, need to use more safe type conversion. - lmdbStorage = reinterpret_cast(storage); +void negentropy_setinitiator(void* negentropy); - Negentropy* ne; - try{ - ne = new Negentropy(*lmdbStorage, frameSizeLimit); - }catch(negentropy::err e){ - //TODO:Find a way to return this error - return NULL; - } - return ne; -} +bool storage_insert(void* storage, uint64_t createdAt, const char* id); -EXTERNC const char* negentropy_initiate(void* negentropy){ - Negentropy* ngn_inst; - ngn_inst = reinterpret_cast*>(negentropy); +bool storage_erase(void* storage, uint64_t createdAt, const char* id); - std::string* output = new std::string(); - try { - *output = ngn_inst->initiate(); - } catch(negentropy::err e){ - //TODO:Find a way to return this error - return NULL; - } - return output->c_str(); -} +const char* reconcile(void* negentropy, const char* query); -EXTERNC void negentropy_setinitiator(void* negentropy){ - Negentropy *ngn_inst; - ngn_inst = reinterpret_cast*>(negentropy); +const char* reconcile_with_ids(void* negentropy, const char* query, const char* have_ids[], + uint64_t have_ids_len, const char* need_ids[], uint64_t need_ids_len); - ngn_inst->setInitiator(); +#endif -} - - -EXTERNC bool storage_insert(void* storage, uint64_t createdAt, const char* id){ - negentropy::storage::BTreeLMDB* lmdbStorage; - lmdbStorage = reinterpret_cast(storage); - - //TODO: Error handling. Is it required? - //How does out of memory get handled? - return lmdbStorage->insert(createdAt, id); -} - - -EXTERNC bool storage_erase(void* storage, uint64_t createdAt, const char* id){ - negentropy::storage::BTreeLMDB* lmdbStorage; - lmdbStorage = reinterpret_cast(storage); - - //TODO: Error handling - return lmdbStorage->erase(createdAt, id); -} - - -EXTERNC const char* reconcile(void* negentropy, const char* query){ - Negentropy *ngn_inst; - ngn_inst = reinterpret_cast*>(negentropy); - - std::string* output = new std::string(); - try { - *output = ngn_inst->reconcile(std::string_view(query)); - } catch(negentropy::err e){ - //TODO:Find a way to return this error - return NULL; - } - return output->c_str(); -} - -EXTERNC const char* reconcile_with_ids(void* negentropy, const char* query, const char* have_ids[], - uint64_t have_ids_len, const char* need_ids[], uint64_t need_ids_len){ - Negentropy *ngn_inst; - ngn_inst = reinterpret_cast*>(negentropy); - - std::optional* output; - std::vector haveIds(have_ids, have_ids+have_ids_len); - - std::vector needIds(need_ids, need_ids+need_ids_len); - - try { - *output = ngn_inst->reconcile(std::string_view(query), haveIds, needIds); - } catch(negentropy::err e){ - //TODO:Find a way to return this error - return NULL; - } - if (output->has_value()) { - //TODO: Figure out diff between error and this. - return NULL; - }else { - - return output->value().c_str(); - } -} \ No newline at end of file