/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- */ // vim: expandtab:ts=8:sw=4:softtabstop=4: #ident "$Id$" #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." #include "includes.h" #include "test.h" static const char fname[]= __SRCFILE__ ".ft_handle"; static TOKUTXN const null_txn = 0; static DB * const null_db = 0; static int test_cursor_debug = 0; static int test_ft_cursor_keycompare(DB *desc __attribute__((unused)), const DBT *a, const DBT *b) { return toku_keycompare(a->data, a->size, b->data, b->size); } static void assert_cursor_notfound(FT_HANDLE brt, int position) { FT_CURSOR cursor=0; int r; r = toku_ft_cursor(brt, &cursor, NULL, FALSE, FALSE); assert(r==0); struct check_pair pair = {0,0,0,0,0}; r = toku_ft_cursor_get(cursor, NULL, lookup_checkf, &pair, position); assert(r == DB_NOTFOUND); assert(pair.call_count==0); r = toku_ft_cursor_close(cursor); assert(r==0); } static void assert_cursor_value(FT_HANDLE brt, int position, long long value) { FT_CURSOR cursor=0; int r; r = toku_ft_cursor(brt, &cursor, NULL, FALSE, FALSE); assert(r==0); if (test_cursor_debug && verbose) printf("key: "); struct check_pair pair = {len_ignore, 0, sizeof(value), &value, 0}; r = toku_ft_cursor_get(cursor, NULL, lookup_checkf, &pair, position); assert(r == 0); assert(pair.call_count==1); r = toku_ft_cursor_close(cursor); assert(r==0); } static void assert_cursor_first_last(FT_HANDLE brt, long long firstv, long long lastv) { FT_CURSOR cursor=0; int r; r = toku_ft_cursor(brt, &cursor, NULL, FALSE, FALSE); assert(r==0); if (test_cursor_debug && verbose) printf("first key: "); { struct check_pair pair = {len_ignore, 0, sizeof(firstv), &firstv, 0}; r = toku_ft_cursor_get(cursor, NULL, lookup_checkf, &pair, DB_FIRST); assert(r == 0); assert(pair.call_count==1); } if (test_cursor_debug && verbose) printf("last key:"); { struct check_pair pair = {len_ignore, 0, sizeof(lastv), &lastv, 0}; r = toku_ft_cursor_get(cursor, NULL, lookup_checkf, &pair, DB_LAST); assert(r == 0); assert(pair.call_count==1); } if (test_cursor_debug && verbose) printf("\n"); r = toku_ft_cursor_close(cursor); assert(r==0); } static void test_ft_cursor_first(int n) { CACHETABLE ct; FT_HANDLE brt; int r; int i; if (verbose) printf("test_ft_cursor_first:%d\n", n); unlink(fname); r = toku_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0); r = toku_open_ft_handle(fname, 1, &brt, 1<<12, 1<<9, TOKU_DEFAULT_COMPRESSION_METHOD, ct, null_txn, test_ft_cursor_keycompare); assert(r==0); /* insert a bunch of kv pairs */ for (i=0; i=0; i--) { char key[8]; long long v; DBT kbt, vbt; snprintf(key, sizeof key, "%4.4d", i); toku_fill_dbt(&kbt, key, strlen(key)+1); v = i; toku_fill_dbt(&vbt, &v, sizeof v); r = toku_ft_insert(brt, &kbt, &vbt, 0); assert(r==0); } if (n == 0) assert_cursor_notfound(brt, DB_FIRST); else assert_cursor_value(brt, DB_FIRST, 0); r = toku_close_ft_handle_nolsn(brt, 0); assert(r==0); r = toku_cachetable_close(&ct); assert(r==0); } static void assert_cursor_walk(FT_HANDLE brt, int n) { FT_CURSOR cursor=0; int i; int r; r = toku_ft_cursor(brt, &cursor, NULL, FALSE, FALSE); assert(r==0); if (test_cursor_debug && verbose) printf("key: "); for (i=0; ; i++) { long long v = i; struct check_pair pair = {len_ignore, 0, sizeof(v), &v, 0}; r = toku_ft_cursor_get(cursor, NULL, lookup_checkf, &pair, DB_NEXT); if (r != 0) { assert(pair.call_count==0); break; } assert(pair.call_count==1); } if (test_cursor_debug && verbose) printf("\n"); assert(i == n); r = toku_ft_cursor_close(cursor); assert(r==0); } static void test_ft_cursor_walk(int n) { CACHETABLE ct; FT_HANDLE brt; int r; int i; if (verbose) printf("test_ft_cursor_walk:%d\n", n); unlink(fname); r = toku_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(r==0); r = toku_open_ft_handle(fname, 1, &brt, 1<<12, 1<<9, TOKU_DEFAULT_COMPRESSION_METHOD, ct, null_txn, test_ft_cursor_keycompare); assert(r==0); /* insert a bunch of kv pairs */ for (i=0; i= v */ for (i=0; i max_key) { /* there is no smallest key if v > the max key */ assert(r == DB_NOTFOUND); assert(pair.call_count==0); } else { assert(r == 0); assert(pair.call_count==1); } } r = toku_ft_cursor_close(cursor); assert(r==0); r = toku_close_ft_handle_nolsn(brt, 0); assert(r==0); r = toku_cachetable_close(&ct); assert(r==0); } static void test_ft_cursor_delete(int n) { if (verbose) printf("test_ft_cursor_delete:%d\n", n); int error; CACHETABLE ct; FT_HANDLE brt; FT_CURSOR cursor=0; unlink(fname); error = toku_create_cachetable(&ct, 0, ZERO_LSN, NULL_LOGGER); assert(error == 0); error = toku_open_ft_handle(fname, 1, &brt, 1<<12, 1<<9, TOKU_DEFAULT_COMPRESSION_METHOD, ct, null_txn, test_ft_cursor_keycompare); assert(error == 0); error = toku_ft_cursor(brt, &cursor, NULL, FALSE, FALSE); assert(error == 0); DBT key, val; int k, v; int i; /* insert keys 0, 1, 2, .. (n-1) */ for (i=0; i