From d345db05510f9f702a79af34b520a12f09c3fcb1 Mon Sep 17 00:00:00 2001 From: Rich Prohaska Date: Mon, 26 Nov 2007 15:26:47 +0000 Subject: [PATCH] Addresses #19 git-svn-id: file:///svn/tokudb@754 c7de825b-a66e-492c-adef-691d508d4ae1 --- .../{test_db_dup.c => test_dup_delete.c} | 307 --------------- src/tests/test_dup_flags.c | 81 ++++ src/tests/test_dup_insert.c | 305 +++++++++++++++ src/tests/test_dup_search.c | 358 ++++++++++++++++++ 4 files changed, 744 insertions(+), 307 deletions(-) rename src/tests/{test_db_dup.c => test_dup_delete.c} (69%) create mode 100644 src/tests/test_dup_flags.c create mode 100644 src/tests/test_dup_insert.c create mode 100644 src/tests/test_dup_search.c diff --git a/src/tests/test_db_dup.c b/src/tests/test_dup_delete.c similarity index 69% rename from src/tests/test_db_dup.c rename to src/tests/test_dup_delete.c index 60266f58823..5b57c263ed3 100644 --- a/src/tests/test_db_dup.c +++ b/src/tests/test_dup_delete.c @@ -9,58 +9,6 @@ #include "test.h" -/* verify that the dup flags are written and read from the database file correctly */ -void test_dup_flags(int dup_flags) { - if (verbose) printf("test_dup_flags:%d\n", dup_flags); - - DB_ENV * const null_env = 0; - DB *db; - DB_TXN * const null_txn = 0; - const char * const fname = DIR "/" "test_dup_flags.brt"; - int r; - - unlink(fname); - - /* create the dup database file */ - r = db_create(&db, null_env, 0); - assert(r == 0); - r = db->set_flags(db, dup_flags); - assert(r == 0); - r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); - assert(r == 0); - r = db->close(db, 0); - assert(r == 0); - - /* verify dup flags match */ - r = db_create(&db, null_env, 0); - assert(r == 0); - r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); - //assert(r != 0); - r = db->close(db, 0); - assert(r == 0); - - r = db_create(&db, null_env, 0); - assert(r == 0); - r = db->set_flags(db, dup_flags); - assert(r == 0); - r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); - assert(r == 0); - r = db->close(db, 0); - assert(r == 0); - - /* verify nodesize match */ - r = db_create(&db, null_env, 0); - assert(r == 0); - r = db->set_flags(db, dup_flags); - assert(r == 0); - r = db->set_pagesize(db, 4096); - assert(r == 0); - r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); - assert(r == 0); - r = db->close(db, 0); - assert(r == 0); -} - DBT *dbt_init(DBT *dbt, void *data, u_int32_t size) { memset(dbt, 0, sizeof *dbt); dbt->data = data; @@ -92,239 +40,6 @@ void expect(DBC *cursor, int k, int v) { free(val.data); } -/* verify that key insertions are stored in insert order */ -void test_insert(int n, int dup_mode) { - if (verbose) printf("test_insert:%d %d\n", n, dup_mode); - - DB_ENV * const null_env = 0; - DB *db; - DB_TXN * const null_txn = 0; - const char * const fname = DIR "/" "test_insert.brt"; - int r; - int i; - - unlink(fname); - - /* create the dup database file */ - r = db_create(&db, null_env, 0); - assert(r == 0); - r = db->set_flags(db, dup_mode); - assert(r == 0); - r = db->set_pagesize(db, 4096); - assert(r == 0); - r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); - assert(r == 0); - - int values[n]; - for (i=0; iput(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); - assert(r == 0); - } - - /* insert n duplicates */ - for (i=0; iput(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); -#if USE_BDB - if (r != 0) { - void find_dup_val(int v, int m) { - int i; - printf("dup values[%d]=%d: ", m, v); - for (i=0; iget(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init_malloc(&val), 0); - assert(r == 0); - int vv; - assert(val.size == sizeof vv); - memcpy(&vv, val.data, val.size); - if (i == n/2) { - if (dup_mode & DB_DUPSORT) - assert(vv == sortvalues[0]); - else if (dup_mode & DB_DUP) - assert(vv == values[0]); - else - assert(vv == values[n-1]); - } else - assert(vv == values[i]); - free(val.data); - } - - /* verify the sort order with a cursor */ - DBC *cursor; - r = db->cursor(db, null_txn, &cursor, 0); - assert(r == 0); - - for (i=0; ic_close(cursor); - assert(r == 0); - - r = db->close(db, 0); - assert(r == 0); -} - -/* verify dup keys are buffered in order in non-leaf nodes */ -void test_nonleaf_insert(int n, int dup_mode) { - if (verbose) printf("test_nonleaf_insert:%d %d\n", n, dup_mode); - - DB_ENV * const null_env = 0; - DB *db; - DB_TXN * const null_txn = 0; - const char * const fname = DIR "/" "test_nonleaf_insert.brt"; - int r; - int i; - - unlink(fname); - - /* create the dup database file */ - r = db_create(&db, null_env, 0); - assert(r == 0); - r = db->set_flags(db, dup_mode); - assert(r == 0); - r = db->set_pagesize(db, 4096); - assert(r == 0); - r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); - assert(r == 0); - - int values[n]; - for (i=0; iput(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); - assert(r == 0); - } - - /* reopen the database to force nonleaf buffering */ - r = db->close(db, 0); - assert(r == 0); - r = db_create(&db, null_env, 0); - assert(r == 0); - r = db->set_flags(db, dup_mode); - assert(r == 0); - r = db->set_pagesize(db, 4096); - assert(r == 0); - r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); - assert(r == 0); - - /* insert n duplicates */ - for (i=0; iput(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); - CKERR(r); - } - - /* verify lookups */ - for (i=0; iget(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init_malloc(&val), 0); - assert(r == 0); - int vv; - assert(val.size == sizeof vv); - memcpy(&vv, val.data, val.size); - if (i == n/2) { - if (dup_mode & DB_DUPSORT) - assert(vv == sortvalues[0]); - else if (dup_mode & DB_DUP) - assert(vv == values[0]); - else - assert(vv == values[n-1]); - } else - assert(vv == values[i]); - free(val.data); - } - - /* verify the sort order with a cursor */ - DBC *cursor; - r = db->cursor(db, null_txn, &cursor, 0); - assert(r == 0); - - for (i=0; ic_close(cursor); - assert(r == 0); - - r = db->close(db, 0); - assert(r == 0); -} - /* verify dup keys delete */ void test_dup_delete(int n, int dup_mode) { if (verbose) printf("test_dup_delete:%d %d\n", n, dup_mode); @@ -1018,43 +733,21 @@ int main(int argc, const char *argv[]) { parse_args(argc, argv); - system("rm -rf " DIR); mkdir(DIR, 0777); - /* test flags */ - test_dup_flags(DB_DUP); - test_dup_flags(DB_DUP + DB_DUPSORT); - - /* nodup tests */ - for (i = 1; i <= (1<<16); i *= 2) { - test_insert(i, 0); - test_nonleaf_insert(i, 0); - } - /* dup tests */ for (i = 1; i <= (1<<16); i *= 2) { - test_insert(i, DB_DUP); test_dup_delete(i, DB_DUP); - test_nonleaf_insert(i, DB_DUP); test_dup_delete_insert(i, DB_DUP); test_all_dup_delete_insert(i); test_walk_empty(i, DB_DUP); } - /* dup search */ - for (i = 1; i <= (1<<16); i *= 2) { - test_ici_search(i, DB_DUP); - test_icdi_search(i, DB_DUP); - test_i0i1ci0_search(i, DB_DUP); - } - #if USE_TDB /* dupsort tests */ for (i = 1; i <= (1<<16); i *= 2) { - test_insert(i, DB_DUP + DB_DUPSORT); test_dup_delete(i, DB_DUP + DB_DUPSORT); - test_nonleaf_insert(i, DB_DUP + DB_DUPSORT); test_dup_delete_insert(i, DB_DUP + DB_DUPSORT); test_walk_empty(i, DB_DUP + DB_DUPSORT); } diff --git a/src/tests/test_dup_flags.c b/src/tests/test_dup_flags.c new file mode 100644 index 00000000000..d4e826f3baa --- /dev/null +++ b/src/tests/test_dup_flags.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +/* verify that the dup flags are written and read from the database file correctly */ +void test_dup_flags(int dup_flags) { + if (verbose) printf("test_dup_flags:%d\n", dup_flags); + + DB_ENV * const null_env = 0; + DB *db; + DB_TXN * const null_txn = 0; + const char * const fname = DIR "/" "test_dup_flags.brt"; + int r; + + unlink(fname); + + /* create the dup database file */ + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_flags); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); + assert(r == 0); + r = db->close(db, 0); + assert(r == 0); + + /* verify dup flags match */ + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); +#if USE_BDB + if (r == 0) + printf("%s:%d: WARNING:open ok:dup_mode:%d\n", __FILE__, __LINE__, dup_flags); +#else + assert(r != 0); +#endif + r = db->close(db, 0); + assert(r == 0); + + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_flags); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); + assert(r == 0); + r = db->close(db, 0); + assert(r == 0); + + /* verify nodesize match */ + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_flags); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); + assert(r == 0); + r = db->close(db, 0); + assert(r == 0); +} + +int main(int argc, const char *argv[]) { + + parse_args(argc, argv); + + system("rm -rf " DIR); + mkdir(DIR, 0777); + + /* test flags */ + test_dup_flags(DB_DUP); + test_dup_flags(DB_DUP + DB_DUPSORT); + + return 0; +} diff --git a/src/tests/test_dup_insert.c b/src/tests/test_dup_insert.c new file mode 100644 index 00000000000..3ec66a0a891 --- /dev/null +++ b/src/tests/test_dup_insert.c @@ -0,0 +1,305 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +DBT *dbt_init(DBT *dbt, void *data, u_int32_t size) { + memset(dbt, 0, sizeof *dbt); + dbt->data = data; + dbt->size = size; + return dbt; +} + +DBT *dbt_init_malloc(DBT *dbt) { + memset(dbt, 0, sizeof *dbt); + dbt->flags = DB_DBT_MALLOC; + return dbt; +} + +void expect(DBC *cursor, int k, int v) { + DBT key, val; + int r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&val), DB_NEXT); + assert(r == 0); + assert(key.size == sizeof k); + int kk; + memcpy(&kk, key.data, key.size); + assert(val.size == sizeof v); + int vv; + memcpy(&vv, val.data, val.size); + if (kk != k || vv != v) printf("expect key %d got %d - %d %d\n", htonl(k), htonl(kk), htonl(v), htonl(vv)); + assert(kk == k); + assert(vv == v); + + free(key.data); + free(val.data); +} + +/* verify that key insertions are stored in insert order */ +void test_insert(int n, int dup_mode) { + if (verbose) printf("test_insert:%d %d\n", n, dup_mode); + + DB_ENV * const null_env = 0; + DB *db; + DB_TXN * const null_txn = 0; + const char * const fname = DIR "/" "test_insert.brt"; + int r; + int i; + + unlink(fname); + + /* create the dup database file */ + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); + assert(r == 0); + + int values[n]; + for (i=0; iput(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); + assert(r == 0); + } + + /* insert n duplicates */ + for (i=0; iput(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); +#if USE_BDB + if (r != 0) { + void find_dup_val(int v, int m) { + int i; + printf("dup values[%d]=%d: ", m, v); + for (i=0; iget(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init_malloc(&val), 0); + assert(r == 0); + int vv; + assert(val.size == sizeof vv); + memcpy(&vv, val.data, val.size); + if (i == n/2) { + if (dup_mode & DB_DUPSORT) + assert(vv == sortvalues[0]); + else if (dup_mode & DB_DUP) + assert(vv == values[0]); + else + assert(vv == values[n-1]); + } else + assert(vv == values[i]); + free(val.data); + } + + /* verify the sort order with a cursor */ + DBC *cursor; + r = db->cursor(db, null_txn, &cursor, 0); + assert(r == 0); + + for (i=0; ic_close(cursor); + assert(r == 0); + + r = db->close(db, 0); + assert(r == 0); +} + +/* verify dup keys are buffered in order in non-leaf nodes */ +void test_nonleaf_insert(int n, int dup_mode) { + if (verbose) printf("test_nonleaf_insert:%d %d\n", n, dup_mode); + + DB_ENV * const null_env = 0; + DB *db; + DB_TXN * const null_txn = 0; + const char * const fname = DIR "/" "test_nonleaf_insert.brt"; + int r; + int i; + + unlink(fname); + + /* create the dup database file */ + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); + assert(r == 0); + + int values[n]; + for (i=0; iput(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); + assert(r == 0); + } + + /* reopen the database to force nonleaf buffering */ + r = db->close(db, 0); + assert(r == 0); + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); + assert(r == 0); + + /* insert n duplicates */ + for (i=0; iput(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); + CKERR(r); + } + + /* verify lookups */ + for (i=0; iget(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init_malloc(&val), 0); + assert(r == 0); + int vv; + assert(val.size == sizeof vv); + memcpy(&vv, val.data, val.size); + if (i == n/2) { + if (dup_mode & DB_DUPSORT) + assert(vv == sortvalues[0]); + else if (dup_mode & DB_DUP) + assert(vv == values[0]); + else + assert(vv == values[n-1]); + } else + assert(vv == values[i]); + free(val.data); + } + + /* verify the sort order with a cursor */ + DBC *cursor; + r = db->cursor(db, null_txn, &cursor, 0); + assert(r == 0); + + for (i=0; ic_close(cursor); + assert(r == 0); + + r = db->close(db, 0); + assert(r == 0); +} + +int main(int argc, const char *argv[]) { + int i; + + parse_args(argc, argv); + + system("rm -rf " DIR); + mkdir(DIR, 0777); + + /* nodup tests */ + for (i = 1; i <= (1<<16); i *= 2) { + test_insert(i, 0); + test_nonleaf_insert(i, 0); + } + + /* dup tests */ + for (i = 1; i <= (1<<16); i *= 2) { + test_insert(i, DB_DUP); + test_nonleaf_insert(i, DB_DUP); + } + +#if USE_TDB + /* dupsort tests */ + for (i = 1; i <= (1<<16); i *= 2) { + test_insert(i, DB_DUP + DB_DUPSORT); + test_nonleaf_insert(i, DB_DUP + DB_DUPSORT); + } +#endif + + return 0; +} diff --git a/src/tests/test_dup_search.c b/src/tests/test_dup_search.c new file mode 100644 index 00000000000..f21db889901 --- /dev/null +++ b/src/tests/test_dup_search.c @@ -0,0 +1,358 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test.h" + +DBT *dbt_init(DBT *dbt, void *data, u_int32_t size) { + memset(dbt, 0, sizeof *dbt); + dbt->data = data; + dbt->size = size; + return dbt; +} + +DBT *dbt_init_malloc(DBT *dbt) { + memset(dbt, 0, sizeof *dbt); + dbt->flags = DB_DBT_MALLOC; + return dbt; +} + +void db_put(DB *db, int k, int v) { + DB_TXN * const null_txn = 0; + DBT key, val; + int r = db->put(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); + assert(r == 0); +} + +void db_get(DB *db, int k) { + DB_TXN * const null_txn = 0; + DBT key, val; + int r = db->get(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init_malloc(&val), 0); + assert(r == 0); + int vv; + assert(val.size == sizeof vv); + memcpy(&vv, val.data, val.size); + printf("do_search %d\n", htonl(vv)); + free(val.data); +} + +void db_del(DB *db, int k) { + DB_TXN * const null_txn = 0; + DBT key; + int r = db->del(db, null_txn, dbt_init(&key, &k, sizeof k), 0); + assert(r == 0); +} + +void expect_db_get(DB *db, int k, int v) { + DB_TXN * const null_txn = 0; + DBT key, val; + int r = db->get(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init_malloc(&val), 0); + assert(r == 0); + int vv; + assert(val.size == sizeof vv); + memcpy(&vv, val.data, val.size); + assert(vv == v); + free(val.data); +} + +void expect_cursor_get(DBC *cursor, int k, int v) { + DBT key, val; + int r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&val), DB_NEXT); + assert(r == 0); + assert(key.size == sizeof k); + int kk; + memcpy(&kk, key.data, key.size); + assert(val.size == sizeof v); + int vv; + memcpy(&vv, val.data, val.size); + if (kk != k || vv != v) printf("expect key %d got %d - %d %d\n", htonl(k), htonl(kk), htonl(v), htonl(vv)); + assert(kk == k); + assert(vv == v); + + free(key.data); + free(val.data); +} + +/* insert, close, delete, insert, search */ +void test_icdi_search(int n, int dup_mode) { + if (verbose) printf("test_icdi_search:%d %d\n", n, dup_mode); + + DB_ENV * const null_env = 0; + DB *db; + DB_TXN * const null_txn = 0; + const char * const fname = DIR "/" "test_icdi_search.brt"; + int r; + + unlink(fname); + + /* create the dup database file */ + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); + assert(r == 0); + + /* insert n duplicates */ + int i; + for (i=0; iclose(db, 0); + assert(r == 0); + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); + assert(r == 0); + + db_del(db, htonl(n/2)); + + /* insert n duplicates */ + for (i=0; icursor(db, null_txn, &cursor, 0); + assert(r == 0); + + for (i=0; ic_close(cursor); + assert(r == 0); + + r = db->close(db, 0); + assert(r == 0); +} + +/* insert, close, insert, search */ +void test_ici_search(int n, int dup_mode) { + if (verbose) printf("test_ici_search:%d %d\n", n, dup_mode); + + DB_ENV * const null_env = 0; + DB *db; + DB_TXN * const null_txn = 0; + const char * const fname = DIR "/" "test_ici_search.brt"; + int r; + + unlink(fname); + + /* create the dup database file */ + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); + assert(r == 0); + + /* insert n duplicates */ + int i; + for (i=0; iclose(db, 0); + assert(r == 0); + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); + assert(r == 0); + + /* insert n duplicates */ + for (i=0; icursor(db, null_txn, &cursor, 0); + assert(r == 0); + + for (i=0; i<2*n; i++) { + expect_cursor_get(cursor, htonl(n/2), htonl(i)); + } + + r = cursor->c_close(cursor); + assert(r == 0); + + r = db->close(db, 0); + assert(r == 0); +} + +/* insert 0, insert 1, close, insert 0, search 0 */ +void test_i0i1ci0_search(int n, int dup_mode) { + if (verbose) printf("test_i0i1ci0_search:%d %d\n", n, dup_mode); + + DB_ENV * const null_env = 0; + DB *db; + DB_TXN * const null_txn = 0; + const char * const fname = DIR "/" "test_i0i1ci0.brt"; + int r; + + unlink(fname); + + /* create the dup database file */ + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); + assert(r == 0); + + /* insert <0,0> */ + db_put(db, 0, 0); + + /* insert n duplicates */ + int i; + for (i=0; iclose(db, 0); + assert(r == 0); + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); + assert(r == 0); + + /* insert <0,1> */ + db_put(db, 0, 1); + + /* verify dup search digs deep into the tree */ + expect_db_get(db, 0, 0); + + r = db->close(db, 0); + assert(r == 0); +} + +/* insert dup keys with data descending from n to 1 */ +void test_reverse_search(int n, int dup_mode) { + if (verbose) printf("test_reverse_search:%d %d\n", n, dup_mode); + + DB_ENV * const null_env = 0; + DB *db; + DB_TXN * const null_txn = 0; + const char * const fname = DIR "/" "test_reverse_search.brt"; + int r; + + unlink(fname); + + /* create the dup database file */ + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); + assert(r == 0); + + /* seq inserts to build the tree */ + int i; + for (i=0; iclose(db, 0); + assert(r == 0); + r = db_create(&db, null_env, 0); + assert(r == 0); + r = db->set_flags(db, dup_mode); + assert(r == 0); + r = db->set_pagesize(db, 4096); + assert(r == 0); + r = db->open(db, null_txn, fname, "main", DB_BTREE, 0, 0666); + assert(r == 0); + + /* dup key inserts , , .. */ + for (i=0; iclose(db, 0); + assert(r == 0); +} + +int main(int argc, const char *argv[]) { + int i; + + parse_args(argc, argv); + + system("rm -rf " DIR); + mkdir(DIR, 0777); + + /* dup search */ + for (i = 1; i <= (1<<16); i *= 2) { + test_ici_search(i, DB_DUP); + test_icdi_search(i, DB_DUP); + test_i0i1ci0_search(i, DB_DUP); + } + + /* insert data in descending order */ + for (i = 1; i <= (1<<16); i *= 2) { + test_reverse_search(i, 0); + test_reverse_search(i, DB_DUP); + test_reverse_search(i, DB_DUP + DB_DUPSORT); + } + + return 0; +}