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

More surgery. Addresess #1195.

git-svn-id: file:///svn/toku/tokudb.1195@7123 c7de825b-a66e-492c-adef-691d508d4ae1
parent 50da025a
...@@ -83,14 +83,6 @@ long long n_items_malloced; ...@@ -83,14 +83,6 @@ long long n_items_malloced;
static void verify_local_fingerprint_nonleaf (BRTNODE node); static void verify_local_fingerprint_nonleaf (BRTNODE node);
static int toku_dump_brtnode (BRT brt, BLOCKNUM blocknum, int depth, bytevec lorange, ITEMLEN lolen, bytevec hirange, ITEMLEN hilen); static int toku_dump_brtnode (BRT brt, BLOCKNUM blocknum, int depth, bytevec lorange, ITEMLEN lolen, bytevec hirange, ITEMLEN hilen);
// We invalidate all the OMTCURSORS any time we push into the root of the BRT for that OMT.
// We keep a counter on each brt header, but if the brt header is evicted from the cachetable
// then we lose that counter. So we also keep a global counter.
// An alternative would be to keep only the global counter. But that would invalidate all OMTCURSORS
// even from unrelated BRTs. This way we only invalidate an OMTCURSOR if
static u_int64_t global_root_put_counter = 0;
/* Frees a node, including all the stuff in the hash table. */ /* Frees a node, including all the stuff in the hash table. */
void toku_brtnode_free (BRTNODE *nodep) { void toku_brtnode_free (BRTNODE *nodep) {
BRTNODE node=*nodep; BRTNODE node=*nodep;
...@@ -2444,28 +2436,6 @@ static void verify_local_fingerprint_nonleaf (BRTNODE node) { ...@@ -2444,28 +2436,6 @@ static void verify_local_fingerprint_nonleaf (BRTNODE node) {
assert(fp==node->local_fingerprint); assert(fp==node->local_fingerprint);
} }
static int
brtnode_put_cmd_simple (BRT t, BRTNODE node, BRT_CMD cmd, TOKULOGGER logger,
BOOL *should_split, BOOL *should_merge) {
if (node->height==0) {
int r;
u_int64_t new_size MAYBE_INIT(0);
r = brt_leaf_put_cmd_simple(t, node, cmd, logger, &new_size);
if (r!=0) return r;
*should_split = new_size > node->nodesize;
*should_merge = (new_size*4) < node->nodesize;
} else {
int r;
u_int32_t new_fanout = 0; // Some compiler bug in gcc is complaining that this is uninitialized.
r = brt_nonleaf_put_cmd_simple(t, node, cmd, logger, &new_fanout);
if (r!=0) return 0;
*should_split = new_fanout > TREE_FANOUT;
*should_merge = new_fanout*4 < TREE_FANOUT;
//printf("%s:%d should_merge=%d\n", __FILE__, __LINE__, *should_merge);
}
return 0;
}
static int brtnode_put_cmd (BRT t, BRTNODE node, BRT_CMD cmd, static int brtnode_put_cmd (BRT t, BRTNODE node, BRT_CMD cmd,
int *did_split, BRTNODE *nodea, BRTNODE *nodeb, DBT *splitk, int *did_split, BRTNODE *nodea, BRTNODE *nodeb, DBT *splitk,
TOKULOGGER logger) { TOKULOGGER logger) {
......
...@@ -127,6 +127,13 @@ message are not overfull. (But they may be underfull or too fat or too thin.) ...@@ -127,6 +127,13 @@ message are not overfull. (But they may be underfull or too fat or too thin.)
// //
#include "includes.h" #include "includes.h"
// We invalidate all the OMTCURSORS any time we push into the root of the BRT for that OMT.
// We keep a counter on each brt header, but if the brt header is evicted from the cachetable
// then we lose that counter. So we also keep a global counter.
// An alternative would be to keep only the global counter. But that would invalidate all OMTCURSORS
// even from unrelated BRTs. This way we only invalidate an OMTCURSOR if
static u_int64_t global_root_put_counter = 0;
static void static void
fixup_child_fingerprint (BRTNODE node, int childnum_of_node, BRTNODE child, BRT UU(brt), TOKULOGGER UU(logger)) fixup_child_fingerprint (BRTNODE node, int childnum_of_node, BRTNODE child, BRT UU(brt), TOKULOGGER UU(logger))
// Effect: Sum the child fingerprint (and leafentry estimates) and store them in NODE. // Effect: Sum the child fingerprint (and leafentry estimates) and store them in NODE.
...@@ -309,6 +316,42 @@ brt_init_new_root(BRT brt, BRTNODE nodea, BRTNODE nodeb, DBT splitk, CACHEKEY *r ...@@ -309,6 +316,42 @@ brt_init_new_root(BRT brt, BRTNODE nodea, BRTNODE nodeb, DBT splitk, CACHEKEY *r
return 0; return 0;
} }
enum should_status { SHOULD_OK, SHOULD_MERGE, SHOULD_SPLIT };
static int
brtnode_put_cmd (BRT t, BRTNODE node, BRT_CMD cmd, TOKULOGGER logger, enum should_status *should, BOOL *did_io)
// Effect: Push CMD into the subtree rooted at NODE, and indicate whether as a result NODE should split or should merge.
// If NODE is a leaf, then
// put CMD into leaf, applying it to the leafentries
// If NODE is a nonleaf, then copy the cmd into the relevant child fifos.
// For each child fifo that is empty and where the child is in main memory put the command into the child (using this same algorithm)
// Use *did_io to determine whether I/O has already been performed. If it has then we avoid doing additional I/O.
// Set *should as follows:
// { SHOULD_SPLIT if the node is overfull
// *should = { SHOULD_MERGE if the node is underfull
// { SHOULD_OK if the node is ok. (Those cases are mutually exclusive.)
// If we perform I/O then set *did_io to true.
{
if (node->height==0) {
int r;
u_int64_t new_size MAYBE_INIT(0);
r = brt_leaf_put_cmd(t, node, cmd, logger, &new_size);
if (r!=0) return r;
if (new_size > node->nodesize) *should = SHOULD_SPLIT;
else if ((new_size*4) < node->nodesize) *should = SHOULD_MERGE;
else *should = SHOULD_OK;
} else {
int r;
u_int32_t new_fanout = 0; // Some compiler bug in gcc is complaining that this is uninitialized.
r = brt_nonleaf_put_cmd(t, node, cmd, logger, &new_fanout);
if (r!=0) return 0;
if (new_fanout > TREE_FANOUT) *should = SHOULD_SPLIT;
else if (new_fanout*4 < TREE_FANOUT) *should = SHOULD_MERGE;
else *should = SHOULD_OK;
}
return 0;
}
static int push_something_at_root (BRT brt, BRTNODE *nodep, CACHEKEY *rootp, BRT_CMD cmd, TOKULOGGER logger) static int push_something_at_root (BRT brt, BRTNODE *nodep, CACHEKEY *rootp, BRT_CMD cmd, TOKULOGGER logger)
// Effect: Put CMD into brt by descending into the tree as deeply as we can // Effect: Put CMD into brt by descending into the tree as deeply as we can
// without performing I/O (but we must fetch the root), // without performing I/O (but we must fetch the root),
...@@ -328,10 +371,12 @@ static int push_something_at_root (BRT brt, BRTNODE *nodep, CACHEKEY *rootp, BRT ...@@ -328,10 +371,12 @@ static int push_something_at_root (BRT brt, BRTNODE *nodep, CACHEKEY *rootp, BRT
// Note: During the initial descent, we may overfull many nonleaf nodes. We wish to flush only one nonleaf node at each level. // Note: During the initial descent, we may overfull many nonleaf nodes. We wish to flush only one nonleaf node at each level.
{ {
BRTNODE node = *nodep; BRTNODE node = *nodep;
enum should_status should;
BOOL did_io = FALSE;
BOOL should_split =-1; BOOL should_split =-1;
BOOL should_merge =-1; BOOL should_merge =-1;
{ {
int r = brtnode_put_cmd(brt, node, cmd, logger, &should_split, &should_merge); int r = brtnode_put_cmd(brt, node, cmd, logger, &should, &did_io);
if (r!=0) return r; if (r!=0) return r;
//if (should_split) printf("%s:%d Pushed something simple, should_split=1\n", __FILE__, __LINE__); //if (should_split) printf("%s:%d Pushed something simple, should_split=1\n", __FILE__, __LINE__);
......
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