Commit 0c071258 authored by Bradley C. Kuszmaul's avatar Bradley C. Kuszmaul Committed by Yoni Fogel

Use a fast version of brt_is_empty. Refs #2919. [t:2919]

git-svn-id: file:///svn/toku/tokudb@23694 c7de825b-a66e-492c-adef-691d508d4ae1
parent d1efe9da
......@@ -5581,6 +5581,55 @@ toku_brt_is_empty (BRT brt, /*out*/BOOL *try_again) {
return is_empty_struct.is_empty_so_far;
}
static BOOL is_empty_fast_iter (BRT brt, BRTNODE node) {
if (node->height > 0) {
if (node->u.n.n_bytes_in_buffers!=0) return 0; // it's not empty if there are bytes in buffers
for (int childnum=0; childnum<node->u.n.n_children; childnum++) {
BRTNODE childnode;
{
void *node_v;
BLOCKNUM childblocknum = BNC_BLOCKNUM(node,childnum);
u_int32_t fullhash = compute_child_fullhash(brt->cf, node, childnum);
int rr = toku_cachetable_get_and_pin(brt->cf, childblocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt->h);
assert(rr ==0);
childnode = node_v;
}
int child_is_empty = is_empty_fast_iter(brt, childnode);
{
int rr = toku_unpin_brtnode(brt, childnode);
assert(rr==0);
}
if (!child_is_empty) return 0;
}
return 1;
} else {
// leaf: If the omt is empty, we are happy.
return toku_omt_size(node->u.l.buffer)==0;
}
}
BOOL toku_brt_is_empty_fast (BRT brt)
// A fast check to see if the tree is empty. If there are any messages or leafentries, we consider the tree to be nonempty. It's possible that those
// messages and leafentries would all optimize away and that the tree is empty, but we'll say it is nonempty.
{
u_int32_t fullhash;
CACHEKEY *rootp = toku_calculate_root_offset_pointer(brt, &fullhash);
BRTNODE node;
//assert(fullhash == toku_cachetable_hash(brt->cf, *rootp));
{
void *node_v;
int rr = toku_cachetable_get_and_pin(brt->cf, *rootp, fullhash,
&node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt->h);
assert(rr==0);
node = node_v;
}
BOOL r = is_empty_fast_iter(brt, node);
{
int rr = toku_unpin_brtnode(brt, node);
assert(rr==0);
}
return r;
}
int toku_brt_strerror_r(int error, char *buf, size_t buflen)
{
......
......@@ -217,6 +217,10 @@ BOOL toku_brt_is_empty (BRT brt, BOOL *try_again);
// Effect: Return TRUE iff the tree is empty. (However if *try_again is set to TRUE by toku_brt_is_empty, then the answer is inconclusive, and the function should
// be tried again. It's a good idea to release the big ydb lock in this case.
BOOL toku_brt_is_empty_fast (BRT brt);
// Effect: Return TRUE if there are no messages or leaf entries in the tree. If so, it's empty. If there are messages or leaf entries, we say it's not empty
// even though if we were to optimize the tree it might turn out that they are empty.
double get_tdiff(void) __attribute__((__visibility__("default")));
BOOL toku_brt_is_recovery_logging_suppressed (BRT);
......
......@@ -4416,21 +4416,6 @@ static int toku_c_pre_acquire_read_lock(DBC *dbc, const DBT *key_left, const DBT
return r;
}
static BOOL brt_is_empty_keep_trying (BRT brt) {
BOOL try_again = TRUE;
BOOL is_empty;
while (try_again) {
try_again = FALSE;
is_empty = toku_brt_is_empty(brt, &try_again);
if (try_again) {
// If the tree changed shape, release the lock for a moment to give others a chance to work.
toku_ydb_unlock();
toku_ydb_lock();
}
}
return is_empty;
}
//static int toku_db_pre_acquire_table_lock(DB *db, DB_TXN *txn) {
// needed by loader.c
int toku_db_pre_acquire_table_lock(DB *db, DB_TXN *txn, BOOL just_lock) {
......@@ -4449,7 +4434,7 @@ int toku_db_pre_acquire_table_lock(DB *db, DB_TXN *txn, BOOL just_lock) {
if (r==0 && !just_lock &&
!toku_brt_is_recovery_logging_suppressed(db->i->brt) &&
brt_is_empty_keep_trying(db->i->brt)
toku_brt_is_empty_fast(db->i->brt)
) {
//Try to suppress both rollback and recovery logs
DB_LOADER *loader;
......
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