Commit 539c2458 authored by Rich Prohaska's avatar Rich Prohaska Committed by Yoni Fogel

#4503 #4504 support concurrent queries on the mainline refs[t:4503] refs[t:4504]

git-svn-id: file:///svn/toku/tokudb@40068 c7de825b-a66e-492c-adef-691d508d4ae1
parent aade4f7e
......@@ -324,7 +324,6 @@ struct __toku_db {
DESCRIPTOR descriptor /* saved row/dictionary descriptor for aiding in comparisons */;
int (*change_descriptor) (DB*, DB_TXN*, const DBT* descriptor, u_int32_t) /* change row/dictionary descriptor for a db. Available only while db is open */;
int (*getf_set)(DB*, DB_TXN*, u_int32_t, DBT*, YDB_CALLBACK_FUNCTION, void*) /* same as DBC->c_getf_set without a persistent cursor) */;
int (*flatten)(DB*, DB_TXN*) /* Flatten a dictionary, similar to (but faster than) a table scan */;
int (*optimize)(DB*) /* Run garbage collecion and promote all transactions older than oldest. Amortized (happens during flattening) */;
int (*hot_optimize)(DB*, int (*progress_callback)(void *progress_extra, float progress), void *progress_extra);
int (*get_fragmentation)(DB*,TOKU_DB_FRAGMENTATION);
......@@ -335,7 +334,7 @@ struct __toku_db {
int (*verify_with_progress)(DB *, int (*progress_callback)(void *progress_extra, float progress), void *progress_extra, int verbose, int keep_going);
int (*update)(DB *, DB_TXN*, const DBT *key, const DBT *extra, u_int32_t flags);
int (*update_broadcast)(DB *, DB_TXN*, const DBT *extra, u_int32_t flags);
void* __toku_dummy0[11];
void* __toku_dummy0[12];
char __toku_dummy1[96];
void *api_internal; /* 32-bit offset=236 size=4, 64=bit offset=376 size=8 */
void* __toku_dummy2[5];
......
......@@ -333,7 +333,6 @@ struct __toku_db {
DESCRIPTOR descriptor /* saved row/dictionary descriptor for aiding in comparisons */;
int (*change_descriptor) (DB*, DB_TXN*, const DBT* descriptor, u_int32_t) /* change row/dictionary descriptor for a db. Available only while db is open */;
int (*getf_set)(DB*, DB_TXN*, u_int32_t, DBT*, YDB_CALLBACK_FUNCTION, void*) /* same as DBC->c_getf_set without a persistent cursor) */;
int (*flatten)(DB*, DB_TXN*) /* Flatten a dictionary, similar to (but faster than) a table scan */;
int (*optimize)(DB*) /* Run garbage collecion and promote all transactions older than oldest. Amortized (happens during flattening) */;
int (*hot_optimize)(DB*, int (*progress_callback)(void *progress_extra, float progress), void *progress_extra);
int (*get_fragmentation)(DB*,TOKU_DB_FRAGMENTATION);
......@@ -344,7 +343,7 @@ struct __toku_db {
int (*verify_with_progress)(DB *, int (*progress_callback)(void *progress_extra, float progress), void *progress_extra, int verbose, int keep_going);
int (*update)(DB *, DB_TXN*, const DBT *key, const DBT *extra, u_int32_t flags);
int (*update_broadcast)(DB *, DB_TXN*, const DBT *extra, u_int32_t flags);
void* __toku_dummy0[14];
void* __toku_dummy0[15];
char __toku_dummy1[96];
void *api_internal; /* 32-bit offset=248 size=4, 64=bit offset=400 size=8 */
void* __toku_dummy2[5];
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -599,7 +599,6 @@ int main (int argc __attribute__((__unused__)), char *const argv[] __attribute__
"DESCRIPTOR descriptor /* saved row/dictionary descriptor for aiding in comparisons */",
"int (*change_descriptor) (DB*, DB_TXN*, const DBT* descriptor, u_int32_t) /* change row/dictionary descriptor for a db. Available only while db is open */",
"int (*getf_set)(DB*, DB_TXN*, u_int32_t, DBT*, YDB_CALLBACK_FUNCTION, void*) /* same as DBC->c_getf_set without a persistent cursor) */",
"int (*flatten)(DB*, DB_TXN*) /* Flatten a dictionary, similar to (but faster than) a table scan */",
"int (*optimize)(DB*) /* Run garbage collecion and promote all transactions older than oldest. Amortized (happens during flattening) */",
"int (*hot_optimize)(DB*, int (*progress_callback)(void *progress_extra, float progress), void *progress_extra)",
"int (*get_fragmentation)(DB*,TOKU_DB_FRAGMENTATION)",
......
......@@ -308,7 +308,6 @@ struct __toku_db {
DESCRIPTOR descriptor /* saved row/dictionary descriptor for aiding in comparisons */;
int (*change_descriptor) (DB*, DB_TXN*, const DBT* descriptor, u_int32_t) /* change row/dictionary descriptor for a db. Available only while db is open */;
int (*getf_set)(DB*, DB_TXN*, u_int32_t, DBT*, YDB_CALLBACK_FUNCTION, void*) /* same as DBC->c_getf_set without a persistent cursor) */;
int (*flatten)(DB*, DB_TXN*) /* Flatten a dictionary, similar to (but faster than) a table scan */;
int (*optimize)(DB*) /* Run garbage collecion and promote all transactions older than oldest. Amortized (happens during flattening) */;
int (*hot_optimize)(DB*, int (*progress_callback)(void *progress_extra, float progress), void *progress_extra);
int (*get_fragmentation)(DB*,TOKU_DB_FRAGMENTATION);
......
......@@ -308,7 +308,6 @@ struct __toku_db {
DESCRIPTOR descriptor /* saved row/dictionary descriptor for aiding in comparisons */;
int (*change_descriptor) (DB*, DB_TXN*, const DBT* descriptor, u_int32_t) /* change row/dictionary descriptor for a db. Available only while db is open */;
int (*getf_set)(DB*, DB_TXN*, u_int32_t, DBT*, YDB_CALLBACK_FUNCTION, void*) /* same as DBC->c_getf_set without a persistent cursor) */;
int (*flatten)(DB*, DB_TXN*) /* Flatten a dictionary, similar to (but faster than) a table scan */;
int (*optimize)(DB*) /* Run garbage collecion and promote all transactions older than oldest. Amortized (happens during flattening) */;
int (*hot_optimize)(DB*, int (*progress_callback)(void *progress_extra, float progress), void *progress_extra);
int (*get_fragmentation)(DB*,TOKU_DB_FRAGMENTATION);
......
......@@ -5276,13 +5276,6 @@ brt_search_node(
return r;
}
// When this is called, the cachetable lock is held
static void
unlock_root_tree_lock (void *v) {
struct brt_header* h = v;
toku_brtheader_release_treelock(h);
}
static int
toku_brt_search (BRT brt, brt_search_t *search, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v, BRT_CURSOR brtcursor, BOOL can_bulk_fetch)
// Effect: Perform a search. Associate cursor with a leaf if possible.
......@@ -5332,7 +5325,6 @@ toku_brt_search (BRT brt, brt_search_t *search, BRT_GET_CALLBACK_FUNCTION getf,
u_int32_t fullhash;
CACHEKEY *rootp = toku_calculate_root_offset_pointer(brt->h, &fullhash);
fill_bfe_for_subset_read(
&bfe,
brt->h,
......@@ -5343,22 +5335,15 @@ toku_brt_search (BRT brt, brt_search_t *search, BRT_GET_CALLBACK_FUNCTION getf,
brtcursor->right_is_pos_infty,
brtcursor->disable_prefetching
);
struct unlockers root_unlockers = {
.locked = TRUE,
.f = unlock_root_tree_lock,
.extra = brt->h,
.next = NULL
};
r = toku_pin_brtnode(brt, *rootp, fullhash,&root_unlockers,(ANCESTORS)NULL, &infinite_bounds, &bfe, TRUE, &node);
assert(r==0 || r== TOKUDB_TRY_AGAIN);
if (r == TOKUDB_TRY_AGAIN) {
// unlock_root_tree_lock will have released tree_lock of header
assert(!root_unlockers.locked);
root_tries++;
goto try_again;
}
assert(root_unlockers.locked);
toku_pin_brtnode_off_client_thread(
brt->h,
*rootp,
fullhash,
&bfe,
0,
NULL,
&node
);
toku_brtheader_release_treelock(brt->h);
}
......@@ -5500,31 +5485,6 @@ toku_brt_cursor_current(BRT_CURSOR cursor, int op, BRT_GET_CALLBACK_FUNCTION get
return getf(cursor->key.size, cursor->key.data, cursor->val.size, cursor->val.data, getf_v, false); // brt_cursor_copyout(cursor, outkey, outval);
}
static int
brt_flatten_getf(ITEMLEN UU(keylen), bytevec UU(key),
ITEMLEN UU(vallen), bytevec UU(val),
void *UU(v), bool UU(lock_only)) {
return DB_NOTFOUND;
}
int
toku_brt_flatten(BRT brt, TOKUTXN ttxn)
{
BRT_CURSOR tmp_cursor;
int r = toku_brt_cursor(brt, &tmp_cursor, ttxn, FALSE, FALSE);
if (r!=0) return r;
brt_search_t search; brt_search_init(&search, brt_cursor_compare_one, BRT_SEARCH_LEFT, 0, tmp_cursor->brt);
r = brt_cursor_search(tmp_cursor, &search, brt_flatten_getf, NULL, FALSE);
brt_search_finish(&search);
if (r==DB_NOTFOUND) r = 0;
{
//Cleanup temporary cursor
int r2 = toku_brt_cursor_close(tmp_cursor);
if (r==0) r = r2;
}
return r;
}
int
toku_brt_cursor_first(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v)
{
......@@ -5939,24 +5899,15 @@ toku_brt_keyrange (BRT brt, DBT *key, u_int64_t *less_p, u_int64_t *equal_p, u_i
u_int32_t fullhash;
CACHEKEY *rootp = toku_calculate_root_offset_pointer(brt->h, &fullhash);
{
struct unlockers root_unlockers = {
.locked = TRUE,
.f = unlock_root_tree_lock,
.extra = brt->h,
.next = NULL
};
int r = toku_pin_brtnode(brt, *rootp, fullhash, &root_unlockers,(ANCESTORS)NULL, &infinite_bounds, &bfe, FALSE, &node);
assert(r == 0 || r == TOKUDB_TRY_AGAIN);
if (r == TOKUDB_TRY_AGAIN) {
assert(!root_unlockers.locked);
goto try_again;
}
assert(root_unlockers.locked);
}
toku_pin_brtnode_off_client_thread(
brt->h,
*rootp,
fullhash,
&bfe,
0,
NULL,
&node
);
toku_brtheader_release_treelock(brt->h);
}
......
......@@ -197,7 +197,6 @@ void toku_brt_cursor_set_range_lock(BRT_CURSOR, const DBT *, const DBT *, BOOL,
// get is deprecated in favor of the individual functions below
int toku_brt_cursor_get (BRT_CURSOR cursor, DBT *key, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v, int get_flags) __attribute__ ((warn_unused_result));
int toku_brt_flatten(BRT, TOKUTXN ttxn) __attribute__ ((warn_unused_result));
int toku_brt_cursor_first(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
int toku_brt_cursor_last(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
int toku_brt_cursor_next(BRT_CURSOR cursor, BRT_GET_CALLBACK_FUNCTION getf, void *getf_v) __attribute__ ((warn_unused_result));
......
......@@ -2492,10 +2492,10 @@ int toku_cachetable_get_and_pin_nonblocking (
note_hash_count(count);
//
// In Dr. No, the ydb lock ensures that only one client may be successfully
// doing a query on a dictionary at any given time. This function
// is called with the ydb lock held. This implies that only ONE client can ever be
// in get_and_pin_nonblocking while the ydb lock is held.
// In Doofenshmirts, we keep the root to leaf path pinned
// as we perform a quiry on a dictionary at any given time.
// This implies that only ONE query client can ever be
// in get_and_pin_nonblocking for this dictionary.
// So, if there is a write lock grabbed
// on the PAIR that we want to lock, then some expensive operation
// MUST be happening (read from disk, write to disk, flush, etc...),
......@@ -2516,13 +2516,9 @@ int toku_cachetable_get_and_pin_nonblocking (
if (partial_fetch_required) {
p->state = CTPAIR_READING;
run_unlockers(unlockers); // The contract says the unlockers are run with the ct lock being held.
if (ct->ydb_unlock_callback) ct->ydb_unlock_callback();
// Now wait for the I/O to occur.
// Now wait for the I/O to occur.
do_partial_fetch(ct, cf, p, pf_callback, read_extraargs, FALSE);
cachetable_unlock(ct);
if (ct->ydb_lock_callback) ct->ydb_lock_callback();
return TOKUDB_TRY_AGAIN;
}
pair_touch(p);
......@@ -2535,7 +2531,6 @@ int toku_cachetable_get_and_pin_nonblocking (
}
else {
run_unlockers(unlockers); // The contract says the unlockers are run with the ct lock being held.
if (ct->ydb_unlock_callback) ct->ydb_unlock_callback();
// Now wait for the I/O to occur.
// We need to obtain the lock (waiting for the write to finish), but then we only waited so we could wake up again
if (p->checkpoint_pending) {
......@@ -2578,7 +2573,6 @@ int toku_cachetable_get_and_pin_nonblocking (
}
}
cachetable_unlock(ct);
if (ct->ydb_lock_callback) ct->ydb_lock_callback();
return TOKUDB_TRY_AGAIN;
}
}
......@@ -2600,13 +2594,11 @@ int toku_cachetable_get_and_pin_nonblocking (
assert(p);
nb_mutex_write_lock(&p->nb_mutex, ct->mutex);
run_unlockers(unlockers); // we hold the ct mutex.
if (ct->ydb_unlock_callback) ct->ydb_unlock_callback();
u_int64_t t0 = get_tnow();
cachetable_fetch_pair(ct, cf, p, fetch_callback, read_extraargs, FALSE);
cachetable_miss++;
cachetable_misstime += get_tnow() - t0;
cachetable_unlock(ct);
if (ct->ydb_lock_callback) ct->ydb_lock_callback();
return TOKUDB_TRY_AGAIN;
}
......
......@@ -21,6 +21,11 @@ endif
OBJS_RAW = \
ydb_lib \
ydb \
ydb_cursor \
ydb_row_lock \
ydb_env_func \
ydb_write \
ydb_db \
errors \
dlmalloc \
loader \
......
......@@ -131,9 +131,4 @@ toku_ydb_unlock_and_yield(unsigned long useconds) {
ydb_unlock_internal(useconds);
}
toku_pthread_mutex_t *
toku_ydb_mutex(void) {
return &ydb_big_lock.lock;
}
#undef STATUS_VALUE
......@@ -20,6 +20,7 @@
#include "leafentry.h"
#include "ule.h"
#include "xids.h"
#include "ydb_row_lock.h"
#include "indexer-internal.h"
......
......@@ -20,6 +20,7 @@
#include "ydb_load.h"
#include "checkpoint.h"
#include "brt-internal.h"
#include "ydb_db.h"
#define lazy_assert(a) assert(a) // indicates code is incomplete
......@@ -239,7 +240,7 @@ int toku_loader_create_loader(DB_ENV *env,
}
// time to open the big kahuna
if ( loader->i->loader_flags & LOADER_USE_PUTS ) {
if ( FALSE && (loader->i->loader_flags & LOADER_USE_PUTS) ) {
XCALLOC_N(loader->i->N, loader->i->ekeys);
XCALLOC_N(loader->i->N, loader->i->evals);
for (int i=0; i<N; i++) {
......@@ -338,7 +339,7 @@ int toku_loader_put(DB_LOADER *loader, DBT *key, DBT *val)
goto cleanup;
}
if ( loader->i->loader_flags & LOADER_USE_PUTS ) {
if ( FALSE && (loader->i->loader_flags & LOADER_USE_PUTS) ) {
r = loader->i->env->put_multiple(loader->i->env,
loader->i->src_db, // src_db
loader->i->txn,
......@@ -389,7 +390,7 @@ int toku_loader_close(DB_LOADER *loader)
if ( loader->i->error_callback != NULL ) {
loader->i->error_callback(loader->i->dbs[loader->i->err_i], loader->i->err_i, loader->i->err_errno, &loader->i->err_key, &loader->i->err_val, loader->i->error_extra);
}
if ( !(loader->i->loader_flags & LOADER_USE_PUTS ) ) {
if (TRUE || !(loader->i->loader_flags & LOADER_USE_PUTS ) ) {
r = toku_brt_loader_abort(loader->i->brt_loader, TRUE);
}
else {
......@@ -397,7 +398,7 @@ int toku_loader_close(DB_LOADER *loader)
}
}
else { // no error outstanding
if ( !(loader->i->loader_flags & LOADER_USE_PUTS ) ) {
if (TRUE || !(loader->i->loader_flags & LOADER_USE_PUTS ) ) {
// use the bulk loader
// in case you've been looking - here is where the real work is done!
r = toku_brt_loader_close(loader->i->brt_loader,
......@@ -436,7 +437,7 @@ int toku_loader_abort(DB_LOADER *loader)
}
}
if ( !(loader->i->loader_flags & LOADER_USE_PUTS) ) {
if (TRUE || !(loader->i->loader_flags & LOADER_USE_PUTS) ) {
r = toku_brt_loader_abort(loader->i->brt_loader, TRUE);
}
toku_ydb_lock();
......
This diff is collapsed.
This diff is collapsed.
......@@ -38,11 +38,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
DB *db_a = (DB *) 2;
......@@ -55,7 +55,7 @@ int main(int argc, const char *argv[]) {
}
// release the locks
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -47,7 +47,7 @@ struct test_arg {
uint64_t iterations;
};
static void runtest(DB *db, TXNID txn, toku_ltm *ltm, toku_lock_tree *lt, uint64_t locks_per_txn, uint64_t nrows, uint64_t iterations) {
static void runtest(DB *db, TXNID txn, toku_ltm *ltm UU(), toku_lock_tree *lt, uint64_t locks_per_txn, uint64_t nrows, uint64_t iterations) {
int r;
uint64_t notgranted = 0, deadlocked = 0;
......@@ -60,9 +60,7 @@ static void runtest(DB *db, TXNID txn, toku_ltm *ltm, toku_lock_tree *lt, uint64
DBT key = { .data = &keys[i], .size = sizeof keys[i] };
toku_lock_request lr;
toku_lock_request_init(&lr, db, txn, &key, &key, LOCK_REQUEST_WRITE);
toku_ltm_lock_mutex(ltm);
r = toku_lt_acquire_lock_request_with_default_timeout_locked(lt, &lr);
toku_ltm_unlock_mutex(ltm);
r = toku_lt_acquire_lock_request_with_default_timeout(lt, &lr);
if (r == 0) {
get_lock(keys[i], txn);
continue;
......@@ -80,9 +78,7 @@ static void runtest(DB *db, TXNID txn, toku_ltm *ltm, toku_lock_tree *lt, uint64
// usleep(random() % 1000);
release_locks(keys, i, txn);
toku_ltm_lock_mutex(ltm);
r = toku_lt_unlock(lt, txn); assert(r == 0);
toku_ltm_unlock_mutex(ltm);
r = toku_lt_unlock_txn(lt, txn); assert(r == 0);
if ((iter % 10000) == 0)
printf("%lu %lu %lu\n", (long unsigned) iter, (long unsigned) notgranted, (long unsigned) deadlocked);
......@@ -143,11 +139,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
DB *fake_db = (DB *) 1;
......
......@@ -33,12 +33,6 @@ static inline int dbcmp (DB *db __attribute__((__unused__)), const DBT *a, const
return toku_keycompare(a->data, a->size, b->data, b->size);
}
toku_dbt_cmp compare_fun = dbcmp;
static inline toku_dbt_cmp get_compare_fun_from_db(__attribute__((unused)) DB* db) {
return compare_fun;
}
bool panicked = false;
static inline int dbpanic(DB* db, int r) {
......
......@@ -7,13 +7,11 @@ int main(void) {
uint32_t max_locks = 1000;
uint64_t max_lock_memory = max_locks*64;
r = toku_ltm_create(&mgr, max_locks, max_lock_memory, dbpanic,
get_compare_fun_from_db);
r = toku_ltm_create(&mgr, max_locks, max_lock_memory, dbpanic);
CKERR(r);
{
r = toku_lt_create(&lt, dbpanic, mgr,
get_compare_fun_from_db);
r = toku_lt_create(&lt, mgr, dbcmp);
CKERR(r);
assert(lt);
r = toku_lt_close(lt);
......
......@@ -22,7 +22,7 @@ static void do_range_test(int (*acquire)(toku_lock_tree*, DB*, TXNID,
DBT* key_l = &_key_l;
DBT* key_r = &_key_r;
{
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
CKERR(r);
assert(lt);
......@@ -64,11 +64,11 @@ static void do_point_test(int (*acquire)(toku_lock_tree*, DB*, TXNID,
/* Point read tests. */
key = &_key;
{
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
CKERR(r);
assert(lt);
r = toku_lt_unlock(NULL, (TXNID)1);
r = toku_lt_unlock_txn(NULL, (TXNID)1);
CKERR2(r, EINVAL);
r = acquire(NULL, db, txn, key);
......@@ -91,18 +91,18 @@ int main(int argc, const char *argv[]) {
int r;
toku_lock_tree* lt = NULL;
r = toku_ltm_create(NULL, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(NULL, max_locks, max_lock_memory, dbpanic);
CKERR2(r, EINVAL);
assert(ltm == NULL);
r = toku_ltm_create(&ltm, 0, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, 0, max_lock_memory, dbpanic);
CKERR2(r, EINVAL);
assert(ltm == NULL);
r = toku_ltm_create(&ltm, max_locks, 0, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, 0, dbpanic);
CKERR2(r, EINVAL);
assert(ltm == NULL);
/* Actually create it. */
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
......@@ -144,17 +144,12 @@ int main(int argc, const char *argv[]) {
/* create tests. */
{
r = toku_lt_create(NULL, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(NULL, ltm, dbcmp);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, NULL, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, NULL, dbcmp);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, NULL, get_compare_fun_from_db);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, ltm, NULL);
CKERR2(r, EINVAL);
}
/* Close tests. */
......
......@@ -42,17 +42,17 @@ static void init_query(void) {
static void setup_tree(void) {
assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
CKERR(r);
assert(lt);
init_query();
}
static void close_tree(void) {
r = toku_lt_unlock(lt, txn); CKERR(r);
r = toku_lt_unlock_txn(lt, txn); CKERR(r);
assert(lt && ltm);
r = toku_lt_close(lt); CKERR(r);
r = toku_ltm_close(ltm); CKERR(r);
......@@ -103,22 +103,9 @@ static void setup_payload_len(void** payload, uint32_t* len, int val) {
}
}
static void temporarily_fake_comparison_functions(void) {
assert(!lt->db && !lt->compare_fun);
lt->db = db;
lt->compare_fun = get_compare_fun_from_db(db);
}
static void stop_fake_comparison_functions(void) {
assert(lt->db && lt->compare_fun);
lt->db = NULL;
lt->compare_fun = NULL;
}
static void lt_find(toku_range_tree* rt,
unsigned k, int key_l, int key_r,
TXNID find_txn) {
temporarily_fake_comparison_functions();
r = toku_rt_find(rt, &query, 0, &buf, &buflen, &numfound);
CKERR(r);
assert(numfound==k);
......@@ -136,9 +123,8 @@ temporarily_fake_comparison_functions();
}
assert(false); //Crash since we didn't find it.
cleanup:
stop_fake_comparison_functions();
}
return;
}
static void insert_1(int key_l, int key_r,
const void* kl, const void* kr) {
......
......@@ -36,10 +36,10 @@ static void init_query(void) {
static void setup_tree(void) {
assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
CKERR(r);
assert(lt);
init_query();
......@@ -102,7 +102,7 @@ static void lt_insert_write(int r_expect, char txn, int key_l) {
static void lt_unlock(char ctxn) {
int retval;
retval = toku_lt_unlock(lt, (TXNID) (size_t) ctxn);
retval = toku_lt_unlock_txn(lt, (TXNID) (size_t) ctxn);
CKERR(retval);
}
......
......@@ -37,12 +37,12 @@ static void init_query(void) {
static void setup_tree(void) {
assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
//ask ltm for lock tree
DICTIONARY_ID dict_id = {0x1234};
r = toku_ltm_get_lt(ltm, &lt, dict_id, db);
r = toku_ltm_get_lt(ltm, &lt, dict_id, db, intcmp);
CKERR(r);
assert(lt);
......@@ -108,7 +108,7 @@ static void lt_insert_write(int r_expect, char txn, int key_l) {
}
static void lt_unlock(char ctxn) {
int retval = toku_lt_unlock(lt, (TXNID) (size_t) ctxn); CKERR(retval);
int retval = toku_lt_unlock_txn(lt, (TXNID) (size_t) ctxn); CKERR(retval);
}
static void run_escalation_test(void) {
......@@ -370,7 +370,6 @@ static void init_test(void) {
buflen = 64;
buf = (toku_range*) toku_malloc(buflen*sizeof(toku_range));
compare_fun = intcmp;
}
static void close_test(void) {
......
......@@ -17,14 +17,14 @@ int nums[10000];
static void setup_ltm(void) {
assert(!ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
}
static void setup_tree(size_t index, DICTIONARY_ID dict_id) {
assert(!lt[index] && ltm);
r = toku_ltm_get_lt(ltm, &lt[index], dict_id, NULL);
r = toku_ltm_get_lt(ltm, &lt[index], dict_id, NULL, intcmp);
CKERR(r);
assert(lt[index]);
}
......@@ -67,7 +67,6 @@ static void run_test(void) {
int main(int argc, const char *argv[]) {
parse_args(argc, argv);
compare_fun = intcmp;
r = system("rm -rf " TESTDIR);
CKERR(r);
......
......@@ -20,7 +20,7 @@ int nums[10000];
static void setup_ltm(void) {
assert(!ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
}
......@@ -30,7 +30,7 @@ static void db_open_tree(size_t index, size_t db_id_index) {
(lt_refs[index] > 0 && lts[index]));
assert(ltm);
lt_refs[index]++;
r = toku_ltm_get_lt(ltm, &lts[index], dict_ids[db_id_index], NULL);
r = toku_ltm_get_lt(ltm, &lts[index], dict_ids[db_id_index], NULL, intcmp);
CKERR(r);
assert(lts[index]);
}
......@@ -136,7 +136,6 @@ static void close_test(void) {
int main(int argc, const char *argv[]) {
parse_args(argc, argv);
compare_fun = intcmp;
r = system("rm -rf " TESTDIR);
CKERR(r);
......
......@@ -36,10 +36,10 @@ static void init_query(void) {
static void setup_tree(void) {
assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
CKERR(r);
assert(lt);
init_query();
......@@ -87,7 +87,7 @@ static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r)
}
static void lt_unlock(TXNID txnid) {
r= toku_lt_unlock(lt, txnid); CKERR(r);
r= toku_lt_unlock_txn(lt, txnid); CKERR(r);
}
static void runtest(void) {
......
......@@ -43,11 +43,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
DBT key_l; dbt_init(&key_l, "L", 1);
......@@ -90,7 +90,7 @@ int main(int argc, const char *argv[]) {
assert(txnid_set_get(&conflicts, 1) == txn_b);
txnid_set_destroy(&conflicts);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
assert(c_w_l.state == LOCK_REQUEST_PENDING);
txnid_set_init(&conflicts);
r = toku_lt_get_lock_request_conflicts(lt, &c_w_l, &conflicts);
......@@ -99,10 +99,10 @@ int main(int argc, const char *argv[]) {
assert(txnid_set_get(&conflicts, 0) == txn_b);
txnid_set_destroy(&conflicts);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
assert(c_w_l.state == LOCK_REQUEST_COMPLETE && c_w_l.complete_r == 0);
toku_lock_request_destroy(&c_w_l);
r = toku_lt_unlock(lt, txn_c); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_c); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -43,11 +43,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
DBT key_l; dbt_init(&key_l, "L", 1);
......@@ -91,7 +91,7 @@ int main(int argc, const char *argv[]) {
assert(txnid_set_get(&conflicts, 1) == txn_b);
txnid_set_destroy(&conflicts);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
assert(c_w_l.state == LOCK_REQUEST_PENDING);
txnid_set_init(&conflicts);
r = toku_lt_get_lock_request_conflicts(lt, &c_w_l, &conflicts);
......@@ -100,10 +100,10 @@ int main(int argc, const char *argv[]) {
assert(txnid_set_get(&conflicts, 0) == txn_b);
txnid_set_destroy(&conflicts);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
assert(c_w_l.state == LOCK_REQUEST_COMPLETE && c_w_l.complete_r == 0);
toku_lock_request_destroy(&c_w_l);
r = toku_lt_unlock(lt, txn_c); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_c); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -68,10 +68,10 @@ int main(int argc, const char *argv[]) {
assert(txnid_set_get(&conflicts, 0) == txn_a);
txnid_set_destroy(&conflicts);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
assert(b_r_l.state == LOCK_REQUEST_COMPLETE && b_r_l.complete_r == 0);
toku_lock_request_destroy(&b_r_l);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
DBT key_l; dbt_init(&key_l, "L", 1);
......@@ -70,8 +70,8 @@ int main(int argc, const char *argv[]) {
txnid_set_destroy(&conflicts);
toku_lock_request_destroy(&b_r_l);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
DBT key_l; dbt_init(&key_l, "L", 1);
......@@ -71,7 +71,7 @@ int main(int argc, const char *argv[]) {
toku_lock_request_destroy(&b_w_l);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -50,11 +50,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -68,7 +68,7 @@ int main(int argc, const char *argv[]) {
r = write_lock(lt, txn_b, "L");
assert(r == DB_LOCK_NOTGRANTED);
}
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -30,7 +30,7 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
uint64_t target_wait_time, the_wait_time;
......
......@@ -93,7 +93,7 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
struct my_ltm_status s;
......@@ -104,7 +104,7 @@ int main(int argc, const char *argv[]) {
assert(s.curr_lock_memory == 0);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
DB *db_a = (DB *) 2;
......@@ -135,7 +135,7 @@ int main(int argc, const char *argv[]) {
// release the locks
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
my_ltm_get_status(ltm, &s);
assert(s.curr_locks == 0);
......
......@@ -95,7 +95,7 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
struct my_ltm_status s;
......@@ -106,7 +106,7 @@ int main(int argc, const char *argv[]) {
assert(s.curr_lock_memory == 0);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
DB *db_a = (DB *) 2;
......@@ -139,7 +139,7 @@ int main(int argc, const char *argv[]) {
// release the locks
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
my_ltm_get_status(ltm, &s);
assert(s.curr_locks == 0);
......
......@@ -36,10 +36,10 @@ static void init_query(void) {
static void setup_tree(void) {
assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
CKERR(r);
assert(lt);
init_query();
......@@ -103,7 +103,7 @@ static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r)
}
static void lt_unlock(TXNID txnid) {
r = toku_lt_unlock(lt, txnid); CKERR(r);
r = toku_lt_unlock_txn(lt, txnid); CKERR(r);
}
static void runtest(void) {
......
......@@ -50,11 +50,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -68,7 +68,7 @@ int main(int argc, const char *argv[]) {
r = write_lock(lt, txn_b, "L", &wait_time);
assert(r == DB_LOCK_NOTGRANTED);
}
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -20,7 +20,7 @@ int main(int argc, const char *argv[]) {
int r;
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, MAX_LOCKS, MAX_LOCK_MEMORY, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, MAX_LOCKS, MAX_LOCK_MEMORY, dbpanic);
CKERR(r);
do_ltm_status(ltm);
#if 0
......@@ -63,17 +63,17 @@ int main(int argc, const char *argv[]) {
/* create tests. */
{
r = toku_lt_create(NULL, dbpanic, ltm,
get_compare_fun_from_db,
dbcmp,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, NULL, ltm,
get_compare_fun_from_db,
dbcmp,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, NULL,
get_compare_fun_from_db,
dbcmp,
toku_malloc, toku_free, toku_realloc);
CKERR2(r, EINVAL);
......@@ -83,15 +83,15 @@ int main(int argc, const char *argv[]) {
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, ltm,
get_compare_fun_from_db,
dbcmp,
NULL, toku_free, toku_realloc);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, ltm,
get_compare_fun_from_db,
dbcmp,
toku_malloc, NULL, toku_realloc);
CKERR2(r, EINVAL);
r = toku_lt_create(&lt, dbpanic, ltm,
get_compare_fun_from_db,
dbcmp,
toku_malloc, toku_free, NULL);
CKERR2(r, EINVAL);
}
......
......@@ -49,11 +49,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -65,11 +65,11 @@ int main(int argc, const char *argv[]) {
const TXNID txn_c = 3;
r = read_lock(lt, txn_c, "L"); assert(r == DB_LOCK_NOTGRANTED);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
r = read_lock(lt, txn_b, "L"); assert(r == 0);
r = read_lock(lt, txn_c, "L"); assert(r == 0);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock(lt, txn_c); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_c); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -38,11 +38,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -62,13 +62,13 @@ int main(int argc, const char *argv[]) {
r = toku_lock_request_start(&c_w_l, lt, false); assert(r != 0);
assert(c_w_l.state == LOCK_REQUEST_PENDING);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
assert(b_w_l.state == LOCK_REQUEST_COMPLETE && b_w_l.complete_r == 0);
assert(c_w_l.state == LOCK_REQUEST_COMPLETE && c_w_l.complete_r == TOKUDB_OUT_OF_LOCKS);
toku_lock_request_destroy(&b_w_l);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
toku_lock_request_destroy(&c_w_l);
r = toku_lt_unlock(lt, txn_c); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_c); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -37,11 +37,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -61,13 +61,13 @@ int main(int argc, const char *argv[]) {
r = toku_lock_request_start(&c_w_l, lt, false); assert(r != 0);
assert(c_w_l.state == LOCK_REQUEST_PENDING);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
assert(b_w_l.state == LOCK_REQUEST_COMPLETE && b_w_l.complete_r == 0);
assert(c_w_l.state == LOCK_REQUEST_COMPLETE && c_w_l.complete_r == 0);;
toku_lock_request_destroy(&b_w_l);
toku_lock_request_destroy(&c_w_l);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock(lt, txn_c); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_c); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
// verify that a user supplied mutex works
// T(A) gets W(L)
// T(B) tries W(L), gets lock request blocked
// T(B) lock request W(L) times out
// T(A) releases locks
// T(B) releases locks
#include "test.h"
int
main(int argc, const char *argv[]) {
int r;
uint32_t max_locks = 2;
uint64_t max_lock_memory = 4096;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
if (verbose > 0) verbose++;
continue;
}
if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0) {
if (verbose > 0) verbose--;
continue;
}
if (strcmp(argv[i], "--max_locks") == 0 && i+1 < argc) {
max_locks = atoi(argv[++i]);
continue;
}
if (strcmp(argv[i], "--max_lock_memory") == 0 && i+1 < argc) {
max_lock_memory = atoi(argv[++i]);
continue;
}
assert(0);
}
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm);
toku_ltm_set_lock_wait_time(ltm, 5000);
toku_pthread_mutex_t my_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER;
toku_ltm_set_mutex(ltm, &my_mutex);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt);
const TXNID txn_a = 1;
const TXNID txn_b = 2;
DBT key_l; dbt_init(&key_l, "L", 1);
toku_lock_request a_w_l; toku_lock_request_init(&a_w_l, (DB *)1, txn_a, &key_l, &key_l, LOCK_REQUEST_WRITE);
toku_ltm_lock_mutex(ltm);
r = toku_lock_request_start_locked(&a_w_l, lt, false); assert(r == 0);
toku_ltm_unlock_mutex(ltm);
assert(a_w_l.state == LOCK_REQUEST_COMPLETE && a_w_l.complete_r == 0);
toku_lock_request b_w_l; toku_lock_request_init(&b_w_l, (DB *)1, txn_b, &key_l, &key_l, LOCK_REQUEST_WRITE);
toku_ltm_lock_mutex(ltm);
r = toku_lock_request_start_locked(&b_w_l, lt, false); assert(r != 0);
toku_ltm_unlock_mutex(ltm);
assert(b_w_l.state == LOCK_REQUEST_PENDING);
toku_ltm_lock_mutex(ltm);
r = toku_lock_request_wait_with_default_timeout(&b_w_l, lt);
toku_ltm_unlock_mutex(ltm);
assert(r == DB_LOCK_NOTGRANTED);
assert(b_w_l.state == LOCK_REQUEST_COMPLETE);
toku_lock_request_destroy(&a_w_l);
toku_lock_request_destroy(&b_w_l);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
r = toku_ltm_close(ltm); assert(r == 0);
return 0;
}
// T(A) gets W(L)
// T(B) tries W(L) with timeout, gets DB_LOCK_NOTGRANTED
// T(B) releases locks
#include "test.h"
static int read_lock(toku_ltm *ltm, toku_lock_tree *lt, TXNID txnid, char *k) {
DBT key; dbt_init(&key, k, strlen(k));
toku_lock_request lr;
toku_lock_request_init(&lr, (DB*)1, txnid, &key, &key, LOCK_REQUEST_READ);
toku_ltm_lock_mutex(ltm);
int r = toku_lt_acquire_lock_request_with_default_timeout_locked(lt, &lr);
toku_ltm_unlock_mutex(ltm);
toku_lock_request_destroy(&lr);
return r;
}
static int write_lock(toku_ltm *ltm, toku_lock_tree *lt, TXNID txnid, char *k) {
DBT key; dbt_init(&key, k, strlen(k));
toku_lock_request lr;
toku_lock_request_init(&lr, (DB*)1, txnid, &key, &key, LOCK_REQUEST_WRITE);
toku_ltm_lock_mutex(ltm);
int r = toku_lt_acquire_lock_request_with_default_timeout_locked(lt, &lr);
toku_ltm_unlock_mutex(ltm);
toku_lock_request_destroy(&lr);
return r;
}
int main(int argc, const char *argv[]) {
int r;
uint32_t max_locks = 1;
uint64_t max_lock_memory = 4096;
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
verbose++;
continue;
}
if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0) {
if (verbose > 0) verbose--;
continue;
}
if (strcmp(argv[i], "--max_locks") == 0 && i+1 < argc) {
max_locks = atoi(argv[++i]);
continue;
}
if (strcmp(argv[i], "--max_lock_memory") == 0 && i+1 < argc) {
max_lock_memory = atoi(argv[++i]);
continue;
}
assert(0);
}
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
assert(r == 0 && ltm);
toku_pthread_mutex_t my_mutex = TOKU_PTHREAD_MUTEX_INITIALIZER;
toku_ltm_set_mutex(ltm, &my_mutex);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
assert(r == 0 && lt);
const TXNID txn_a = 1;
const TXNID txn_b = 2;
r = write_lock(ltm, lt, txn_a, "L"); assert(r == 0);
for (int t = 1; t < 10; t++) {
toku_ltm_set_lock_wait_time(ltm, t * 1000);
r = read_lock(ltm, lt, txn_b, "L");
assert(r == DB_LOCK_NOTGRANTED);
r = write_lock(ltm, lt, txn_b, "L");
assert(r == DB_LOCK_NOTGRANTED);
}
toku_ltm_lock_mutex(ltm);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
toku_ltm_unlock_mutex(ltm);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
r = toku_ltm_close(ltm); assert(r == 0);
return 0;
}
......@@ -36,11 +36,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -65,14 +65,14 @@ int main(int argc, const char *argv[]) {
r = toku_lock_request_start(&b_w_l, lt, false); assert(r == DB_LOCK_DEADLOCK);
assert(b_w_l.state == LOCK_REQUEST_COMPLETE && b_w_l.complete_r == DB_LOCK_DEADLOCK);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
toku_lock_request_destroy(&b_w_l);
assert(a_w_m.state == LOCK_REQUEST_COMPLETE && a_w_m.complete_r == 0
);
toku_lock_request_destroy(&a_w_m);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -36,11 +36,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -64,13 +64,13 @@ int main(int argc, const char *argv[]) {
r = toku_lock_request_start(&b_w_l, lt, false); assert(r == DB_LOCK_DEADLOCK);
assert(b_w_l.state == LOCK_REQUEST_COMPLETE && b_w_l.complete_r == DB_LOCK_DEADLOCK);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
toku_lock_request_destroy(&b_w_l);
assert(a_w_l.state == LOCK_REQUEST_COMPLETE && a_w_l.complete_r == 0);
toku_lock_request_destroy(&a_w_l);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -36,11 +36,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -64,13 +64,13 @@ int main(int argc, const char *argv[]) {
r = toku_lock_request_start(&b_w_l, lt, true); assert(r == DB_LOCK_DEADLOCK);
assert(b_w_l.state == LOCK_REQUEST_COMPLETE && b_w_l.complete_r == DB_LOCK_DEADLOCK);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
toku_lock_request_destroy(&b_w_l);
assert(a_w_l.state == LOCK_REQUEST_COMPLETE && a_w_l.complete_r == 0);
toku_lock_request_destroy(&a_w_l);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -27,7 +27,7 @@ static void *writer_thread(void *arg) {
int r = write_lock(writer_arg->lt, writer_arg->id, writer_arg->name); assert(r == 0);
printf("%lu locked\n", writer_arg->id);
sleep(1);
toku_lt_unlock(writer_arg->lt, writer_arg->id);
toku_lt_unlock_txn(writer_arg->lt, writer_arg->id);
printf("%lu unlocked\n", writer_arg->id);
return arg;
}
......@@ -65,11 +65,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -84,7 +84,7 @@ int main(int argc, const char *argv[]) {
r = toku_pthread_create(&tids[i], NULL, writer_thread, writer_arg); assert(r == 0);
}
sleep(10);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
printf("main unlocked\n");
for (int i = 0; i < max_threads; i++) {
......
......@@ -40,11 +40,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -52,9 +52,9 @@ int main(int argc, const char *argv[]) {
r = write_lock(lt, txn_a, "L"); assert(r == 0);
r = write_lock(lt, txn_b, "L"); assert(r == DB_LOCK_NOTGRANTED);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
r = write_lock(lt, txn_b, "L"); assert(r == 0);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -36,10 +36,10 @@ static void init_query(void) {
static void setup_tree(void) {
assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
CKERR(r);
assert(lt);
init_query();
......@@ -125,7 +125,7 @@ static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r)
static void lt_unlock(char ctxn) UU();
static void lt_unlock(char ctxn) {
int retval;
retval = toku_lt_unlock(lt, (TXNID) (size_t) ctxn);
retval = toku_lt_unlock_txn(lt, (TXNID) (size_t) ctxn);
CKERR(retval);
}
......
......@@ -36,10 +36,10 @@ static void init_query(void) {
static void setup_tree(void) {
assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
CKERR(r);
assert(lt);
init_query();
......@@ -101,7 +101,7 @@ static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r)
static void lt_unlock(char ctxn) UU();
static void lt_unlock(char ctxn) {
int retval;
retval = toku_lt_unlock(lt, (TXNID) (size_t) ctxn);
retval = toku_lt_unlock_txn(lt, (TXNID) (size_t) ctxn);
CKERR(retval);
}
......
......@@ -36,10 +36,10 @@ static void init_query(void) {
static void setup_tree(void) {
assert(!lt && !ltm);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
CKERR(r);
assert(ltm);
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
CKERR(r);
assert(lt);
init_query();
......@@ -102,7 +102,7 @@ static void lt_insert_write_range(int r_expect, char txn, int key_l, int key_r)
static void lt_unlock(char ctxn) UU();
static void lt_unlock(char ctxn) {
int retval;
retval = toku_lt_unlock(lt, (TXNID) (size_t) ctxn);
retval = toku_lt_unlock_txn(lt, (TXNID) (size_t) ctxn);
CKERR(retval);
}
......
......@@ -34,11 +34,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -54,10 +54,10 @@ int main(int argc, const char *argv[]) {
r = toku_lock_request_start(&b_w_l, lt, false); assert(r != 0);
assert(b_w_l.state == LOCK_REQUEST_PENDING);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
assert(b_w_l.state == LOCK_REQUEST_COMPLETE && b_w_l.complete_r == 0);
toku_lock_request_destroy(&b_w_l);
r = toku_lt_unlock(lt, txn_b); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_b); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -33,11 +33,11 @@ int main(int argc, const char *argv[]) {
// setup
toku_ltm *ltm = NULL;
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic, get_compare_fun_from_db);
r = toku_ltm_create(&ltm, max_locks, max_lock_memory, dbpanic);
assert(r == 0 && ltm);
toku_lock_tree *lt = NULL;
r = toku_lt_create(&lt, dbpanic, ltm, get_compare_fun_from_db);
r = toku_lt_create(&lt, ltm, dbcmp);
assert(r == 0 && lt);
const TXNID txn_a = 1;
......@@ -57,7 +57,7 @@ int main(int argc, const char *argv[]) {
assert(a_w_l_2.state == LOCK_REQUEST_COMPLETE && a_w_l_2.complete_r == 0);
toku_lock_request_destroy(&a_w_l_2);
r = toku_lt_unlock(lt, txn_a); assert(r == 0);
r = toku_lt_unlock_txn(lt, txn_a); assert(r == 0);
// shutdown
r = toku_lt_close(lt); assert(r == 0);
......
......@@ -215,8 +215,6 @@ toku_rt_insert(toku_range_tree* tree, toku_range* range) {
insert_range = toku_xmalloc(sizeof *insert_range);
*insert_range = *range;
size_t start_omt_size = toku_omt_memory_size(tree->i.omt);
static int count = 0;
count++;
r = toku_omt_insert_at(tree->i.omt, insert_range, index);
assert_zero(r);
size_t end_omt_size = toku_omt_memory_size(tree->i.omt);
......
......@@ -178,6 +178,7 @@ BDB_DONTRUN_TESTS = \
perf_malloc_free \
perf_nop \
perf_ptquery \
perf_ptquery2 \
perf_xmalloc_free \
prelock-read-read \
prelock-read-write \
......
// verify that cursor deletes without write locks can detect deadlocks.
#include "test.h"
#include "toku_pthread.h"
static void populate(DB_ENV *db_env, DB *db, uint64_t nrows) {
int r;
DB_TXN *txn = NULL;
r = db_env->txn_begin(db_env, NULL, &txn, 0); assert(r == 0);
for (uint64_t i = 0; i < nrows; i++) {
uint64_t k = htonl(i);
uint64_t v = i;
DBT key = { .data = &k, .size = sizeof k };
DBT val = { .data = &v, .size = sizeof v };
r = db->put(db, txn, &key, &val, 0); assert(r == 0);
}
r = txn->commit(txn, 0); assert(r == 0);
}
struct my_callback_context {
DBT key;
DBT val;
};
#if TOKUDB
static void copy_dbt(DBT *dest, DBT const *src) {
assert(dest->flags == DB_DBT_REALLOC);
dest->size = src->size;
dest->data = toku_xrealloc(dest->data, dest->size);
memcpy(dest->data, src->data, dest->size);
}
static int blocking_c_del_callback(DBT const *a UU(), DBT const *b UU(), void *e UU()) {
DBT const *found_key = a;
DBT const *found_val = b;
struct my_callback_context *context = (struct my_callback_context *) e;
copy_dbt(&context->key, found_key);
copy_dbt(&context->val, found_val);
return 0;
}
#endif
static void blocking_c_del(DB_ENV *db_env, DB *db, uint64_t nrows, long sleeptime) {
int r;
struct my_callback_context context;
context.key = (DBT) { .data = NULL, .size = 0, .flags = DB_DBT_REALLOC };
context.val = (DBT) { .data = NULL, .size = 0, .flags = DB_DBT_REALLOC };
for (uint64_t i = 0; i < nrows; i++) {
DB_TXN *txn = NULL;
r = db_env->txn_begin(db_env, NULL, &txn, 0); assert(r == 0);
DBC *cursor = NULL;
r = db->cursor(db, txn, &cursor, 0); assert(r == 0);
uint64_t k = htonl(i);
DBT key = { .data = &k, .size = sizeof k };
#if TOKUDB
r = cursor->c_getf_set(cursor, 0, &key, blocking_c_del_callback, &context);
#else
r = cursor->c_get(cursor, &key, &context.val, DB_SET);
#endif
assert(r == 0 || r == DB_NOTFOUND);
if (r == 0) {
usleep(sleeptime);
if (verbose) {
uint64_t kk;
#if TOKUDB
assert(context.key.size == sizeof kk);
memcpy(&kk, context.key.data, sizeof kk);
#else
assert(key.size == sizeof kk);
memcpy(&kk, key.data, sizeof kk);
#endif
printf("%lu deleting %lu\n", toku_pthread_self(), (long unsigned) htonl(kk));
}
r = cursor->c_del(cursor, 0);
assert(r == 0 || r == DB_LOCK_DEADLOCK);
}
{ int rr = cursor->c_close(cursor); assert(rr == 0); }
if (r == 0) {
if (verbose) printf("%lu commit\n", toku_pthread_self());
r = txn->commit(txn, 0);
} else {
if (verbose) printf("%lu abort\n", toku_pthread_self());
r = txn->abort(txn);
}
assert(r == 0);
if (verbose)
printf("%lu %lu\n", toku_pthread_self(), i);
}
toku_free(context.key.data);
toku_free(context.val.data);
}
struct blocking_c_del_args {
DB_ENV *db_env;
DB *db;
uint64_t nrows;
long sleeptime;
};
static void *blocking_c_del_thread(void *arg) {
struct blocking_c_del_args *a = (struct blocking_c_del_args *) arg;
blocking_c_del(a->db_env, a->db, a->nrows, a->sleeptime);
return arg;
}
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
struct blocking_c_del_args a = { db_env, db, nrows, sleeptime };
for (int i = 0; i < nthreads-1; i++) {
r = toku_pthread_create(&tids[i], NULL, blocking_c_del_thread, &a); assert(r == 0);
}
blocking_c_del(db_env, db, nrows, sleeptime);
for (int i = 0; i < nthreads-1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
}
int test_main(int argc, char * const argv[]) {
uint64_t cachesize = 0;
uint32_t pagesize = 0;
uint64_t nrows = 10;
int nthreads = 2;
long sleeptime = 100000;
#if defined(USE_TDB)
char *db_env_dir = "dir." __FILE__ ".tokudb";
#elif defined(USE_BDB)
char *db_env_dir = "dir." __FILE__ ".bdb";
#else
#error
#endif
char *db_filename = "test.db";
int db_env_open_flags = DB_CREATE | DB_PRIVATE | DB_INIT_MPOOL | DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_THREAD;
// parse_args(argc, argv);
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
verbose++;
continue;
}
if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0) {
if (verbose > 0)
verbose--;
continue;
}
if (strcmp(argv[i], "--nrows") == 0 && i+1 < argc) {
nrows = atoll(argv[++i]);
continue;
}
if (strcmp(argv[i], "--nthreads") == 0 && i+1 < argc) {
nthreads = atoi(argv[++i]);
continue;
}
if (strcmp(argv[i], "--sleeptime") == 0 && i+1 < argc) {
sleeptime = atol(argv[++i]);
continue;
}
assert(0);
}
// setup env
int r;
char rm_cmd[strlen(db_env_dir) + strlen("rm -rf ") + 1];
snprintf(rm_cmd, sizeof(rm_cmd), "rm -rf %s", db_env_dir);
r = system(rm_cmd); assert(r == 0);
r = toku_os_mkdir(db_env_dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); assert(r == 0);
DB_ENV *db_env = NULL;
r = db_env_create(&db_env, 0); assert(r == 0);
if (cachesize) {
const u_int64_t gig = 1 << 30;
r = db_env->set_cachesize(db_env, cachesize / gig, cachesize % gig, 1); assert(r == 0);
}
r = db_env->open(db_env, db_env_dir, db_env_open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
#if TOKUDB
r = db_env->set_lock_timeout(db_env, 30 * 1000); assert(r == 0);
#else
r = db_env->set_lk_detect(db_env, DB_LOCK_YOUNGEST); assert(r == 0);
#endif
// create the db
DB *db = NULL;
r = db_create(&db, db_env, 0); assert(r == 0);
if (pagesize) {
r = db->set_pagesize(db, pagesize); assert(r == 0);
}
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
// populate the db
populate(db_env, db, nrows);
run_test(db_env, db, nthreads, nrows, sleeptime);
// close env
r = db->close(db, 0); assert(r == 0); db = NULL;
r = db_env->close(db_env, 0); assert(r == 0); db_env = NULL;
return 0;
}
// verify that cursor deletes with write locking cause transactions with lock conflicts to
// suspend the conflicting threads.
#include "test.h"
#include "toku_pthread.h"
static void populate(DB_ENV *db_env, DB *db, uint64_t nrows) {
int r;
DB_TXN *txn = NULL;
r = db_env->txn_begin(db_env, NULL, &txn, 0); assert(r == 0);
for (uint64_t i = 0; i < nrows; i++) {
uint64_t k = htonl(i);
uint64_t v = i;
DBT key = { .data = &k, .size = sizeof k };
DBT val = { .data = &v, .size = sizeof v };
r = db->put(db, txn, &key, &val, 0); assert(r == 0);
}
r = txn->commit(txn, 0); assert(r == 0);
}
struct my_callback_context {
DBT key;
DBT val;
};
#if TOKUDB
static void copy_dbt(DBT *dest, DBT const *src) {
assert(dest->flags == DB_DBT_REALLOC);
dest->size = src->size;
dest->data = toku_xrealloc(dest->data, dest->size);
memcpy(dest->data, src->data, dest->size);
}
static int blocking_c_del_callback(DBT const *a UU(), DBT const *b UU(), void *e UU()) {
DBT const *found_key = a;
DBT const *found_val = b;
struct my_callback_context *context = (struct my_callback_context *) e;
copy_dbt(&context->key, found_key);
copy_dbt(&context->val, found_val);
return 0;
}
#endif
static void blocking_c_del(DB_ENV *db_env, DB *db, uint64_t nrows, long sleeptime) {
int r;
struct my_callback_context context;
context.key = (DBT) { .data = NULL, .size = 0, .flags = DB_DBT_REALLOC };
context.val = (DBT) { .data = NULL, .size = 0, .flags = DB_DBT_REALLOC };
for (uint64_t i = 0; i < nrows; i++) {
DB_TXN *txn = NULL;
r = db_env->txn_begin(db_env, NULL, &txn, 0); assert(r == 0);
DBC *cursor = NULL;
r = db->cursor(db, txn, &cursor, 0); assert(r == 0);
uint64_t k = htonl(i);
DBT key = { .data = &k, .size = sizeof k };
#if TOKUDB
r = cursor->c_getf_set(cursor, DB_RMW, &key, blocking_c_del_callback, &context);
#else
r = cursor->c_get(cursor, &key, &context.val, DB_SET + DB_RMW);
#endif
assert(r == 0 || r == DB_NOTFOUND);
if (r == 0) {
usleep(sleeptime);
if (verbose) {
uint64_t kk;
#if TOKUDB
assert(context.key.size == sizeof kk);
memcpy(&kk, context.key.data, sizeof kk);
#else
assert(key.size == sizeof kk);
memcpy(&kk, key.data, sizeof kk);
#endif
printf("%lu deleting %lu\n", toku_pthread_self(), (long unsigned) htonl(kk));
}
r = cursor->c_del(cursor, 0);
assert(r == 0 || r == DB_LOCK_DEADLOCK);
}
{ int rr = cursor->c_close(cursor); assert(rr == 0); }
if (r == 0)
r = txn->commit(txn, 0);
else
r = txn->abort(txn);
assert(r == 0);
if (verbose)
printf("%lu %lu\n", toku_pthread_self(), i);
}
toku_free(context.key.data);
toku_free(context.val.data);
}
struct blocking_c_del_args {
DB_ENV *db_env;
DB *db;
uint64_t nrows;
long sleeptime;
};
static void *blocking_c_del_thread(void *arg) {
struct blocking_c_del_args *a = (struct blocking_c_del_args *) arg;
blocking_c_del(a->db_env, a->db, a->nrows, a->sleeptime);
return arg;
}
static void run_test(DB_ENV *db_env, DB *db, int nthreads, uint64_t nrows, long sleeptime) {
int r;
toku_pthread_t tids[nthreads];
struct blocking_c_del_args a = { db_env, db, nrows, sleeptime };
for (int i = 0; i < nthreads-1; i++) {
r = toku_pthread_create(&tids[i], NULL, blocking_c_del_thread, &a); assert(r == 0);
}
blocking_c_del(db_env, db, nrows, sleeptime);
for (int i = 0; i < nthreads-1; i++) {
void *ret;
r = toku_pthread_join(tids[i], &ret); assert(r == 0);
}
}
int test_main(int argc, char * const argv[]) {
uint64_t cachesize = 0;
uint32_t pagesize = 0;
uint64_t nrows = 10;
int nthreads = 2;
long sleeptime = 100000;
#if defined(USE_TDB)
char *db_env_dir = "dir." __FILE__ ".tokudb";
#elif defined(USE_BDB)
char *db_env_dir = "dir." __FILE__ ".bdb";
#else
#error
#endif
char *db_filename = "test.db";
int db_env_open_flags = DB_CREATE | DB_PRIVATE | DB_INIT_MPOOL | DB_INIT_TXN | DB_INIT_LOCK | DB_INIT_LOG | DB_THREAD;
// parse_args(argc, argv);
for (int i = 1; i < argc; i++) {
if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {
verbose++;
continue;
}
if (strcmp(argv[i], "-q") == 0 || strcmp(argv[i], "--quiet") == 0) {
if (verbose > 0)
verbose--;
continue;
}
if (strcmp(argv[i], "--nrows") == 0 && i+1 < argc) {
nrows = atoll(argv[++i]);
continue;
}
if (strcmp(argv[i], "--nthreads") == 0 && i+1 < argc) {
nthreads = atoi(argv[++i]);
continue;
}
if (strcmp(argv[i], "--sleeptime") == 0 && i+1 < argc) {
sleeptime = atol(argv[++i]);
continue;
}
assert(0);
}
// setup env
int r;
char rm_cmd[strlen(db_env_dir) + strlen("rm -rf ") + 1];
snprintf(rm_cmd, sizeof(rm_cmd), "rm -rf %s", db_env_dir);
r = system(rm_cmd); assert(r == 0);
r = toku_os_mkdir(db_env_dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); assert(r == 0);
DB_ENV *db_env = NULL;
r = db_env_create(&db_env, 0); assert(r == 0);
if (cachesize) {
const u_int64_t gig = 1 << 30;
r = db_env->set_cachesize(db_env, cachesize / gig, cachesize % gig, 1); assert(r == 0);
}
r = db_env->open(db_env, db_env_dir, db_env_open_flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
#if TOKUDB
r = db_env->set_lock_timeout(db_env, 30 * 1000); assert(r == 0);
#else
r = db_env->set_lk_detect(db_env, DB_LOCK_YOUNGEST); assert(r == 0);
#endif
// create the db
DB *db = NULL;
r = db_create(&db, db_env, 0); assert(r == 0);
if (pagesize) {
r = db->set_pagesize(db, pagesize); assert(r == 0);
}
r = db->open(db, NULL, db_filename, NULL, DB_BTREE, DB_CREATE|DB_AUTO_COMMIT|DB_THREAD, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); assert(r == 0);
// populate the db
populate(db_env, db, nrows);
run_test(db_env, db, nthreads, nrows, sleeptime);
// close env
r = db->close(db, 0); assert(r == 0); db = NULL;
r = db_env->close(db_env, 0); assert(r == 0); db_env = NULL;
return 0;
}
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
#include "test.h"
/* See #627. */
#include <sys/stat.h>
#include <memory.h>
static void
do_627 (void) {
int r;
DB_ENV *env;
DB *db;
r = system("rm -rf " ENVDIR);
CKERR(r);
r=toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO); assert(r==0);
r=db_env_create(&env, 0); assert(r==0);
env->set_errfile(env, stderr);
r=env->open(env, ENVDIR, DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_MPOOL|DB_INIT_TXN|DB_CREATE|DB_PRIVATE, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
r=db_create(&db, env, 0); CKERR(r);
DB_TXN *t1, *t2;
DBT a,b;
r=env->txn_begin(env, 0, &t1, 0); assert(r==0);
r=db->open(db, t1, "foo.db", 0, DB_BTREE, DB_CREATE, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
r=db->put(db, t1, dbt_init(&a, "a", 2), dbt_init(&b, "b", 2), 0);
r=t1->commit(t1, 0); assert(r==0);
r=env->txn_begin(env, 0, &t1, 0); assert(r==0);
r=env->txn_begin(env, 0, &t2, 0); assert(r==0);
DBC *c1,*c2;
r=db->cursor(db, t1, &c1, 0); CKERR(r);
r=db->cursor(db, t2, &c2, 0); CKERR(r);
r=c1->c_get(c1, dbt_init(&a, "a", 2), dbt_init_malloc(&b), DB_SET); CKERR(r);
toku_free(b.data);
r=c2->c_get(c2, dbt_init(&a, "a", 2), dbt_init_malloc(&b), DB_SET); CKERR(r);
toku_free(b.data);
// This causes all hell to break loose in BDB 4.6, so we just cannot run this under BDB.
// PANIC: Invalid argument
// Expected DB_LOCK_NOTGRANTED, got DB_RUNRECOVERY: Fatal error, run database recovery
// bug627.bdb: bug627.c:44: do_627: Assertion `r==(-30994)' failed.
// Aborted
r=c1->c_del(c1, 0);
if (r!=DB_LOCK_NOTGRANTED) {
fprintf(stderr, "Expected DB_LOCK_NOTGRANTED, got %s\n", db_strerror(r));
}
assert(r==DB_LOCK_NOTGRANTED);
r=c1->c_close(c1); CKERR(r);
r=t1->commit(t1, 0); assert(r==0);
r=c2->c_del(c2, 0); CKERR(r);
r=c2->c_close(c2); CKERR(r);
r=t2->commit(t2, 0); assert(r==0);
r=db->close(db, 0); CKERR(r);
r=env->close(env, 0); CKERR(r);
}
int
test_main (int argc, char * const argv[]) {
parse_args(argc, argv);
do_627();
return 0;
}
......@@ -66,7 +66,7 @@ doit (BOOL committed_provdels) {
r = dbc->c_get(dbc, &key, &data, DB_NEXT); CKERR(r);
assert(*(int*)key.data == i);
assert(*(int*)data.data == j);
r = dbc->c_del(dbc, 0); CKERR(r);
r = db->del(db, txn, &key, DB_DELETE_ANY); CKERR(r);
}
r = dbc->c_get(dbc, &key, &data, DB_NEXT); CKERR2(r, DB_NOTFOUND);
r = dbc->c_get(dbc, &key, &data, DB_FIRST); CKERR2(r, DB_NOTFOUND);
......
......@@ -1004,8 +1004,8 @@ static void do_args(int argc, char * const argv[]) {
} else if (strcmp(argv[0], "-c")==0) {
CHECK_RESULTS = 1;
} else if (strcmp(argv[0], "-p")==0) {
USE_PUTS = LOADER_USE_PUTS;
printf("Using puts\n");
USE_PUTS = 0;
printf("DISABLED Using puts as part of #4503\n");
} else if (strcmp(argv[0], "-k")==0) {
test_only_abort_via_poll = 1;
printf("Perform only abort_via_poll test\n");
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
#ident "$Id: test_stress1.c 39258 2012-01-27 13:51:58Z zardosht $"
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <toku_pthread.h>
#include <unistd.h>
#include <memory.h>
#include <sys/stat.h>
#include <db.h>
#include "threaded_stress_test_helpers.h"
static int ptquery_op2(DB_TXN *txn, ARG arg, void* operation_extra) {
int db_index = *(int *)operation_extra;
DB* db = arg->dbp[db_index];
return ptquery_and_maybe_check_op(db, txn, arg, TRUE);
}
//
// This test is a form of stress that does operations on a single dictionary:
// We create a dictionary bigger than the cachetable (around 4x greater).
// Then, we spawn a bunch of pthreads that do the following:
// - scan dictionary forward with bulk fetch
// - scan dictionary forward slowly
// - scan dictionary backward with bulk fetch
// - scan dictionary backward slowly
// - Grow the dictionary with insertions
// - do random point queries into the dictionary
// With the small cachetable, this should produce quite a bit of churn in reading in and evicting nodes.
// If the test runs to completion without crashing, we consider it a success. It also tests that snapshots
// work correctly by verifying that table scans sum their vals to 0.
//
// This does NOT test:
// - splits and merges
// - multiple DBs
//
// Variables that are interesting to tweak and run:
// - small cachetable
// - number of elements
//
static void
stress_table(DB_ENV* env, DB** dbp, struct cli_args *cli_args) {
int n = cli_args->num_elements;
//
// the threads that we want:
// - some threads constantly updating random values
// - one thread doing table scan with bulk fetch
// - one thread doing table scan without bulk fetch
// - some threads doing random point queries
//
if (verbose) printf("starting creation of pthreads\n");
const int num_threads = cli_args->num_ptquery_threads;
struct arg myargs[num_threads];
int thread_ids[num_threads];
for (int i = 0; i < num_threads; i++) {
arg_init(&myargs[i], n, dbp, env, cli_args);
}
for (int i = 0; i < num_threads; i++) {
thread_ids[i] = i % cli_args->num_DBs;
myargs[i].operation = ptquery_op2;
myargs[i].operation_extra = &thread_ids[i];
}
run_workers(myargs, num_threads, cli_args->time_of_test, false, cli_args);
}
int
test_main(int argc, char *const argv[]) {
struct cli_args args = get_default_args_for_perf();
parse_stress_test_args(argc, argv, &args);
stress_test_main(&args);
return 0;
}
......@@ -18,7 +18,11 @@ int test_main (int argc, char * const argv[]) {
env->set_errfile(env, stderr);
// set a cachetable size of 10K
u_int32_t cachesize = 10*1024;
r = env->set_cachesize(env, 0, cachesize, 1); CKERR(r);
// as part of #4503, arbitrarily increasing sizze of cachetable
// the idea is to make it small enough such that all data
// cannot fit in the cachetable, but big enough such that
// we don't have cachet pressure
r = env->set_cachesize(env, 0, 4*cachesize, 1); CKERR(r);
r = env->set_default_bt_compare(env, int64_dbt_cmp); CKERR(r);
r = env->open(env, ENVDIR, envflags, S_IRWXU+S_IRWXG+S_IRWXO); CKERR(r);
......
......@@ -84,7 +84,7 @@ run (int choice) {
i=0;
while (0==(r=(c->c_get(c, &kdbt, &vdbt, DB_FIRST)))) {
i++;
r=c->c_del(c, 0);
r = db->del(db, txn, &kdbt, DB_DELETE_ANY);
CKERR(r);
}
assert(r==DB_NOTFOUND);
......
......@@ -86,7 +86,7 @@ test_789(void) {
r = db->cursor(db, txn, &cursor, 0); assert(r == 0);
DBT key, val;
r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&val), DB_NEXT); assert(r == 0);
r = cursor->c_del(cursor, 0); assert(r == 0);
r = db->del(db, txn, &key, DB_DELETE_ANY); assert(r == 0);
r = cursor->c_close(cursor); assert(r == 0);
toku_free(key.data); toku_free(val.data);
r = txn->commit(txn, 0); assert(r == 0);
......@@ -121,7 +121,7 @@ test_789(void) {
r = db->cursor(db, txn, &cursor, 0); assert(r == 0);
DBT key, val;
r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&val), DB_NEXT); assert(r == 0);
r = cursor->c_del(cursor, 0); assert(r == 0);
r = db->del(db, txn, &key, DB_DELETE_ANY); assert(r == 0);
r = cursor->c_close(cursor); assert(r == 0);
toku_free(key.data); toku_free(val.data);
r = txn->commit(txn, 0); assert(r == 0);
......
......@@ -102,7 +102,10 @@ test_bulk_fetch (u_int64_t n, BOOL prelock, BOOL disable_prefetching) {
DB_ENV *env;
r = db_env_create(&env, 0); assert(r == 0);
r=env->set_default_bt_compare(env, int64_dbt_cmp); CKERR(r);
r = env->set_cachesize(env, 0, (u_int32_t)n, 1); assert(r == 0);
// arbitrarily have cachetable size be 4*n
// goal is to make it small enough such that all of data
// does not fit in cachetable, but not so small that we get thrashing
r = env->set_cachesize(env, 0, (u_int32_t)4*n, 1); assert(r == 0);
r = env->open(env, ENVDIR, DB_CREATE+DB_PRIVATE+DB_INIT_MPOOL, 0); assert(r == 0);
DB *db;
......
......@@ -46,9 +46,6 @@ test_cursor_current (void) {
DBT key, data; int kk, vv;
r = cursor->c_del(cursor, 0);
assert(r == EINVAL);
r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&data), DB_CURRENT);
assert(r == EINVAL);
......@@ -70,17 +67,12 @@ test_cursor_current (void) {
assert(data.size == sizeof vv);
memcpy(&vv, data.data, data.size);
assert(vv == v);
r = db->del(db, null_txn, &key, DB_DELETE_ANY);
toku_free(key.data); toku_free(data.data);
r = cursor->c_del(cursor, 0);
CKERR(r);
r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&data), DB_CURRENT);
CKERR2(r,DB_KEYEMPTY);
r = cursor->c_del(cursor, 0);
CKERR2(r,DB_KEYEMPTY);
r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&data), DB_CURRENT);
CKERR2(r,DB_KEYEMPTY);
......
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <errno.h>
#include <sys/stat.h>
#include <db.h>
static void
cursor_expect (DBC *cursor, int k, int v, int op) {
DBT key, val;
int r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&val), op);
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 %u got %u - %u %u\n", (uint32_t)htonl(k), (uint32_t)htonl(kk), (uint32_t)htonl(v), (uint32_t)htonl(vv));
assert(kk == k);
assert(vv == v);
toku_free(key.data);
toku_free(val.data);
}
/* generate a multi-level tree and delete all entries with a cursor
verify that the pivot flags are toggled (currently by inspection) */
static void
test_cursor_delete (int dup_mode) {
if (verbose) printf("test_cursor_delete:%d\n", dup_mode);
int pagesize = 4096;
int elementsize = 32;
int npp = pagesize/elementsize;
int n = 16*npp; /* build a 2 level tree */
DB_TXN * const null_txn = 0;
const char * const fname = "test.cursor.delete.brt";
int r;
r = system("rm -rf " ENVDIR); assert(r == 0);
r = toku_os_mkdir(ENVDIR, S_IRWXU|S_IRWXG|S_IRWXO); assert(r == 0);
/* create the dup database file */
DB_ENV *env;
r = db_env_create(&env, 0); assert(r == 0);
#ifdef USE_TDB
r = env->set_redzone(env, 0); CKERR(r);
#endif
r = env->open(env, ENVDIR, DB_CREATE+DB_PRIVATE+DB_INIT_MPOOL, 0); assert(r == 0);
DB *db;
r = db_create(&db, env, 0); assert(r == 0);
db->set_errfile(db,0); // Turn off those annoying errors
r = db->set_flags(db, dup_mode); assert(r == 0);
r = db->set_pagesize(db, pagesize); assert(r == 0);
r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); assert(r == 0);
int i;
for (i=0; i<n; i++) {
int k = htonl(i);
int v = htonl(i);
DBT key, val;
r = db->put(db, null_txn, dbt_init(&key, &k, sizeof k), dbt_init(&val, &v, sizeof v), 0); assert(r == 0);
}
/* verify the sort order with a cursor */
DBC *cursor;
r = db->cursor(db, null_txn, &cursor, 0); assert(r == 0);
for (i=0; i<n; i++) {
cursor_expect(cursor, htonl(i), htonl(i), DB_NEXT);
r = cursor->c_del(cursor, 0); assert(r == 0);
}
r = cursor->c_close(cursor); assert(r == 0);
r = db->close(db, 0); assert(r == 0);
r = env->close(env, 0); assert(r == 0);
}
int
test_main(int argc, char *const argv[]) {
parse_args(argc, argv);
test_cursor_delete(0);
#ifdef USE_BDB
test_cursor_delete(DB_DUP);
#endif
return 0;
}
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <errno.h>
#include <sys/stat.h>
#include <db.h>
static DB_ENV *dbenv;
static DB *db;
static DB_TXN * txn;
static DBC *cursor;
static void
test_cursor_delete2 (void) {
int r;
DBT key,val;
r = db_env_create(&dbenv, 0); CKERR(r);
r = dbenv->open(dbenv, ENVDIR, DB_PRIVATE|DB_INIT_MPOOL|DB_CREATE|DB_INIT_TXN, 0); CKERR(r);
r = db_create(&db, dbenv, 0); CKERR(r);
r = dbenv->txn_begin(dbenv, 0, &txn, 0); CKERR(r);
r = db->open(db, txn, "primary.db", NULL, DB_BTREE, DB_CREATE, 0600); CKERR(r);
r = txn->commit(txn, 0); CKERR(r);
r = dbenv->txn_begin(dbenv, 0, &txn, 0); CKERR(r);
r = db->put(db, txn, dbt_init(&key, "a", 2), dbt_init(&val, "b", 2), 0); CKERR(r);
r = txn->commit(txn, 0); CKERR(r);
r = dbenv->txn_begin(dbenv, 0, &txn, 0); CKERR(r);
r = db->del(db, txn, dbt_init(&key, "a", 2), 0); CKERR(r);
r = txn->commit(txn, 0); CKERR(r);
r = dbenv->txn_begin(dbenv, 0, &txn, 0); CKERR(r);
r = db->put(db, txn, dbt_init(&key, "a", 2), dbt_init(&val, "c", 2), 0); CKERR(r);
cursor=cursor;
r = db->cursor(db, txn, &cursor, 0); CKERR(r);
r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&val), DB_FIRST); CKERR(r);
assert(strcmp(key.data, "a")==0); toku_free(key.data);
assert(strcmp(val.data, "c")==0); toku_free(val.data);
r = cursor->c_del(cursor, 0); CKERR(r);
r = cursor->c_del(cursor, 0); assert(r==DB_KEYEMPTY);
r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&val), DB_NEXT); assert(r==DB_NOTFOUND);
r = cursor->c_close(cursor); CKERR(r);
r = txn->commit(txn, 0); CKERR(r);
r = db->close(db, 0); CKERR(r);
r = dbenv->close(dbenv, 0); CKERR(r);
}
int
test_main(int argc, char *const argv[]) {
parse_args(argc, argv);
int r;
r = system("rm -rf " ENVDIR);
CKERR(r);
toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
test_cursor_delete2();
return 0;
}
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007 Tokutek Inc. All rights reserved."
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <errno.h>
#include <sys/stat.h>
#include <db.h>
static DB_ENV *dbenv;
static DB *db;
static DB_TXN * txn;
static DBC *cursor;
static void
test_cursor_delete_2119 (u_int32_t c_del_flags, u_int32_t txn_isolation_flags) {
int r;
r = system("rm -rf " ENVDIR);
CKERR(r);
r = toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
CKERR(r);
DBT key,val;
r = db_env_create(&dbenv, 0); CKERR(r);
r = dbenv->open(dbenv, ENVDIR, DB_PRIVATE|DB_INIT_MPOOL|DB_CREATE|DB_INIT_TXN|DB_INIT_LOCK, 0); CKERR(r);
r = db_create(&db, dbenv, 0); CKERR(r);
r = dbenv->txn_begin(dbenv, 0, &txn, txn_isolation_flags); CKERR(r);
r = db->open(db, txn, "primary.db", NULL, DB_BTREE, DB_CREATE, 0600); CKERR(r);
r = txn->commit(txn, 0); CKERR(r);
r = dbenv->txn_begin(dbenv, 0, &txn, txn_isolation_flags); CKERR(r);
r = db->put(db, txn, dbt_init(&key, "a", 2), dbt_init(&val, "b", 2), 0); CKERR(r);
r = txn->commit(txn, 0); CKERR(r);
r = dbenv->txn_begin(dbenv, 0, &txn, txn_isolation_flags); CKERR(r);
r = db->del(db, txn, dbt_init(&key, "a", 2), 0); CKERR(r);
r = txn->commit(txn, 0); CKERR(r);
r = dbenv->txn_begin(dbenv, 0, &txn, txn_isolation_flags); CKERR(r);
r = db->put(db, txn, dbt_init(&key, "a", 2), dbt_init(&val, "c", 2), 0); CKERR(r);
cursor=cursor;
r = db->cursor(db, txn, &cursor, 0); CKERR(r);
r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&val), DB_FIRST); CKERR(r);
assert(strcmp(key.data, "a")==0); toku_free(key.data);
assert(strcmp(val.data, "c")==0); toku_free(val.data);
r = cursor->c_del(cursor, c_del_flags); CKERR(r);
r = cursor->c_del(cursor, c_del_flags); assert(r==DB_KEYEMPTY);
r = cursor->c_get(cursor, dbt_init_malloc(&key), dbt_init_malloc(&val), DB_NEXT); assert(r==DB_NOTFOUND);
r = cursor->c_close(cursor); CKERR(r);
r = txn->commit(txn, 0); CKERR(r);
r = db->close(db, 0); CKERR(r);
r = dbenv->close(dbenv, 0); CKERR(r);
}
int
test_main(int argc, char *const argv[]) {
parse_args(argc, argv);
int isolation;
int read_prelocked;
int write_prelocked;
for (isolation = 0; isolation < 2; isolation++) {
u_int32_t isolation_flag = isolation ? DB_READ_UNCOMMITTED : 0;
for (read_prelocked = 0; read_prelocked < 2; read_prelocked++) {
u_int32_t read_prelocked_flag = read_prelocked ? DB_PRELOCKED : 0;
for (write_prelocked = 0; write_prelocked < 2; write_prelocked++) {
u_int32_t write_prelocked_flag = write_prelocked ? DB_PRELOCKED_WRITE : 0;
test_cursor_delete_2119(read_prelocked_flag | write_prelocked_flag,
isolation_flag);
}
}
}
return 0;
}
This diff is collapsed.
......@@ -60,7 +60,7 @@ test_main (int UU(argc), char UU(*const argv[])) {
assert(*(int*)val.data == v1); // Will bring up valgrind error.
r = cursor->c_del(cursor, 0);
r = db->del(db, null_txn, &ckey, DB_DELETE_ANY); assert(r == 0);
CKERR(r);
assert(*(int*)val.data == v1); // Will bring up valgrind error.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment