Commit 885e0bbb authored by Bradley C. Kuszmaul's avatar Bradley C. Kuszmaul

Put all the child info into one struct. Addresses #126.

git-svn-id: file:///svn/tokudb@2002 c7de825b-a66e-492c-adef-691d508d4ae1
parent 809fcd79
......@@ -35,11 +35,9 @@ struct brtnode_nonleaf_pivotinfo {
};
struct brtnode_nonleaf_childinfo {
u_int32_t subtree_fingerprint;
#if 0
DISKOFF diskoff;
FIFO htable;
FIFO buffer;
unsigned int n_bytes_in_buffer; /* How many bytes are in each buffer (including overheads for the disk-representation) */
#endif
};
typedef struct brtnode *BRTNODE;
......@@ -72,26 +70,15 @@ struct brtnode {
struct brtnode_nonleaf_childinfo childinfos[TREE_FANOUT+1]; /* One extra so we can grow */
#if 0
u_int32_t child_subtree_fingerprints[TREE_FANOUT+1];
#define BRTNODE_CHILD_SUBTREE_FINGERPRINTS(node,i) ((node)->u.n.child_subtree_fingerprints[i])
#else
#define BRTNODE_CHILD_SUBTREE_FINGERPRINTS(node,i) ((node)->u.n.childinfos[i].subtree_fingerprint)
#endif
#define BNC_SUBTREE_FINGERPRINT(node,i) ((node)->u.n.childinfos[i].subtree_fingerprint)
#define BNC_DISKOFF(node,i) ((node)->u.n.childinfos[i].diskoff)
#define BNC_BUFFER(node,i) ((node)->u.n.childinfos[i].buffer)
#define BNC_NBYTESINBUF(node,i) ((node)->u.n.childinfos[i].n_bytes_in_buffer)
//#define CHSTRUCT
#ifdef CHSTRUCT
struct brtnode_nonleaf_pivotinfo pivots[TREE_FANOUT]; /* One extra one so we can grow. */
#else
struct kv_pair *childkeys[TREE_FANOUT]; /* Pivot keys. Child 0's keys are <= childkeys[0]. Child 1's keys are <= childkeys[1].
Note: It is possible that Child 1's keys are == to child 0's key's, so it is
not necessarily true that child 1's keys are > childkeys[0].
However, in the absense of duplicate keys, child 1's keys *are* > childkeys[0]. */
DISKOFF children[TREE_FANOUT+1]; /* unused if height==0 */ /* Note: The last element of these arrays is used only temporarily while splitting a node. */
#define BRTNODE_CHILD_DISKOFF(node,i) ((node)->u.n.children[i])
FIFO buffers[TREE_FANOUT+1];
unsigned int n_bytes_in_buffer[TREE_FANOUT+1]; /* how many bytes are in each buffer (including overheads) */
#endif
} n;
struct leaf {
PMA buffer;
......
......@@ -34,21 +34,21 @@ static void test_serialize(void) {
hello_string = toku_strdup("hello");
sn.u.n.childkeys[0] = kv_pair_malloc(hello_string, 6, 0, 0);
sn.u.n.totalchildkeylens = 6;
sn.u.n.children[0] = sn.nodesize*30;
sn.u.n.children[1] = sn.nodesize*35;
BRTNODE_CHILD_SUBTREE_FINGERPRINTS(&sn, 0) = random();
BRTNODE_CHILD_SUBTREE_FINGERPRINTS(&sn, 1) = random();
r = toku_fifo_create(&sn.u.n.buffers[0]); assert(r==0);
r = toku_fifo_create(&sn.u.n.buffers[1]); assert(r==0);
r = toku_fifo_enq(sn.u.n.buffers[0], "a", 2, "aval", 5, BRT_NONE); assert(r==0); sn.local_fingerprint += randval*toku_calccrc32_cmd(BRT_NONE, "a", 2, "aval", 5);
r = toku_fifo_enq(sn.u.n.buffers[0], "b", 2, "bval", 5, BRT_NONE); assert(r==0); sn.local_fingerprint += randval*toku_calccrc32_cmd(BRT_NONE, "b", 2, "bval", 5);
r = toku_fifo_enq(sn.u.n.buffers[1], "x", 2, "xval", 5, BRT_NONE); assert(r==0); sn.local_fingerprint += randval*toku_calccrc32_cmd(BRT_NONE, "x", 2, "xval", 5);
sn.u.n.n_bytes_in_buffer[0] = 2*(BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+2+5);
sn.u.n.n_bytes_in_buffer[1] = 1*(BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+2+5);
BNC_DISKOFF(&sn, 0) = sn.nodesize*30;
BNC_DISKOFF(&sn, 1) = sn.nodesize*35;
BNC_SUBTREE_FINGERPRINT(&sn, 0) = random();
BNC_SUBTREE_FINGERPRINT(&sn, 1) = random();
r = toku_fifo_create(&BNC_BUFFER(&sn,0)); assert(r==0);
r = toku_fifo_create(&BNC_BUFFER(&sn,1)); assert(r==0);
r = toku_fifo_enq(BNC_BUFFER(&sn,0), "a", 2, "aval", 5, BRT_NONE); assert(r==0); sn.local_fingerprint += randval*toku_calccrc32_cmd(BRT_NONE, "a", 2, "aval", 5);
r = toku_fifo_enq(BNC_BUFFER(&sn,0), "b", 2, "bval", 5, BRT_NONE); assert(r==0); sn.local_fingerprint += randval*toku_calccrc32_cmd(BRT_NONE, "b", 2, "bval", 5);
r = toku_fifo_enq(BNC_BUFFER(&sn,1), "x", 2, "xval", 5, BRT_NONE); assert(r==0); sn.local_fingerprint += randval*toku_calccrc32_cmd(BRT_NONE, "x", 2, "xval", 5);
BNC_NBYTESINBUF(&sn, 0) = 2*(BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+2+5);
BNC_NBYTESINBUF(&sn, 1) = 1*(BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+2+5);
{
int i;
for (i=2; i<TREE_FANOUT+1; i++)
sn.u.n.n_bytes_in_buffer[i]=0;
BNC_NBYTESINBUF(&sn, i)=0;
}
sn.u.n.n_bytes_in_buffers = 3*(BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+2+5);
......@@ -66,12 +66,12 @@ static void test_serialize(void) {
assert(strcmp(kv_pair_key(dn->u.n.childkeys[0]), "hello")==0);
assert(toku_brtnode_pivot_key_len(dn, dn->u.n.childkeys[0])==6);
assert(dn->u.n.totalchildkeylens==6);
assert(dn->u.n.children[0]==nodesize*30);
assert(dn->u.n.children[1]==nodesize*35);
assert(BNC_DISKOFF(dn,0)==nodesize*30);
assert(BNC_DISKOFF(dn,1)==nodesize*35);
{
int i;
for (i=0; i<2; i++) {
assert(BRTNODE_CHILD_SUBTREE_FINGERPRINTS(dn, i)==BRTNODE_CHILD_SUBTREE_FINGERPRINTS(&sn, i));
assert(BNC_SUBTREE_FINGERPRINT(dn, i)==BNC_SUBTREE_FINGERPRINT(&sn, i));
}
assert(dn->local_fingerprint==sn.local_fingerprint);
}
......@@ -101,8 +101,8 @@ static void test_serialize(void) {
kv_pair_free(sn.u.n.childkeys[0]);
toku_free(hello_string);
toku_fifo_free(&sn.u.n.buffers[0]);
toku_fifo_free(&sn.u.n.buffers[1]);
toku_fifo_free(&BNC_BUFFER(&sn,0));
toku_fifo_free(&BNC_BUFFER(&sn,1));
}
int main (int argc __attribute__((__unused__)), char *argv[] __attribute__((__unused__))) {
......
......@@ -46,11 +46,11 @@ static unsigned int toku_serialize_brtnode_size_slow(BRTNODE node) {
size+=4; /* n_entries */
assert(0 <= n_buffers && n_buffers < TREE_FANOUT+1);
for (i=0; i< n_buffers; i++) {
FIFO_ITERATE(node->u.n.buffers[i],
key __attribute__((__unused__)), keylen,
data __attribute__((__unused__)), datalen,
type __attribute__((__unused__)),
(hsize+=BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+keylen+datalen));
FIFO_ITERATE(BNC_BUFFER(node,i),
key __attribute__((__unused__)), keylen,
data __attribute__((__unused__)), datalen,
type __attribute__((__unused__)),
(hsize+=BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+keylen+datalen));
}
assert(hsize==node->u.n.n_bytes_in_buffers);
assert(csize==node->u.n.totalchildkeylens);
......@@ -125,13 +125,13 @@ void toku_serialize_brtnode_to(int fd, DISKOFF off, DISKOFF size, BRTNODE node)
{
u_int32_t subtree_fingerprint = node->local_fingerprint;
for (i=0; i<node->u.n.n_children; i++) {
subtree_fingerprint += BRTNODE_CHILD_SUBTREE_FINGERPRINTS(node, i);
subtree_fingerprint += BNC_SUBTREE_FINGERPRINT(node, i);
}
wbuf_int(&w, subtree_fingerprint);
}
wbuf_int(&w, node->u.n.n_children);
for (i=0; i<node->u.n.n_children; i++) {
wbuf_int(&w, BRTNODE_CHILD_SUBTREE_FINGERPRINTS(node, i));
wbuf_int(&w, BNC_SUBTREE_FINGERPRINT(node, i));
}
//printf("%s:%d w.ndone=%d\n", __FILE__, __LINE__, w.ndone);
for (i=0; i<node->u.n.n_children-1; i++) {
......@@ -144,7 +144,7 @@ void toku_serialize_brtnode_to(int fd, DISKOFF off, DISKOFF size, BRTNODE node)
//printf("%s:%d w.ndone=%d (childkeylen[%d]=%d\n", __FILE__, __LINE__, w.ndone, i, node->childkeylens[i]);
}
for (i=0; i<node->u.n.n_children; i++) {
wbuf_DISKOFF(&w, node->u.n.children[i]);
wbuf_DISKOFF(&w, BNC_DISKOFF(node,i));
//printf("%s:%d w.ndone=%d\n", __FILE__, __LINE__, w.ndone);
}
......@@ -153,8 +153,8 @@ void toku_serialize_brtnode_to(int fd, DISKOFF off, DISKOFF size, BRTNODE node)
u_int32_t check_local_fingerprint = 0;
for (i=0; i< n_buffers; i++) {
//printf("%s:%d p%d=%p n_entries=%d\n", __FILE__, __LINE__, i, node->mdicts[i], mdict_n_entries(node->mdicts[i]));
wbuf_int(&w, toku_fifo_n_entries(node->u.n.buffers[i]));
FIFO_ITERATE(node->u.n.buffers[i], key, keylen, data, datalen, type,
wbuf_int(&w, toku_fifo_n_entries(BNC_BUFFER(node,i)));
FIFO_ITERATE(BNC_BUFFER(node,i), key, keylen, data, datalen, type,
({
wbuf_char(&w, type);
wbuf_bytes(&w, key, keylen);
......@@ -278,13 +278,13 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, BRTNODE *brtnode, int fl
if (result->height>0) {
result->u.n.totalchildkeylens=0;
for (i=0; i<TREE_FANOUT; i++) {
BRTNODE_CHILD_SUBTREE_FINGERPRINTS(result, i)=0;
result->u.n.childkeys[i]=0;
}
for (i=0; i<TREE_FANOUT+1; i++) {
result->u.n.children[i]=0;
result->u.n.buffers[i]=0;
result->u.n.n_bytes_in_buffer[i]=0;
BNC_SUBTREE_FINGERPRINT(result, i)=0;
BNC_DISKOFF(result,i)=0;
BNC_BUFFER(result,i)=0;
BNC_NBYTESINBUF(result,i)=0;
}
u_int32_t subtree_fingerprint = rbuf_int(&rc);
u_int32_t check_subtree_fingerprint = 0;
......@@ -293,7 +293,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, BRTNODE *brtnode, int fl
assert(result->u.n.n_children>=0 && result->u.n.n_children<=TREE_FANOUT);
for (i=0; i<result->u.n.n_children; i++) {
u_int32_t childfp = rbuf_int(&rc);
BRTNODE_CHILD_SUBTREE_FINGERPRINTS(result, i)= childfp;
BNC_SUBTREE_FINGERPRINT(result, i)= childfp;
check_subtree_fingerprint += childfp;
}
for (i=0; i<result->u.n.n_children-1; i++) {
......@@ -313,19 +313,19 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, BRTNODE *brtnode, int fl
result->u.n.totalchildkeylens+=toku_brtnode_pivot_key_len(result, result->u.n.childkeys[i]);
}
for (i=0; i<result->u.n.n_children; i++) {
result->u.n.children[i] = rbuf_diskoff(&rc);
BNC_DISKOFF(result,i) = rbuf_diskoff(&rc);
//printf("Child %d at %lld\n", i, result->children[i]);
}
for (i=0; i<TREE_FANOUT+1; i++) {
result->u.n.n_bytes_in_buffer[i] = 0;
BNC_NBYTESINBUF(result,i)=0;
}
result->u.n.n_bytes_in_buffers = 0;
for (i=0; i<result->u.n.n_children; i++) {
r=toku_fifo_create(&result->u.n.buffers[i]);
r=toku_fifo_create(&BNC_BUFFER(result,i));
if (r!=0) {
int j;
if (0) { died_12: j=result->u.n.n_bytes_in_buffers; }
for (j=0; j<i; j++) toku_fifo_free(&result->u.n.buffers[j]);
for (j=0; j<i; j++) toku_fifo_free(&BNC_BUFFER(result,j));
goto died1;
}
}
......@@ -347,12 +347,12 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, BRTNODE *brtnode, int fl
check_local_fingerprint += result->rand4fingerprint * toku_calccrc32_cmd(type, key, keylen, val, vallen);
//printf("Found %s,%s\n", (char*)key, (char*)val);
{
r=toku_fifo_enq(result->u.n.buffers[cnum], key, keylen, val, vallen, type); /* Copies the data into the hash table. */
r=toku_fifo_enq(BNC_BUFFER(result, cnum), key, keylen, val, vallen, type); /* Copies the data into the hash table. */
if (r!=0) { goto died_12; }
}
diff = keylen + vallen + KEY_VALUE_OVERHEAD + BRT_CMD_OVERHEAD;
result->u.n.n_bytes_in_buffers += diff;
result->u.n.n_bytes_in_buffer[cnum] += diff;
BNC_NBYTESINBUF(result,cnum) += diff;
//printf("Inserted\n");
}
}
......@@ -456,11 +456,11 @@ void toku_verify_counts (BRTNODE node) {
unsigned int sum = 0;
int i;
for (i=0; i<node->u.n.n_children; i++)
sum += node->u.n.n_bytes_in_buffer[i];
sum += BNC_NBYTESINBUF(node,i);
// We don't rally care of the later buffers have garbage in them. Valgrind would do a better job noticing if we leave it uninitialized.
// But for now the code always initializes the later tables so they are 0.
for (; i<TREE_FANOUT+1; i++) {
assert(node->u.n.n_bytes_in_buffer[i]==0);
assert(BNC_NBYTESINBUF(node,i)==0);
}
assert(sum==node->u.n.n_bytes_in_buffers);
}
......
......@@ -24,7 +24,7 @@ static void verify_local_fingerprint (BRTNODE node) {
int i;
if (node->height>0) {
for (i=0; i<node->u.n.n_children; i++)
FIFO_ITERATE(node->u.n.buffers[i], key, keylen, data, datalen, type,
FIFO_ITERATE(BNC_BUFFER(node,i), key, keylen, data, datalen, type,
({
fp += node->rand4fingerprint * toku_calccrc32_cmd(type, key, keylen, data, datalen);
}));
......@@ -76,7 +76,7 @@ int toku_verify_brtnode (BRT brt, DISKOFF off, bytevec lorange, ITEMLEN lolen, b
result=1;
}
}
toku_fifo_iterate(node->u.n.buffers[i], verify_pair, 0);
toku_fifo_iterate(BNC_BUFFER(node,i), verify_pair, 0);
}
}
for (i=0; i<node->u.n.n_children; i++) {
......@@ -85,7 +85,7 @@ int toku_verify_brtnode (BRT brt, DISKOFF off, bytevec lorange, ITEMLEN lolen, b
if (hirange) assert(toku_keycompare(kv_pair_key(node->u.n.childkeys[i-1]), toku_brt_pivot_key_len(brt, node->u.n.childkeys[i-1]), hirange, hilen)<=0);
}
if (recurse) {
result|=toku_verify_brtnode(brt, node->u.n.children[i],
result|=toku_verify_brtnode(brt, BNC_DISKOFF(node, i),
(i==0) ? lorange : kv_pair_key(node->u.n.childkeys[i-1]),
(i==0) ? lolen : toku_brt_pivot_key_len(brt, node->u.n.childkeys[i-1]),
(i==node->u.n.n_children-1) ? hirange : kv_pair_key(node->u.n.childkeys[i]),
......
This diff is collapsed.
......@@ -64,7 +64,7 @@ void dump_node (int f, DISKOFF off, struct brt_header *h) {
printf(" subfingerprints={");
for (i=0; i<n->u.n.n_children; i++) {
if (i>0) printf(" ");
printf("%08x", BRTNODE_CHILD_SUBTREE_FINGERPRINTS(n, i));
printf("%08x", BNC_SUBTREE_FINGERPRINT(n, i));
}
printf("}\n");
printf(" pivots:\n");
......@@ -77,7 +77,7 @@ void dump_node (int f, DISKOFF off, struct brt_header *h) {
}
printf(" children:\n");
for (i=0; i<n->u.n.n_children; i++) {
printf(" child %d: %lld\n", i, BRTNODE_CHILD_DISKOFF(n, i));
printf(" child %d: %lld\n", i, BNC_DISKOFF(n, i));
printf(" buffer contains %d bytes (%d items)\n", n->u.n.n_bytes_in_buffer[i], toku_fifo_n_entries(n->u.n.buffers[i]));
FIFO_ITERATE(n->u.n.buffers[i], key, keylen, data, datalen, typ,
({
......
......@@ -239,16 +239,14 @@ void toku_recover_addchild (struct logtype_addchild *le) {
unsigned int i;
for (i=node->u.n.n_children; i>le->childnum; i--) {
node->u.n.childinfos[i]=node->u.n.childinfos[i-1];
BRTNODE_CHILD_DISKOFF(node,i) = BRTNODE_CHILD_DISKOFF(node, i-1);
node->u.n.buffers[i] = node->u.n.buffers[i-1];
node->u.n.n_bytes_in_buffer[i] = node->u.n.n_bytes_in_buffer[i-1];
assert(i>=2);
node->u.n.childkeys [i-1] = node->u.n.childkeys [i-2];
}
node->u.n.childinfos[le->childnum].subtree_fingerprint = le->childfingerprint;
node->u.n.children [le->childnum] = le->child;
BNC_DISKOFF(node, le->childnum) = le->child;
node->u.n.childkeys [le->childnum-1] = 0;
int r= toku_fifo_create(&node->u.n.buffers[le->childnum]); assert(r==0);
int r= toku_fifo_create(&BNC_BUFFER(node, le->childnum)); assert(r==0);
node->u.n.n_bytes_in_buffer[le->childnum] = 0;
node->u.n.n_children++;
node->log_lsn = le->lsn;
......@@ -271,20 +269,17 @@ void toku_recover_delchild (struct logtype_delchild *le) {
u_int32_t childnum = le->childnum;
assert(childnum < (unsigned)node->u.n.n_children);
assert(node->u.n.childinfos[childnum].subtree_fingerprint == le->childfingerprint);
assert(node->u.n.children[childnum]==le->child);
assert(toku_fifo_n_entries(node->u.n.buffers[childnum])==0);
assert(BNC_DISKOFF(node, childnum)==le->child);
assert(toku_fifo_n_entries(BNC_BUFFER(node,childnum))==0);
assert(node->u.n.n_bytes_in_buffer[childnum]==0);
assert(node->u.n.n_children>2); // Must be at least two children.
u_int32_t i;
assert(childnum>0);
node->u.n.totalchildkeylens -= toku_brt_pivot_key_len(pair->brt, node->u.n.childkeys[childnum-1]);
toku_free((void*)node->u.n.childkeys[childnum-1]);
toku_fifo_free(&node->u.n.buffers[childnum]);
toku_fifo_free(&BNC_BUFFER(node,childnum));
for (i=childnum+1; i<(unsigned)node->u.n.n_children; i++) {
node->u.n.childinfos[i-1] = node->u.n.childinfos[i];
BRTNODE_CHILD_SUBTREE_FINGERPRINTS(node, i-1) = BRTNODE_CHILD_SUBTREE_FINGERPRINTS(node, i);
BRTNODE_CHILD_DISKOFF(node, i-1) = BRTNODE_CHILD_DISKOFF(node, i);
node->u.n.buffers[i-1] = node->u.n.buffers[i];
node->u.n.n_bytes_in_buffer[i-1] = node->u.n.n_bytes_in_buffer[i];
node->u.n.childkeys[i-2] = node->u.n.childkeys[i-1];
}
......@@ -308,7 +303,7 @@ void toku_recover_setchild (struct logtype_setchild *le) {
BRTNODE node = node_v;
assert(node->height>0);
assert(le->childnum < (unsigned)node->u.n.n_children);
node->u.n.children[le->childnum] = le->newchild;
BNC_DISKOFF(node, le->childnum) = le->newchild;
node->log_lsn = le->lsn;
r = toku_cachetable_unpin(pair->cf, le->diskoff, 1, toku_serialize_brtnode_size(node));
assert(r==0);
......@@ -348,7 +343,7 @@ void toku_recover_changechildfingerprint (struct logtype_changechildfingerprint
BRTNODE node = node_v;
assert(node->height>0);
assert((signed)le->childnum < node->u.n.n_children);
BRTNODE_CHILD_SUBTREE_FINGERPRINTS(node, le->childnum) = le->newfingerprint;
BNC_SUBTREE_FINGERPRINT(node, le->childnum) = le->newfingerprint;
node->log_lsn = le->lsn;
r = toku_cachetable_unpin(pair->cf, le->diskoff, 1, toku_serialize_brtnode_size(node));
assert(r==0);
......
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