#include "lmdb-safe.hh" #include #include #include #include #include #include std::shared_ptr getMDBEnv(const char* fname, int mode, int flags) { struct Value { weak_ptr wp; int flags; }; static std::map, Value> s_envs; static std::mutex mut; struct stat statbuf; if(stat(fname, &statbuf)) { if(errno != ENOENT) throw std::runtime_error("Unable to stat prospective mdb database: "+string(strerror(errno))); else { std::lock_guard l(mut); cout<<"Making a fresh one, file did not exist yet"<(fname, mode, flags); if(stat(fname, &statbuf)) throw std::runtime_error("Unable to stat prospective mdb database: "+string(strerror(errno))); auto key = std::tie(statbuf.st_dev, statbuf.st_ino); s_envs[key] = {fresh, flags}; return fresh; } } std::lock_guard l(mut); auto key = std::tie(statbuf.st_dev, statbuf.st_ino); auto iter = s_envs.find(key); if(iter != s_envs.end()) { cout<<"Found something!"<second.wp.lock(); if(sp) { if(iter->second.flags != flags) throw std::runtime_error("Can't open mdb with differing flags"); cout<<"It was live!"<(fname, mode, flags); s_envs[key] = {fresh, flags}; return fresh; } MDBDbi MDBEnv::openDB(const char* dbname, int flags) { unsigned int envflags; mdb_env_get_flags(d_env, &envflags); if(!(envflags & MDB_RDONLY)) { auto rwt = getRWTransaction(); MDBDbi ret = rwt.openDB(dbname, flags); rwt.commit(); return ret; } auto rwt = getROTransaction(); return rwt.openDB(dbname, flags); } MDBRWCursor MDBRWTransaction::getCursor(const MDBDbi& dbi) { return MDBRWCursor(this, dbi); } MDBROTransaction MDBEnv::getROTransaction() { return MDBROTransaction(this); } MDBRWTransaction MDBEnv::getRWTransaction() { return MDBRWTransaction(this); } void MDBRWTransaction::closeCursors() { for(auto& c : d_cursors) c->close(); d_cursors.clear(); } MDBROCursor MDBROTransaction::getCursor(const MDBDbi& dbi) { return MDBROCursor(this, dbi); }