mirror of
https://github.com/MariaDB/server.git
synced 2025-02-02 03:51:50 +01:00
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
This commit is contained in:
parent
d1efe9da42
commit
0c071258d7
3 changed files with 54 additions and 16 deletions
49
newbrt/brt.c
49
newbrt/brt.c
|
@ -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);
|
||||
|
|
17
src/ydb.c
17
src/ydb.c
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue