Browse Source
[t:4147], add test
[t:4147], add test
git-svn-id: file:///svn/toku/tokudb@38217 c7de825b-a66e-492c-adef-691d508d4ae1pull/73/head
committed by
Yoni Fogel
1 changed files with 203 additions and 0 deletions
@ -0,0 +1,203 @@ |
|||
#ident "$Id: test-del-inorder.c 32975 2011-07-11 23:42:51Z leifwalsh $" |
|||
/* The goal of this test. Make sure that inserts stay behind deletes. */ |
|||
|
|||
|
|||
#include "test.h" |
|||
#include "includes.h" |
|||
#include <brt-cachetable-wrappers.h> |
|||
|
|||
static TOKUTXN const null_txn = 0; |
|||
static DB * const null_db = 0; |
|||
|
|||
enum { NODESIZE = 1024, KSIZE=NODESIZE-100, TOKU_PSIZE=20 }; |
|||
|
|||
CACHETABLE ct; |
|||
BRT brt; |
|||
int fnamelen; |
|||
char *fname; |
|||
|
|||
static int update_func( |
|||
DB* UU(db), |
|||
const DBT* key, |
|||
const DBT* old_val, |
|||
const DBT* UU(extra), |
|||
void (*set_val)(const DBT *new_val, void *set_extra), |
|||
void *set_extra) |
|||
{ |
|||
DBT new_val; |
|||
assert(old_val->size > 0); |
|||
if (verbose) { |
|||
printf("applying update to %s\n", (char *)key->data); |
|||
} |
|||
toku_init_dbt(&new_val); |
|||
set_val(&new_val, set_extra); |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
static void |
|||
doit (void) { |
|||
BLOCKNUM node_leaf[2]; |
|||
BLOCKNUM node_internal, node_root; |
|||
|
|||
int r; |
|||
|
|||
fnamelen = strlen(__FILE__) + 20; |
|||
fname = toku_malloc(fnamelen); |
|||
assert(fname!=0); |
|||
|
|||
snprintf(fname, fnamelen, "%s.brt", __FILE__); |
|||
r = toku_brt_create_cachetable(&ct, 500*1024*1024, ZERO_LSN, NULL_LOGGER); assert(r==0); |
|||
unlink(fname); |
|||
r = toku_open_brt(fname, 1, &brt, NODESIZE, NODESIZE/2, ct, null_txn, toku_builtin_compare_fun, null_db); |
|||
assert(r==0); |
|||
toku_free(fname); |
|||
|
|||
brt->update_fun = update_func; |
|||
brt->h->update_fun = update_func; |
|||
|
|||
toku_testsetup_initialize(); // must precede any other toku_testsetup calls |
|||
|
|||
r = toku_testsetup_leaf(brt, &node_leaf[0]); |
|||
assert(r==0); |
|||
r = toku_testsetup_leaf(brt, &node_leaf[1]); |
|||
assert(r==0); |
|||
|
|||
char* pivots[1]; |
|||
pivots[0] = toku_strdup("kkkkk"); |
|||
int pivot_len = 6; |
|||
|
|||
r = toku_testsetup_nonleaf(brt, 1, &node_internal, 2, node_leaf, pivots, &pivot_len); |
|||
assert(r==0); |
|||
|
|||
r = toku_testsetup_nonleaf(brt, 1, &node_root, 1, &node_internal, 0, 0); |
|||
assert(r==0); |
|||
|
|||
r = toku_testsetup_root(brt, node_root); |
|||
assert(r==0); |
|||
|
|||
// |
|||
// at this point we have created a tree with a root, an internal node, |
|||
// and two leaf nodes, the pivot being "kkkkk" |
|||
// |
|||
|
|||
// now we insert a row into each leaf node |
|||
r = toku_testsetup_insert_to_leaf ( |
|||
brt, |
|||
node_leaf[0], |
|||
"a", // key |
|||
2, // keylen |
|||
"aa", |
|||
3 |
|||
); |
|||
assert(r==0); |
|||
r = toku_testsetup_insert_to_leaf ( |
|||
brt, |
|||
node_leaf[1], |
|||
"z", // key |
|||
2, // keylen |
|||
"zz", |
|||
3 |
|||
); |
|||
assert(r==0); |
|||
|
|||
// |
|||
// now insert a bunch of dummy delete messages |
|||
// into the internal node, to get its cachepressure size up |
|||
// |
|||
for (int i = 0; i < 100000; i++) { |
|||
r = toku_testsetup_insert_to_nonleaf ( |
|||
brt, |
|||
node_internal, |
|||
BRT_DELETE_ANY, |
|||
"jj", // this key does not exist, so its message application should be a no-op |
|||
3, |
|||
NULL, |
|||
0 |
|||
); |
|||
assert(r==0); |
|||
} |
|||
|
|||
// |
|||
// now insert a broadcast message into the root |
|||
// |
|||
r = toku_testsetup_insert_to_nonleaf ( |
|||
brt, |
|||
node_root, |
|||
BRT_UPDATE_BROADCAST_ALL, |
|||
NULL, |
|||
0, |
|||
NULL, |
|||
0 |
|||
); |
|||
assert(r==0); |
|||
|
|||
// now do a lookup on one of the keys, this should bring a leaf node up to date |
|||
DBT k; |
|||
struct check_pair pair = {2, "a", 0, NULL, 0}; |
|||
r = toku_brt_lookup(brt, toku_fill_dbt(&k, "a", 2), lookup_checkf, &pair); |
|||
assert(r==0); |
|||
|
|||
// |
|||
// now let us induce a clean on the internal node |
|||
// |
|||
BRTNODE node; |
|||
struct brtnode_fetch_extra bfe; |
|||
fill_bfe_for_min_read(&bfe, brt->h); |
|||
toku_pin_brtnode_off_client_thread( |
|||
brt->h, |
|||
node_internal, |
|||
toku_cachetable_hash(brt->h->cf, node_internal), |
|||
&bfe, |
|||
0, |
|||
NULL, |
|||
&node |
|||
); |
|||
assert(node->n_children == 2); |
|||
// we expect that this flushes its buffer, that |
|||
// a merge is not done, and that the lookup |
|||
// of values "a" and "z" still works |
|||
r = toku_brtnode_cleaner_callback( |
|||
node, |
|||
node_internal, |
|||
toku_cachetable_hash(brt->h->cf, node_internal), |
|||
brt->h |
|||
); |
|||
|
|||
// verify that node_internal's buffer is empty |
|||
fill_bfe_for_min_read(&bfe, brt->h); |
|||
toku_pin_brtnode_off_client_thread( |
|||
brt->h, |
|||
node_internal, |
|||
toku_cachetable_hash(brt->h->cf, node_internal), |
|||
&bfe, |
|||
0, |
|||
NULL, |
|||
&node |
|||
); |
|||
// check that no merge happened |
|||
assert(node->n_children == 2); |
|||
// check that buffers are empty |
|||
assert(toku_bnc_nbytesinbuf(BNC(node, 0)) == 0); |
|||
assert(toku_bnc_nbytesinbuf(BNC(node, 1)) == 0); |
|||
toku_unpin_brtnode_off_client_thread(brt->h, node); |
|||
// check that lookups on the two keys is still good |
|||
struct check_pair pair1 = {2, "a", 0, NULL, 0}; |
|||
r = toku_brt_lookup(brt, toku_fill_dbt(&k, "a", 2), lookup_checkf, &pair1); |
|||
assert(r==0); |
|||
struct check_pair pair2 = {2, "z", 0, NULL, 0}; |
|||
r = toku_brt_lookup(brt, toku_fill_dbt(&k, "z", 2), lookup_checkf, &pair2); |
|||
assert(r==0); |
|||
|
|||
|
|||
r = toku_close_brt(brt, 0); assert(r==0); |
|||
r = toku_cachetable_close(&ct); assert(r==0); |
|||
|
|||
toku_free(pivots[0]); |
|||
} |
|||
|
|||
int |
|||
test_main (int argc __attribute__((__unused__)), const char *argv[] __attribute__((__unused__))) { |
|||
doit(); |
|||
return 0; |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue