Open DrissiReda opened 5 years ago
You are calling dbi.del(wtxn, ...)
after you are calling wtxn.commit()
. Committing (or aborting) a transaction invalidates it. You can't then use it for subsequent operations. Either do the delete in the same transaction, or open a new transaction.
BTW: This repo is not really maintained anymore. I'll try to answer questions as best as possible here, but I have forked it for C++17 and will try to maintain that fork: https://github.com/hoytech/lmdbxx
is your fork compatible with C++11?
My fork requires a C++17 compiler since it uses std::string_view. However, C++11 code will I believe compile fine with a C++17 compiler.
Thanks, I'll look into it
Oh, and you asked about docs. You sort of have to use the LMDB C API docs: http://www.lmdb.tech/doc/
For examples of the C++ interface, you can checkout my test code, it has more working C++ examples than does this repo: https://github.com/hoytech/lmdbxx/blob/master/check.cc
Currently I'm limited to C++11, what you told me worked, but I have issues with dbi.get
now. If it doesn't find the entry, everything works normally, if it does find the entry, I have a segmentation fault on the call dbi.get
#include <cstdio>
#include <cstdlib>
#include <lmdb++.h>
using namespace lmdb;
int main() {
auto env = lmdb::env::create();
env.set_mapsize(1UL * 1024UL * 1024UL * 1024UL); /* 1 GiB */
env.open("./example.mdb", 0, 0664);
{
auto wtxn = lmdb::txn::begin(env);
auto dbi = lmdb::dbi::open(wtxn, nullptr);
dbi.put(wtxn, "email", "hello");
wtxn.commit();
}
{
auto rtxn = lmdb::txn::begin(env, nullptr, MDB_RDONLY);
auto mydb = lmdb::dbi::open(rtxn, nullptr);
std::string v;
mydb.get(rtxn, "email", v);
//std::printf("we found '%s'", v.c_str());
}
return EXIT_SUCCESS;
}
A snippet from valgrind:
==80114== Process terminating with default action of signal 11 (SIGSEGV)
==80114== Access not within mapped region at address 0x106F6C6C6560
==80114== at 0x510A02C: std::string::assign(std::string const&) (in /usr/lib64/libstdc++.so.6.0.19)
==80114== by 0x4020A3: bool lmdb::dbi::get<std::string>(MDB_txn*, char const*, std::string&) const (in /home/reda/lmdbxx-master/test)
==80114== by 0x40155E: main (in /home/reda/lmdbxx-master/test)
==80114== If you believe this happened as a result of a stack
==80114== overflow in your program's main thread (unlikely but
==80114== possible), you can try to increase the size of the
==80114== main thread stack using the --main-stacksize= flag.
==80114== The main thread stack size used in this run was 8388608.
A warning printed prior to the error that might be relevant:
==80114== Warning: set address range perms: large range [0x39602000, 0x79602000) (defined)
==80114== Invalid read of size 4
==80114== at 0x510A02C: std::string::assign(std::string const&) (in /usr/lib64/libstdc++.so.6.0.19)
==80114== by 0x4020A3: bool lmdb::dbi::get<std::string>(MDB_txn*, char const*, std::string&) const (in /home/reda/lmdbxx-master/test)
==80114== by 0x40155E: main (in /home/reda/lmdbxx-master/test)
==80114== Address 0x106f6c6c6560 is not stack'd, malloc'd or (recently) free'd
You are using the templated get method with std::string. Don't do that: https://github.com/drycpp/lmdbxx/issues/1
Use lmdb::val
instead. You can then construct an std::string
from that by copying the value from the DB.
using lmdb::val
gives an ambiguity error:
EDIT: nevermind, using an lmdb::val object for the key instead of a const char* fixed it.
You have to use it for the key too. Passing a const char* works in my fork because it implicitly creates a string_view.
I tried to simply delete an entry, and can't really know if I'm wrong or if this is a bug, the only documentation I could find was the api reference, if anyone has better material I'd be glad to take it.
This yields the following error :