/* -*- mode: C; c-basic-offset: 4 -*- */ #ident "Copyright (c) 2007 Tokutek Inc. All rights reserved." /* try a reverse compare function to verify that the database always uses the application's compare function */ #include #include #include #include #include #include #include #include #include #include #define DIR __FILE__ ".dir" int verbose; int keycompare (const void *key1, unsigned int key1len, const void *key2, unsigned int key2len) { if (key1len==key2len) { return memcmp(key1,key2,key1len); } else if (key1lendata, a->size, b->data, b->size); } void expect(Dbc *cursor, int k, int v) { Dbt key; key.set_flags(DB_DBT_MALLOC); Dbt val; val.set_flags(DB_DBT_MALLOC); int r = cursor->get(&key, &val, DB_NEXT); assert(r == 0); assert(key.get_size() == sizeof k); int kk; memcpy(&kk, key.get_data(), key.get_size()); assert(val.get_size() == sizeof v); int vv; memcpy(&vv, val.get_data(), val.get_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); toku_free(key.get_data()); toku_free(val.get_data()); } void test_reverse_compare(int n) { if (verbose) printf("test_reverse_compare:%d\n", n); Db *db; DbTxn * const null_txn = 0; const char * const fname = "reverse.compare.db"; int r; int i; system("rm -rf " DIR); toku_os_mkdir(DIR, 0777); /* create the dup database file */ DbEnv env(DB_CXX_NO_EXCEPTIONS); r = env.set_redzone(0); assert(r==0); r = env.set_default_bt_compare(reverse_compare); assert(r == 0); r = env.open(DIR, DB_INIT_MPOOL + DB_CREATE + DB_PRIVATE, 0777); assert(r == 0); db = new Db(&env, DB_CXX_NO_EXCEPTIONS); assert(db); r = db->set_pagesize(4096); assert(r == 0); r = db->open(null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); assert(r == 0); /* insert n unique keys {0, 1, n-1} */ for (i=0; iput(null_txn, &key, &val, DB_YESOVERWRITE); assert(r == 0); } /* reopen the database to force nonleaf buffering */ r = db->close(0); assert(r == 0); delete db; db = new Db(&env, 0); assert(db); r = db->set_pagesize(4096); assert(r == 0); r = db->open(null_txn, fname, "main", DB_BTREE, 0, 0666); assert(r == 0); /* insert n unique keys {n, n+1, 2*n-1} */ for (i=n; i<2*n; i++) { int k, v; k = htonl(i); Dbt key(&k, sizeof k); v = htonl(i); Dbt val(&v, sizeof v); r = db->put(null_txn, &key, &val, DB_YESOVERWRITE); assert(r == 0); } /* verify the sort order with a cursor */ Dbc *cursor; r = db->cursor(null_txn, &cursor, 0); assert(r == 0); //for (i=0; i<2*n; i++) for (i=2*n-1; i>=0; i--) expect(cursor, htonl(i), htonl(i)); r = cursor->close(); assert(r == 0); r = db->close(0); assert(r == 0); delete db; } int main(int argc, const char *argv[]) { int i; for (i = 1; i <= (1<<16); i *= 2) { test_reverse_compare(i); } return 0; }