From 1581fecd0896d89f183f8bd5518a2754a90798d5 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Wed, 13 May 2015 22:48:02 +0300 Subject: [PATCH] lmdb: test for weak-checkpoints feature. This is 8/9 for https://github.com/ReOpen/ReOpenLDAP/issues/1 and https://github.com/ReOpen/ReOpenLDAP/issues/2 Change-Id: I2bd2d62a9b79d2953409c865fad699d554c4b694 --- .gitignore | 3 +- Makefile | 8 ++- mtest.c | 175 --------------------------------------------------- mtest0.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++ mtest1.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mtest2.c | 4 +- mtest3.c | 4 +- mtest4.c | 2 + mtest5.c | 4 +- mtest6.c | 2 + 10 files changed, 375 insertions(+), 183 deletions(-) delete mode 100644 mtest.c create mode 100644 mtest0.c create mode 100644 mtest1.c diff --git a/.gitignore b/.gitignore index 9d52c88e..494dc738 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ -mtest -mtest[23456] +mtest[0123456] testdb mdb_copy mdb_stat diff --git a/Makefile b/Makefile index f730fb94..c89ab273 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ IHDRS = lmdb.h ILIBS = liblmdb.a liblmdb.so IPROGS = mdb_stat mdb_copy mdb_dump mdb_load mdb_chk IDOCS = mdb_stat.1 mdb_copy.1 mdb_dump.1 mdb_load.1 -PROGS = $(IPROGS) mtest mtest2 mtest3 mtest4 mtest5 mtest6 +PROGS = $(IPROGS) mtest0 mtest1 mtest2 mtest3 mtest4 mtest5 mtest6 all: $(ILIBS) $(PROGS) install: $(ILIBS) $(IPROGS) $(IHDRS) @@ -47,7 +47,8 @@ clean: test: all [ -d testdb ] || mkdir testdb && rm -f testdb/* \ - && echo "*** LMDB-TEST-1" && ./mtest && ./mdb_chk testdb \ + && echo "*** LMDB-TEST-0" && ./mtest0 && ./mdb_chk testdb \ + && echo "*** LMDB-TEST-1" && ./mtest1 && ./mdb_chk testdb \ && echo "*** LMDB-TEST-2" && ./mtest2 && ./mdb_chk testdb \ && echo "*** LMDB-TEST-3" && ./mtest3 && ./mdb_chk testdb \ && echo "*** LMDB-TEST-4" && ./mtest4 && ./mdb_chk testdb \ @@ -67,7 +68,8 @@ mdb_copy: mdb_copy.o liblmdb.a mdb_dump: mdb_dump.o liblmdb.a mdb_load: mdb_load.o liblmdb.a mdb_chk: mdb_chk.o liblmdb.a -mtest: mtest.o liblmdb.a +mtest0: mtest0.o liblmdb.a +mtest1: mtest1.o liblmdb.a mtest2: mtest2.o liblmdb.a mtest3: mtest3.o liblmdb.a mtest4: mtest4.o liblmdb.a diff --git a/mtest.c b/mtest.c deleted file mode 100644 index 2197f58e..00000000 --- a/mtest.c +++ /dev/null @@ -1,175 +0,0 @@ -/* mtest.c - memory-mapped database tester/toy */ -/* - * Copyright 2011-2015 Howard Chu, Symas Corp. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted only as authorized by the OpenLDAP - * Public License. - * - * A copy of this license is available in the file LICENSE in the - * top-level directory of the distribution or, alternatively, at - * . - */ -#include -#include -#include -#include "lmdb.h" - -#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) -#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0)) -#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \ - "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort())) - -int main(int argc,char * argv[]) -{ - int i = 0, j = 0, rc; - MDB_env *env; - MDB_dbi dbi; - MDB_val key, data; - MDB_txn *txn; - MDB_stat mst; - MDB_cursor *cursor, *cur2; - MDB_cursor_op op; - int count; - int *values; - char sval[32] = ""; - - srand(time(NULL)); - - count = (rand()%384) + 64; - values = (int *)malloc(count*sizeof(int)); - - for(i = 0;i -1; i-= (rand()%5)) { - j++; - txn=NULL; - E(mdb_txn_begin(env, NULL, 0, &txn)); - sprintf(sval, "%03x ", values[i]); - if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) { - j--; - mdb_txn_abort(txn); - } else { - E(mdb_txn_commit(txn)); - } - } - free(values); - printf("Deleted %d values\n", j); - - E(mdb_env_stat(env, &mst)); - E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); - E(mdb_cursor_open(txn, dbi, &cursor)); - printf("Cursor next\n"); - while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { - printf("key: %.*s, data: %.*s\n", - (int) key.mv_size, (char *) key.mv_data, - (int) data.mv_size, (char *) data.mv_data); - } - CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); - printf("Cursor last\n"); - E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); - printf("key: %.*s, data: %.*s\n", - (int) key.mv_size, (char *) key.mv_data, - (int) data.mv_size, (char *) data.mv_data); - printf("Cursor prev\n"); - while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) { - printf("key: %.*s, data: %.*s\n", - (int) key.mv_size, (char *) key.mv_data, - (int) data.mv_size, (char *) data.mv_data); - } - CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); - printf("Cursor last/prev\n"); - E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); - printf("key: %.*s, data: %.*s\n", - (int) key.mv_size, (char *) key.mv_data, - (int) data.mv_size, (char *) data.mv_data); - E(mdb_cursor_get(cursor, &key, &data, MDB_PREV)); - printf("key: %.*s, data: %.*s\n", - (int) key.mv_size, (char *) key.mv_data, - (int) data.mv_size, (char *) data.mv_data); - - mdb_txn_abort(txn); - - printf("Deleting with cursor\n"); - E(mdb_txn_begin(env, NULL, 0, &txn)); - E(mdb_cursor_open(txn, dbi, &cur2)); - for (i=0; i<50; i++) { - if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, MDB_NEXT))) - break; - printf("key: %p %.*s, data: %p %.*s\n", - key.mv_data, (int) key.mv_size, (char *) key.mv_data, - data.mv_data, (int) data.mv_size, (char *) data.mv_data); - E(mdb_del(txn, dbi, &key, NULL)); - } - - printf("Restarting cursor in txn\n"); - for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { - if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, op))) - break; - printf("key: %p %.*s, data: %p %.*s\n", - key.mv_data, (int) key.mv_size, (char *) key.mv_data, - data.mv_data, (int) data.mv_size, (char *) data.mv_data); - } - mdb_cursor_close(cur2); - E(mdb_txn_commit(txn)); - - printf("Restarting cursor outside txn\n"); - E(mdb_txn_begin(env, NULL, 0, &txn)); - E(mdb_cursor_open(txn, dbi, &cursor)); - for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { - if (RES(MDB_NOTFOUND, mdb_cursor_get(cursor, &key, &data, op))) - break; - printf("key: %p %.*s, data: %p %.*s\n", - key.mv_data, (int) key.mv_size, (char *) key.mv_data, - data.mv_data, (int) data.mv_size, (char *) data.mv_data); - } - mdb_cursor_close(cursor); - mdb_txn_abort(txn); - - mdb_dbi_close(env, dbi); - mdb_env_close(env); - - return 0; -} diff --git a/mtest0.c b/mtest0.c new file mode 100644 index 00000000..f27132d1 --- /dev/null +++ b/mtest0.c @@ -0,0 +1,175 @@ +/* mtest.c - memory-mapped database tester/toy */ +/* + * Copyright 2011-2015 Howard Chu, Symas Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +#include +#include +#include +#include "lmdb.h" + +#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) +#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0)) +#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \ + "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort())) + +int main(int argc,char * argv[]) +{ + int i = 0, j = 0, rc; + MDB_env *env; + MDB_dbi dbi; + MDB_val key, data; + MDB_txn *txn; + MDB_stat mst; + MDB_cursor *cursor, *cur2; + MDB_cursor_op op; + int count; + int *values; + char sval[32] = ""; + + srand(time(NULL)); + + count = (rand()%384) + 64; + values = (int *)malloc(count*sizeof(int)); + + for(i = 0;i -1; i-= (rand()%5)) { + j++; + txn=NULL; + E(mdb_txn_begin(env, NULL, 0, &txn)); + sprintf(sval, "%03x ", values[i]); + if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) { + j--; + mdb_txn_abort(txn); + } else { + E(mdb_txn_commit(txn)); + } + } + free(values); + printf("Deleted %d values\n", j); + + E(mdb_env_stat(env, &mst)); + E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); + E(mdb_cursor_open(txn, dbi, &cursor)); + printf("Cursor next\n"); + while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { + printf("key: %.*s, data: %.*s\n", + (int) key.mv_size, (char *) key.mv_data, + (int) data.mv_size, (char *) data.mv_data); + } + CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); + printf("Cursor last\n"); + E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); + printf("key: %.*s, data: %.*s\n", + (int) key.mv_size, (char *) key.mv_data, + (int) data.mv_size, (char *) data.mv_data); + printf("Cursor prev\n"); + while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) { + printf("key: %.*s, data: %.*s\n", + (int) key.mv_size, (char *) key.mv_data, + (int) data.mv_size, (char *) data.mv_data); + } + CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); + printf("Cursor last/prev\n"); + E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); + printf("key: %.*s, data: %.*s\n", + (int) key.mv_size, (char *) key.mv_data, + (int) data.mv_size, (char *) data.mv_data); + E(mdb_cursor_get(cursor, &key, &data, MDB_PREV)); + printf("key: %.*s, data: %.*s\n", + (int) key.mv_size, (char *) key.mv_data, + (int) data.mv_size, (char *) data.mv_data); + + mdb_txn_abort(txn); + + printf("Deleting with cursor\n"); + E(mdb_txn_begin(env, NULL, 0, &txn)); + E(mdb_cursor_open(txn, dbi, &cur2)); + for (i=0; i<50; i++) { + if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, MDB_NEXT))) + break; + printf("key: %p %.*s, data: %p %.*s\n", + key.mv_data, (int) key.mv_size, (char *) key.mv_data, + data.mv_data, (int) data.mv_size, (char *) data.mv_data); + E(mdb_del(txn, dbi, &key, NULL)); + } + + printf("Restarting cursor in txn\n"); + for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { + if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, op))) + break; + printf("key: %p %.*s, data: %p %.*s\n", + key.mv_data, (int) key.mv_size, (char *) key.mv_data, + data.mv_data, (int) data.mv_size, (char *) data.mv_data); + } + mdb_cursor_close(cur2); + E(mdb_txn_commit(txn)); + + printf("Restarting cursor outside txn\n"); + E(mdb_txn_begin(env, NULL, 0, &txn)); + E(mdb_cursor_open(txn, dbi, &cursor)); + for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { + if (RES(MDB_NOTFOUND, mdb_cursor_get(cursor, &key, &data, op))) + break; + printf("key: %p %.*s, data: %p %.*s\n", + key.mv_data, (int) key.mv_size, (char *) key.mv_data, + data.mv_data, (int) data.mv_size, (char *) data.mv_data); + } + mdb_cursor_close(cursor); + mdb_txn_abort(txn); + + mdb_dbi_close(env, dbi); + mdb_env_close(env); + + return 0; +} diff --git a/mtest1.c b/mtest1.c new file mode 100644 index 00000000..eb26ffd2 --- /dev/null +++ b/mtest1.c @@ -0,0 +1,181 @@ +/* + Copyright (c) 2015 Leonid Yuriev . + Copyright (c) 2015 Peter-Service R&D LLC. + + This file is part of ReOpenLDAP. + + ReOpenLDAP is free software; you can redistribute it and/or modify it under + the terms of the GNU Affero General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ReOpenLDAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +/* Based on mtest2.c - memory-mapped database tester/toy */ + +#include +#include +#include +#include "lmdb.h" + +#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) +#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0)) +#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \ + "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort())) + +int main(int argc,char * argv[]) +{ + int i = 0, j = 0, rc; + MDB_env *env; + MDB_dbi dbi; + MDB_val key, data; + MDB_txn *txn; + MDB_stat mst; + MDB_cursor *cursor; + int count; + int *values; + char sval[32] = ""; + + srand(time(NULL)); + + count = (rand()%384) + 64; + values = (int *)malloc(count*sizeof(int)); + + for(i = 0;i -1; i-= (rand()%5)) { + j++; + txn=NULL; + E(mdb_txn_begin(env, NULL, 0, &txn)); + sprintf(sval, "%03x ", values[i]); + if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) { + j--; + mdb_txn_abort(txn); + } else { + E(mdb_txn_commit(txn)); + } + } + free(values); + printf("Deleted %d values\n", j); + + printf("check-preset-b.cursor-next\n"); + E(mdb_env_stat(env, &mst)); + E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); + E(mdb_cursor_open(txn, dbi, &cursor)); + int present_b = 0; + while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { + printf("key: %.*s, data: %.*s\n", + (int) key.mv_size, (char *) key.mv_data, + (int) data.mv_size, (char *) data.mv_data); + ++present_b; + } + CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); + CHECK(present_b == present_a - j, "mismatch"); + + printf("check-preset-b.cursor-prev\n"); + j = 1; + while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) { + printf("key: %.*s, data: %.*s\n", + (int) key.mv_size, (char *) key.mv_data, + (int) data.mv_size, (char *) data.mv_data); + ++j; + } + CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); + CHECK(present_b == j, "mismatch"); + mdb_cursor_close(cursor); + mdb_txn_abort(txn); + + mdb_dbi_close(env, dbi); + /********************* LY: kept DB dirty ****************/ + mdb_env_close_ex(env, 1); + E(mdb_env_create(&env)); + E(mdb_env_set_maxdbs(env, 4)); + E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664)); + + printf("check-preset-c.cursor-next\n"); + E(mdb_env_stat(env, &mst)); + E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); + E(mdb_dbi_open(txn, "id1", 0, &dbi)); + E(mdb_cursor_open(txn, dbi, &cursor)); + int present_c = 0; + while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { + printf("key: %.*s, data: %.*s\n", + (int) key.mv_size, (char *) key.mv_data, + (int) data.mv_size, (char *) data.mv_data); + ++present_c; + } + CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); + CHECK(present_c == present_a, "mismatch"); + + printf("check-preset-d.cursor-prev\n"); + j = 1; + while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) { + printf("key: %.*s, data: %.*s\n", + (int) key.mv_size, (char *) key.mv_data, + (int) data.mv_size, (char *) data.mv_data); + ++j; + } + CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); + CHECK(present_c == j, "mismatch"); + mdb_cursor_close(cursor); + mdb_txn_abort(txn); + + mdb_dbi_close(env, dbi); + mdb_env_close_ex(env, 0); + + return 0; +} diff --git a/mtest2.c b/mtest2.c index d36273f9..d04e08ae 100644 --- a/mtest2.c +++ b/mtest2.c @@ -53,7 +53,9 @@ int main(int argc,char * argv[]) E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664)); E(mdb_txn_begin(env, NULL, 0, &txn)); - E(mdb_dbi_open(txn, "id1", MDB_CREATE, &dbi)); + if (mdb_dbi_open(txn, "id2", MDB_CREATE, &dbi) == MDB_SUCCESS) + E(mdb_drop(txn, dbi, 1)); + E(mdb_dbi_open(txn, "id2", MDB_CREATE, &dbi)); key.mv_size = sizeof(int); key.mv_data = sval; diff --git a/mtest3.c b/mtest3.c index 9db79e62..6e3b9e02 100644 --- a/mtest3.c +++ b/mtest3.c @@ -55,7 +55,9 @@ int main(int argc,char * argv[]) E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664)); E(mdb_txn_begin(env, NULL, 0, &txn)); - E(mdb_dbi_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi)); + if (mdb_dbi_open(txn, "id3", MDB_CREATE, &dbi) == MDB_SUCCESS) + E(mdb_drop(txn, dbi, 1)); + E(mdb_dbi_open(txn, "id3", MDB_CREATE|MDB_DUPSORT, &dbi)); key.mv_size = sizeof(int); key.mv_data = kval; diff --git a/mtest4.c b/mtest4.c index 6df890e2..22f4af85 100644 --- a/mtest4.c +++ b/mtest4.c @@ -53,6 +53,8 @@ int main(int argc,char * argv[]) E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664)); E(mdb_txn_begin(env, NULL, 0, &txn)); + if (mdb_dbi_open(txn, "id4", MDB_CREATE, &dbi) == MDB_SUCCESS) + E(mdb_drop(txn, dbi, 1)); E(mdb_dbi_open(txn, "id4", MDB_CREATE|MDB_DUPSORT|MDB_DUPFIXED, &dbi)); key.mv_size = sizeof(int); diff --git a/mtest5.c b/mtest5.c index 14e3c0da..11913da8 100644 --- a/mtest5.c +++ b/mtest5.c @@ -55,7 +55,9 @@ int main(int argc,char * argv[]) E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664)); E(mdb_txn_begin(env, NULL, 0, &txn)); - E(mdb_dbi_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi)); + if (mdb_dbi_open(txn, "id5", MDB_CREATE, &dbi) == MDB_SUCCESS) + E(mdb_drop(txn, dbi, 1)); + E(mdb_dbi_open(txn, "id5", MDB_CREATE|MDB_DUPSORT, &dbi)); E(mdb_cursor_open(txn, dbi, &cursor)); key.mv_size = sizeof(int); diff --git a/mtest6.c b/mtest6.c index 2a75abcc..76b0a9c1 100644 --- a/mtest6.c +++ b/mtest6.c @@ -46,6 +46,8 @@ int main(int argc,char * argv[]) E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664)); E(mdb_txn_begin(env, NULL, 0, &txn)); + if (mdb_dbi_open(txn, "id6", MDB_CREATE, &dbi) == MDB_SUCCESS) + E(mdb_drop(txn, dbi, 1)); E(mdb_dbi_open(txn, "id6", MDB_CREATE|MDB_INTEGERKEY, &dbi)); E(mdb_cursor_open(txn, dbi, &cursor)); E(mdb_stat(txn, dbi, &mst));