2013-04-16 23:57:20 -04:00
|
|
|
#include "includes.h"
|
2008-03-05 18:34:32 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
int toku_testsetup_leaf(BRT brt, BLOCKNUM *blocknum) {
|
2008-03-05 18:34:32 +00:00
|
|
|
BRTNODE node;
|
2013-04-16 23:57:18 -04:00
|
|
|
int r = toku_read_brt_header_and_store_in_cachefile(brt->cf, &brt->h);
|
2008-03-05 18:34:32 +00:00
|
|
|
if (r!=0) return r;
|
|
|
|
toku_create_new_brtnode(brt, &node, 0, (TOKULOGGER)0);
|
2008-04-03 20:24:47 +00:00
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
*blocknum = node->thisnodename;
|
2008-03-05 18:34:32 +00:00
|
|
|
r = toku_unpin_brtnode(brt, node);
|
|
|
|
if (r!=0) return r;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't bother to clean up carefully if something goes wrong. (E.g., it's OK to have malloced stuff that hasn't been freed.)
|
2013-04-16 23:57:18 -04:00
|
|
|
int toku_testsetup_nonleaf (BRT brt, int height, BLOCKNUM *blocknum, int n_children, BLOCKNUM *children, u_int32_t *subtree_fingerprints, char **keys, int *keylens) {
|
2008-03-05 18:34:32 +00:00
|
|
|
BRTNODE node;
|
|
|
|
assert(n_children<=BRT_FANOUT);
|
2013-04-16 23:57:18 -04:00
|
|
|
int r = toku_read_brt_header_and_store_in_cachefile(brt->cf, &brt->h);
|
2008-03-05 18:34:32 +00:00
|
|
|
if (r!=0) return r;
|
|
|
|
toku_create_new_brtnode(brt, &node, height, (TOKULOGGER)0);
|
|
|
|
node->u.n.n_children=n_children;
|
2008-04-03 20:24:47 +00:00
|
|
|
MALLOC_N(n_children+1, node->u.n.childinfos);
|
|
|
|
MALLOC_N(n_children, node->u.n.childkeys);
|
2008-03-05 18:34:32 +00:00
|
|
|
node->u.n.totalchildkeylens=0;
|
|
|
|
node->u.n.n_bytes_in_buffers=0;
|
|
|
|
int i;
|
|
|
|
for (i=0; i<n_children; i++) {
|
|
|
|
node->u.n.childinfos[i] = (struct brtnode_nonleaf_childinfo){ .subtree_fingerprint = subtree_fingerprints[i],
|
2008-04-30 13:23:04 +00:00
|
|
|
.leafentry_estimate = 0,
|
2013-04-16 23:57:18 -04:00
|
|
|
.blocknum = children[i],
|
2008-03-05 18:34:32 +00:00
|
|
|
.n_bytes_in_buffer = 0 };
|
|
|
|
r = toku_fifo_create(&BNC_BUFFER(node,i)); if (r!=0) return r;
|
|
|
|
}
|
|
|
|
for (i=0; i+1<n_children; i++) {
|
|
|
|
node->u.n.childkeys[i] = kv_pair_malloc(keys[i], keylens[i], 0, 0);
|
|
|
|
node->u.n.totalchildkeylens += keylens[i];
|
|
|
|
}
|
2013-04-16 23:57:18 -04:00
|
|
|
*blocknum = node->thisnodename;
|
2013-04-16 23:57:18 -04:00
|
|
|
return toku_unpin_brtnode(brt, node);
|
2008-03-05 18:34:32 +00:00
|
|
|
}
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
int toku_testsetup_root(BRT brt, BLOCKNUM blocknum) {
|
2013-04-16 23:57:18 -04:00
|
|
|
int r = toku_read_brt_header_and_store_in_cachefile(brt->cf, &brt->h);
|
2008-03-05 18:34:32 +00:00
|
|
|
if (r!=0) return r;
|
2013-04-16 23:57:18 -04:00
|
|
|
brt->h->roots[0] = blocknum;
|
2008-06-18 21:38:01 +00:00
|
|
|
brt->h->root_hashes[0].valid = FALSE;
|
2013-04-16 23:57:18 -04:00
|
|
|
return 0;
|
2008-03-05 18:34:32 +00:00
|
|
|
}
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
int toku_testsetup_get_sersize(BRT brt, BLOCKNUM diskoff) // Return the size on disk
|
2008-03-05 18:34:32 +00:00
|
|
|
{
|
|
|
|
void *node_v;
|
2008-06-17 17:05:19 +00:00
|
|
|
int r = toku_cachetable_get_and_pin(brt->cf, diskoff, toku_cachetable_hash(brt->cf, diskoff), &node_v, NULL,
|
2008-03-05 18:34:32 +00:00
|
|
|
toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt);
|
|
|
|
assert(r==0);
|
|
|
|
int size = toku_serialize_brtnode_size(node_v);
|
|
|
|
r = toku_unpin_brtnode(brt, node_v);
|
|
|
|
assert(r==0);
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
int toku_testsetup_insert_to_leaf (BRT brt, BLOCKNUM blocknum, char *key, int keylen, char *val, int vallen, u_int32_t *subtree_fingerprint) {
|
2008-03-05 18:34:32 +00:00
|
|
|
void *node_v;
|
|
|
|
int r;
|
2013-04-16 23:57:18 -04:00
|
|
|
r = toku_cachetable_get_and_pin(brt->cf, blocknum, toku_cachetable_hash(brt->cf, blocknum), &node_v, NULL,
|
2008-03-05 18:34:32 +00:00
|
|
|
toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt);
|
|
|
|
if (r!=0) return r;
|
|
|
|
BRTNODE node=node_v;
|
2008-04-04 13:13:51 +00:00
|
|
|
toku_verify_counts(node);
|
2008-03-05 18:34:32 +00:00
|
|
|
assert(node->height==0);
|
2008-04-02 23:40:36 +00:00
|
|
|
|
2008-04-07 01:30:25 +00:00
|
|
|
u_int32_t lesize, disksize;
|
|
|
|
LEAFENTRY tmp_leafentry;
|
|
|
|
r = le_committed(keylen, key, vallen, val, &lesize, &disksize, &tmp_leafentry);
|
|
|
|
|
2008-04-22 20:39:50 +00:00
|
|
|
LEAFENTRY leafentry = mempool_malloc_from_omt(node->u.l.buffer, &node->u.l.buffer_mempool, lesize);
|
2008-04-07 01:30:25 +00:00
|
|
|
memcpy(leafentry, tmp_leafentry, lesize);
|
|
|
|
toku_free(tmp_leafentry);
|
|
|
|
|
2008-04-25 13:45:55 +00:00
|
|
|
OMTVALUE storeddatav;
|
2008-04-02 23:40:36 +00:00
|
|
|
u_int32_t idx;
|
2008-04-07 01:30:25 +00:00
|
|
|
DBT keydbt,valdbt;
|
|
|
|
BRT_CMD_S cmd = {BRT_INSERT, 0, .u.id={toku_fill_dbt(&keydbt, key, keylen),
|
|
|
|
toku_fill_dbt(&valdbt, val, vallen)}};
|
2013-04-16 23:57:24 -04:00
|
|
|
struct cmd_leafval_heaviside_extra be = {brt, &cmd, node->flags & TOKU_DB_DUPSORT};
|
|
|
|
r = toku_omt_find_zero(node->u.l.buffer, toku_cmd_leafval_heaviside, &be, &storeddatav, &idx, NULL);
|
2008-04-07 01:30:25 +00:00
|
|
|
|
2008-04-02 23:40:36 +00:00
|
|
|
|
|
|
|
if (r==0) {
|
2008-04-25 13:45:55 +00:00
|
|
|
LEAFENTRY storeddata=storeddatav;
|
2008-04-02 23:40:36 +00:00
|
|
|
// It's already there. So now we have to remove it and put the new one back in.
|
2008-04-22 20:39:50 +00:00
|
|
|
node->u.l.n_bytes_in_buffer -= OMT_ITEM_OVERHEAD + leafentry_disksize(storeddata);
|
2008-04-07 01:30:25 +00:00
|
|
|
node->local_fingerprint -= node->rand4fingerprint*toku_le_crc(storeddata);
|
2008-04-22 20:39:50 +00:00
|
|
|
toku_mempool_mfree(&node->u.l.buffer_mempool, storeddata, leafentry_memsize(storeddata));
|
2008-04-02 23:40:36 +00:00
|
|
|
// Now put the new kv in.
|
2008-04-22 20:39:50 +00:00
|
|
|
toku_omt_set_at(node->u.l.buffer, leafentry, idx);
|
2008-03-05 18:34:32 +00:00
|
|
|
} else {
|
2013-04-16 23:57:24 -04:00
|
|
|
r = toku_omt_insert(node->u.l.buffer, leafentry, toku_cmd_leafval_heaviside, &be, 0);
|
2008-04-02 23:40:36 +00:00
|
|
|
assert(r==0);
|
2008-03-05 18:34:32 +00:00
|
|
|
}
|
2008-04-02 23:40:36 +00:00
|
|
|
|
2008-04-22 20:39:50 +00:00
|
|
|
node->u.l.n_bytes_in_buffer += OMT_ITEM_OVERHEAD + disksize;
|
2008-04-07 01:30:25 +00:00
|
|
|
node->local_fingerprint += node->rand4fingerprint*toku_le_crc(leafentry);
|
2008-04-02 23:40:36 +00:00
|
|
|
|
2008-03-05 18:34:32 +00:00
|
|
|
node->dirty=1;
|
|
|
|
*subtree_fingerprint = node->local_fingerprint;
|
2008-04-04 13:13:51 +00:00
|
|
|
|
|
|
|
toku_verify_counts(node);
|
|
|
|
|
2008-03-05 18:34:32 +00:00
|
|
|
r = toku_unpin_brtnode(brt, node_v);
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2013-04-16 23:57:18 -04:00
|
|
|
int toku_testsetup_insert_to_nonleaf (BRT brt, BLOCKNUM blocknum, enum brt_cmd_type cmdtype, char *key, int keylen, char *val, int vallen, u_int32_t *subtree_fingerprint) {
|
2008-03-05 18:34:32 +00:00
|
|
|
void *node_v;
|
|
|
|
int r;
|
2013-04-16 23:57:18 -04:00
|
|
|
r = toku_cachetable_get_and_pin(brt->cf, blocknum, toku_cachetable_hash(brt->cf, blocknum), &node_v, NULL,
|
2008-03-05 18:34:32 +00:00
|
|
|
toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt);
|
|
|
|
if (r!=0) return r;
|
|
|
|
BRTNODE node=node_v;
|
|
|
|
assert(node->height>0);
|
|
|
|
|
|
|
|
DBT k,v;
|
|
|
|
int childnum = toku_brtnode_which_child(node,
|
|
|
|
toku_fill_dbt(&k, key, keylen),
|
|
|
|
toku_fill_dbt(&v, val, vallen),
|
|
|
|
brt);
|
|
|
|
|
|
|
|
r = toku_fifo_enq(BNC_BUFFER(node, childnum), key, keylen, val, vallen, cmdtype, (TXNID)0);
|
|
|
|
assert(r==0);
|
2008-07-27 22:16:49 +00:00
|
|
|
u_int32_t fdelta = node->rand4fingerprint * toku_calc_fingerprint_cmd(cmdtype, (TXNID)0, key, keylen, val, vallen);
|
2008-03-05 18:34:32 +00:00
|
|
|
node->local_fingerprint += fdelta;
|
|
|
|
*subtree_fingerprint += fdelta;
|
|
|
|
int sizediff = keylen + vallen + KEY_VALUE_OVERHEAD + BRT_CMD_OVERHEAD;
|
|
|
|
node->u.n.n_bytes_in_buffers += sizediff;
|
|
|
|
BNC_NBYTESINBUF(node, childnum) += sizediff;
|
|
|
|
node->dirty = 1;
|
|
|
|
|
|
|
|
r = toku_unpin_brtnode(brt, node_v);
|
|
|
|
return r;
|
|
|
|
}
|