/* -*- mode: C; c-basic-offset: 4 -*- */ #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." #include #include #include #include #include #include #include #include #include "toku_assert.h" #include "memory.h" #include "cachetable.h" #include "test.h" // this mutex is used by some of the tests to serialize access to some // global data, especially between the test thread and the cachetable // writeback threads pthread_mutex_t test_mutex; static inline void test_mutex_init() { int r = pthread_mutex_init(&test_mutex, 0); assert(r == 0); } static inline void test_mutex_destroy() { int r = pthread_mutex_destroy(&test_mutex); assert(r == 0); } static inline void test_mutex_lock() { int r = pthread_mutex_lock(&test_mutex); assert(r == 0); } static inline void test_mutex_unlock() { int r = pthread_mutex_unlock(&test_mutex); assert(r == 0); } enum { KEYLIMIT = 4, TRIALLIMIT=256000 }; static CACHEKEY keys[KEYLIMIT]; static void* vals[KEYLIMIT]; static int n_keys=0; static void r_flush (CACHEFILE f __attribute__((__unused__)), CACHEKEY k, void *value, long size __attribute__((__unused__)), BOOL write_me __attribute__((__unused__)), BOOL keep_me, LSN modified_lsn __attribute__((__unused__)), BOOL rename_p __attribute__((__unused__))) { int i; //printf("Flush\n"); if (keep_me) return; test_mutex_lock(); for (i=0; i= KEYLIMIT) { test_mutex_unlock(); pthread_yield(); test_mutex_lock(); } assert(n_keys0) { // Rename something int objnum = random()%n_keys; CACHEKEY nkey = random(); test_mutex_lock(); CACHEKEY okey = keys[objnum]; test_mutex_unlock(); void *current_value; long current_size; if (verbose) printf("Rename %llx to %llx\n", okey, nkey); r = toku_cachetable_get_and_pin(f, okey, toku_cachetable_hash(f, okey), ¤t_value, ¤t_size, r_flush, r_fetch, 0); if (r == -42) continue; assert(r==0); r = toku_cachetable_rename(f, okey, nkey); assert(r==0); test_mutex_lock(); // assert(objnum < n_keys && keys[objnum] == okey); // get_and_pin may reorganize the keys[], so we need to find it again int j; for (j=0; j < n_keys; j++) if (keys[j] == okey) break; assert(j < n_keys); keys[j]=nkey; test_mutex_unlock(); r = toku_cachetable_unpin(f, nkey, toku_cachetable_hash(f, nkey), CACHETABLE_DIRTY, 1); } } // test rename fails if old key does not exist in the cachetable CACHEKEY okey, nkey; while (1) { okey = random(); void *v; r = toku_cachetable_maybe_get_and_pin(f, okey, toku_cachetable_hash(f, okey), &v); if (r != 0) break; r = toku_cachetable_unpin(f, okey, toku_cachetable_hash(f, okey), CACHETABLE_CLEAN, 1); assert(r == 0); } nkey = random(); r = toku_cachetable_rename(f, okey, nkey); assert(r != 0); r = toku_cachefile_close(&f, 0); assert(r == 0); r = toku_cachetable_close(&t); assert(r == 0); test_mutex_destroy(); assert(n_keys == 0); } int main (int argc, const char *argv[]) { // defaults int do_malloc_fail = 0; // parse args int i; for (i=1; i