Skip to content
19 changes: 12 additions & 7 deletions cpp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,30 @@ NEGENTROPY_ROOT := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
INCS = -I$(NEGENTROPY_ROOT) -I/opt/homebrew/include/ -I$(NEGENTROPY_ROOT)/vendor/lmdbxx/include/

ifeq ($(OS),Windows_NT)
TARGET = negentropy.dll
TARGET = libnegentropy.dll
else
TARGET = libnegentropy.so
TARGET = libnegentropy.a
endif

.PHONY: all clean install-deps precompiled-header shared-lib
.PHONY: all clean install-deps precompiled-header build-lib

all: precompiled-header shared-lib
all: precompiled-header build-lib

#TODO: Need to add compilation flags based on OS
install-deps:
brew install lmdb openssl

# Generate 'negentropy.h.gch'
precompiled-header:
g++ -O0 --std=c++20 -Wall -fexceptions -g $(NEGENTROPY_ROOT)negentropy.h $(INCS)
g++ -x c++-header -O0 --std=c++20 -Wall -fexceptions -g -o $(NEGENTROPY_ROOT)negentropy.h.gch $(NEGENTROPY_ROOT)negentropy.h $(INCS)

shared-lib:
build-lib:
ifeq ($(OS),Windows_NT)
g++ -O0 -g -std=c++20 $(INCS) -shared -fPIC -o $(TARGET) $(NEGENTROPY_ROOT)negentropy_wrapper.cpp -lcrypto -lssl -L/opt/homebrew/lib/
else
g++ -O0 -g -std=c++20 $(INCS) -fPIC -c negentropy_wrapper.cpp
ar rcs $(TARGET) negentropy_wrapper.o
endif

clean:
rm -f $(TARGET) negentropy.h.gch libnegentropy.so
rm -f $(TARGET) negentropy.h.gch *.o
92 changes: 55 additions & 37 deletions cpp/negentropy_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
//This is a C-wrapper for the C++ library that helps in integrating negentropy with nim code.
//TODO: Do error handling by catching exceptions

thread_local std::string lastError;
EXTERNC const char* get_last_error() {
return lastError.c_str();
}

void printHexString(std::string_view toPrint){
for (size_t i = 0; i < toPrint.size(); ++i) {
printf("%0hhx", toPrint[i]);
Expand All @@ -18,20 +23,27 @@ void printHexString(std::string_view toPrint){

void* storage_new(const char* db_path, const char* name){
negentropy::storage::BTreeMem* storage;
/*
auto env = lmdb::env::create();
env.set_max_dbs(64);
env.open(db_path, 0);
try {
/*
auto env = lmdb::env::create();
env.set_max_dbs(64);
env.open(db_path, 0);

lmdb::dbi btreeDbi;
lmdb::dbi btreeDbi;

{
auto txn = lmdb::txn::begin(env);
btreeDbi = negentropy::storage::BTreeMem::setupDB(txn, name);
txn.commit();
} */
{
auto txn = lmdb::txn::begin(env);
btreeDbi = negentropy::storage::BTreeMem::setupDB(txn, name);
txn.commit();
}
*/

storage = new negentropy::storage::BTreeMem();
} catch (const std::exception& e) {
lastError = e.what();
return nullptr;
}

storage = new negentropy::storage::BTreeMem();
return storage;
}

Expand Down Expand Up @@ -60,8 +72,8 @@ void* negentropy_new(void* storage, uint64_t frameSizeLimit){
try{
ne = new Negentropy<negentropy::storage::BTreeMem>(*lmdbStorage, frameSizeLimit);
}catch(negentropy::err e){
//TODO: Error handling
return NULL;
lastError = e.what();
return nullptr;
}
return ne;
}
Expand All @@ -78,7 +90,7 @@ int negentropy_initiate(void* negentropy, result* result){
printHexString(std::string_view(*output)); */
} catch(negentropy::err e){
//std::cout << "Exception raised in initiate " << e.what() << std::endl;
//TODO: Error handling
lastError = e.what();
return -1;
}
if (output.size() > 0 ){
Expand All @@ -104,25 +116,32 @@ bool storage_insert(void* storage, uint64_t createdAt, buffer* id){
negentropy::storage::BTreeMem* lmdbStorage;
lmdbStorage = reinterpret_cast<negentropy::storage::BTreeMem*>(storage);
std::string_view data(reinterpret_cast< char const* >(id->data), id->len);
/* std::cout << "inserting entry in storage, createdAt:" << createdAt << ",id:";

/* std::cout << "inserting entry in storage, createdAt:" << createdAt << ",id:";
printHexString(data); */

//TODO: Error handling. Is it required?
//How does out of memory get handled?
return lmdbStorage->insert(createdAt, data);

try {
return lmdbStorage->insert(createdAt, data);
} catch (const std::exception& e) {
lastError = e.what();
return false;
}
}

bool storage_erase(void* storage, uint64_t createdAt, buffer* id){
negentropy::storage::BTreeMem* lmdbStorage;
lmdbStorage = reinterpret_cast<negentropy::storage::BTreeMem*>(storage);
std::string_view data(reinterpret_cast< char const* >(id->data), id->len);

/* std::cout << "erasing entry from storage, createdAt:" << createdAt << ",id:";
/* std::cout << "erasing entry from storage, createdAt:" << createdAt << ",id:";
printHexString(data); */

//TODO: Error handling
return lmdbStorage->erase(createdAt, data);

try {
return lmdbStorage->erase(createdAt, data);
} catch (const std::exception& e) {
lastError = e.what();
return false;
}
}

int reconcile(void* negentropy, buffer* query, result* result){
Expand All @@ -136,7 +155,7 @@ int reconcile(void* negentropy, buffer* query, result* result){
} catch(negentropy::err e){
//All errors returned are non-recoverable errors.
//So passing on the error message upwards
//std::cout << "Exception raised in reconcile " << e.what() << std::endl;
lastError = e.what();
result->error = (char*)calloc(strlen(e.what()), sizeof(char));
strcpy(result->error,e.what());
return -1;
Expand All @@ -154,7 +173,7 @@ int reconcile(void* negentropy, buffer* query, result* result){

void transform(std::vector<std::string> &from_ids, buffer* to_ids)
{
for (int i=0; i < from_ids.size(); i ++){
for (int i=0; i < from_ids.size(); i ++){
to_ids[i].len = from_ids[i].size();
to_ids[i].data = (unsigned char*)from_ids[i].c_str();
}
Expand Down Expand Up @@ -204,7 +223,7 @@ int reconcile_with_ids(void* negentropy, buffer* query,reconcile_cbk cbk, char*
free(have_ids);
free(need_ids);
return 0;
}
}

void transform_with_alloc(std::vector<std::string> &from_ids, buffer* to_ids)
{
Expand Down Expand Up @@ -239,11 +258,11 @@ int reconcile_with_ids_no_cbk(void* negentropy, buffer* query, result* result){


} catch(negentropy::err e){
std::cout << "caught error "<< e.what() << std::endl;
result->error = (char*)calloc(strlen(e.what()), sizeof(char));
strcpy(result->error,e.what());
lastError = e.what();
result->error = strdup(e.what());
return -1;
}

buffer output = {0,NULL};
if (out) {
result->output.len = out.value().size();
Expand All @@ -264,7 +283,7 @@ void free_result(result* r){
if (r->output.len > 0) {
free((void *) r->output.data);
}

if (r->have_ids_len > 0){
for (int i = 0; i < r->have_ids_len; i++) {
free((void *) r->have_ids[i].data);
Expand Down Expand Up @@ -293,7 +312,7 @@ void* subrange_new(void* storage, uint64_t startTimeStamp, uint64_t endTimeStamp
try {
subRange = new negentropy::storage::SubRange(*st, negentropy::Bound(startTimeStamp), negentropy::Bound(endTimeStamp));
} catch (negentropy::err e){
//TODO: Error handling
lastError = e.what();
return NULL;
}
return subRange;
Expand Down Expand Up @@ -324,7 +343,7 @@ void* negentropy_subrange_new(void* subrange, uint64_t frameSizeLimit){
try{
ne = new Negentropy<negentropy::storage::SubRange>(*sub_range, frameSizeLimit);
}catch(negentropy::err e){
//TODO: Error handling
lastError = e.what();
return NULL;
}
return ne;
Expand All @@ -341,7 +360,7 @@ int negentropy_subrange_initiate(void* negentropy, result* result){
/* std::cout << "output of initiate is, len:" << output->size() << ", output:";
printHexString(std::string_view(*output)); */
} catch(negentropy::err e){
//std::cout << "Exception raised in initiate " << e.what() << std::endl;
lastError = e.what();
return -1;
}
if (output.size() > 0 ){
Expand Down Expand Up @@ -374,7 +393,7 @@ int reconcile_subrange(void* negentropy, buffer* query, result* result){
} catch(negentropy::err e){
//All errors returned are non-recoverable errors.
//So passing on the error message upwards
//std::cout << "Exception raised in reconcile " << e.what() << std::endl;
lastError = e.what();
result->error = (char*)calloc(strlen(e.what()), sizeof(char));
strcpy(result->error,e.what());
return -1;
Expand Down Expand Up @@ -414,7 +433,7 @@ int reconcile_with_ids_subrange_no_cbk(void* negentropy, buffer* query, result*


} catch(negentropy::err e){
std::cout << "caught error "<< e.what() << std::endl;
lastError = e.what();
result->error = (char*)calloc(strlen(e.what()), sizeof(char));
strcpy(result->error,e.what());
return -1;
Expand All @@ -433,4 +452,3 @@ int reconcile_with_ids_subrange_no_cbk(void* negentropy, buffer* query, result*
}
return 0;
}

2 changes: 2 additions & 0 deletions cpp/negentropy_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ typedef struct _result_ {
//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 const char* get_last_error();

EXTERNC void* storage_new(const char* db_path, const char* name);

EXTERNC void storage_delete(void* storage);
Expand Down