summaryrefslogtreecommitdiffstats
path: root/common/storage_lmdb.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/storage_lmdb.cpp')
-rw-r--r--common/storage_lmdb.cpp54
1 files changed, 31 insertions, 23 deletions
diff --git a/common/storage_lmdb.cpp b/common/storage_lmdb.cpp
index 13a6853..f0a5bc0 100644
--- a/common/storage_lmdb.cpp
+++ b/common/storage_lmdb.cpp
@@ -52,9 +52,11 @@ public:
52 bool readTransaction; 52 bool readTransaction;
53 bool firstOpen; 53 bool firstOpen;
54 static QMutex sMutex; 54 static QMutex sMutex;
55 static QHash<QString, MDB_env*> sEnvironments;
55}; 56};
56 57
57QMutex Storage::Private::sMutex; 58QMutex Storage::Private::sMutex;
59QHash<QString, MDB_env*> Storage::Private::sEnvironments;
58 60
59Storage::Private::Private(const QString &s, const QString &n, AccessMode m) 61Storage::Private::Private(const QString &s, const QString &n, AccessMode m)
60 : storageRoot(s), 62 : storageRoot(s),
@@ -70,23 +72,30 @@ Storage::Private::Private(const QString &s, const QString &n, AccessMode m)
70 dir.mkpath(storageRoot); 72 dir.mkpath(storageRoot);
71 dir.mkdir(fullPath); 73 dir.mkdir(fullPath);
72 74
73 //This seems to resolve threading related issues, not sure why though 75 //Ensure the environment is only created once
74 QMutexLocker locker(&sMutex); 76 QMutexLocker locker(&sMutex);
75 77
76 //create file 78 int rc = 0;
77 if (mdb_env_create(&env)) { 79 /*
78 // TODO: handle error 80 * It seems we can only ever have one environment open in the process.
79 } else { 81 * Otherwise multi-threading breaks.
80 int rc = mdb_env_open(env, fullPath.toStdString().data(), 0, 0664); 82 */
81 83 env = sEnvironments.value(fullPath);
82 if (rc) { 84 if (!env) {
83 std::cerr << "mdb_env_open: " << rc << " " << mdb_strerror(rc) << std::endl; 85 if ((rc = mdb_env_create(&env))) {
84 mdb_env_close(env); 86 // TODO: handle error
85 env = 0; 87 std::cerr << "mdb_env_create: " << rc << " " << mdb_strerror(rc) << std::endl;
86 } else { 88 } else {
87 //FIXME: dynamic resize 89 if ((rc = mdb_env_open(env, fullPath.toStdString().data(), 0, 0664))) {
88 const size_t dbSize = (size_t)10485760 * (size_t)100 * (size_t)80; //10MB * 800 90 std::cerr << "mdb_env_open: " << rc << " " << mdb_strerror(rc) << std::endl;
89 mdb_env_set_mapsize(env, dbSize); 91 mdb_env_close(env);
92 env = 0;
93 } else {
94 //FIXME: dynamic resize
95 const size_t dbSize = (size_t)10485760 * (size_t)100 * (size_t)80; //10MB * 800
96 mdb_env_set_mapsize(env, dbSize);
97 sEnvironments.insert(fullPath, env);
98 }
90 } 99 }
91 } 100 }
92} 101}
@@ -97,11 +106,12 @@ Storage::Private::~Private()
97 mdb_txn_abort(transaction); 106 mdb_txn_abort(transaction);
98 } 107 }
99 108
100 // it is still there and still unused, so we can shut it down 109 //Since we can have only one environment open per process, we currently leak the environments.
101 if (env) { 110 // if (env) {
102 mdb_dbi_close(env, dbi); 111 // //mdb_dbi_close should not be necessary and is potentially dangerous (see docs)
103 mdb_env_close(env); 112 // mdb_dbi_close(env, dbi);
104 } 113 // mdb_env_close(env);
114 // }
105} 115}
106 116
107Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode) 117Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode)
@@ -292,7 +302,7 @@ void Storage::scan(const char *keyData, uint keySize,
292 302
293 rc = mdb_cursor_open(d->transaction, d->dbi, &cursor); 303 rc = mdb_cursor_open(d->transaction, d->dbi, &cursor);
294 if (rc) { 304 if (rc) {
295 Error error(d->name.toStdString(), rc, mdb_strerror(rc)); 305 Error error(d->name.toStdString(), rc, std::string("Error during mdb_cursor open: ") + mdb_strerror(rc));
296 errorHandler(error); 306 errorHandler(error);
297 return; 307 return;
298 } 308 }
@@ -314,15 +324,13 @@ void Storage::scan(const char *keyData, uint keySize,
314 } else { 324 } else {
315 if ((rc = mdb_cursor_get(cursor, &key, &data, MDB_SET)) == 0) { 325 if ((rc = mdb_cursor_get(cursor, &key, &data, MDB_SET)) == 0) {
316 resultHandler(key.mv_data, key.mv_size, data.mv_data, data.mv_size); 326 resultHandler(key.mv_data, key.mv_size, data.mv_data, data.mv_size);
317 } else {
318 std::cout << "couldn't find value " << std::string(keyData, keySize) << std::endl;
319 } 327 }
320 } 328 }
321 329
322 mdb_cursor_close(cursor); 330 mdb_cursor_close(cursor);
323 331
324 if (rc) { 332 if (rc) {
325 Error error(d->name.toStdString(), rc, mdb_strerror(rc)); 333 Error error(d->name.toStdString(), rc, std::string("Key: ") + std::string(keyData, keySize) + " : " + mdb_strerror(rc));
326 errorHandler(error); 334 errorHandler(error);
327 } 335 }
328 336