diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/storage_lmdb.cpp | 54 |
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 | ||
57 | QMutex Storage::Private::sMutex; | 58 | QMutex Storage::Private::sMutex; |
59 | QHash<QString, MDB_env*> Storage::Private::sEnvironments; | ||
58 | 60 | ||
59 | Storage::Private::Private(const QString &s, const QString &n, AccessMode m) | 61 | Storage::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 | ||
107 | Storage::Storage(const QString &storageRoot, const QString &name, AccessMode mode) | 117 | Storage::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 | ||