Full_Name: Jonny Wilkes Version: 2.4.2 OS: Linux URL: ftp://ftp.openldap.org/incoming/ Submission from: (NULL) (67.160.82.31)
The following code shows key corruption.
I am probably using the API wrong, but I don't see how. I apologize in advance for not having a clue.
And now, on to the test. It can be compiled and run like so:
gcc t1.c -llmdb && ./a.out
--------- t1.c starts here --------- /*
The output of this program using liblmdb0 v0.9.21-1 on Ubuntu is:
--- dump --- key12345 key67890 --- dump --- key12345 y12345
Why? What happened to key67890?
*/
#include <lmdb.h> #if USE_SOURCE #include "midl.c" #include "mdb.c" #endif #include <stdio.h> #include <string.h> #include <unistd.h>
#define P(K) printf("%s\n", (char *)K.mv_data)
#define X(x) do { int _x = x; if (_x) fprintf(stderr, "%d %s\n", _x, mdb_strerror(_x)); } while (0)
const char *path = "/tmp/lmdb-why.tmp"; MDB_env *env;
/* * setup creates /tmp/lmdb-why.tmp with 2 keys with the data "hey": * * 1. key12345 : hey * 2. key67890 : hey */ int setup(void) { unlink(path); if (!env) { X(mdb_env_create(&env)); X(mdb_env_open(env, path, MDB_NOSUBDIR, 0664)); }
MDB_txn *txn; X(mdb_txn_begin(env, NULL, 0, &txn)); MDB_dbi dbi; X(mdb_dbi_open(txn, NULL, 0, &dbi));
const char *keys[] = { "key12345", "key67890" }; for (unsigned i = 0; i < 2; ++i) { MDB_val key, data; key.mv_data = (void *)keys[i]; key.mv_size = strlen(keys[i])+1; data.mv_data = "hey"; data.mv_size = 4; X(mdb_put(txn, dbi, &key, &data, 0)); } X(mdb_txn_commit(txn)); return 0; }
int dump(void) { printf("--- dump ---\n");
MDB_txn *txn; X(mdb_txn_begin(env, NULL, 0, &txn)); MDB_dbi dbi; X(mdb_dbi_open(txn, NULL, 0, &dbi)); MDB_cursor *cursor; X(mdb_cursor_open(txn, dbi, &cursor));
MDB_val key; int rc; while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT)) == 0) { P(key); }
mdb_cursor_close(cursor); if (MDB_NOTFOUND != rc) return rc; mdb_txn_abort(txn); return 0; }
/* * change_data change the data for each key to "there" using mdb_put. * After it completes, the keys are corrupt. */ int change_data(void) { MDB_txn *txn; X(mdb_txn_begin(env, NULL, 0, &txn)); MDB_dbi dbi; X(mdb_dbi_open(txn, NULL, 0, &dbi)); MDB_cursor *cursor; X(mdb_cursor_open(txn, dbi, &cursor));
MDB_val key; int rc; while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT)) == 0) { MDB_val data; data.mv_data = (void *)"there"; data.mv_size = 6; /* ! */ X(mdb_put(txn, dbi, &key, &data, 0)); } mdb_cursor_close(cursor); if (MDB_NOTFOUND != rc) return rc;
X(mdb_txn_commit(txn)); return 0; }
int main(void) { X(setup()); X(dump()); X(change_data()); X(dump()); return 0; }