diff --git a/newbrt/brt-internal.h b/newbrt/brt-internal.h index fd1a77ac39d..62ed3056cad 100644 --- a/newbrt/brt-internal.h +++ b/newbrt/brt-internal.h @@ -39,7 +39,7 @@ enum { BUFFER_HEADER_SIZE = (4 // height// struct brtnode_nonleaf_childinfo { u_int32_t subtree_fingerprint; u_int64_t leafentry_estimate; // estimate how many leafentries are below us. - DISKOFF diskoff; + BLOCKNUM blocknum; BOOL have_fullhash; // do we have the full hash? u_int32_t fullhash; // the fullhash of the child FIFO buffer; @@ -53,7 +53,7 @@ struct brtnode { unsigned int nodesize; int ever_been_written; unsigned int flags; - DISKOFF thisnodename; // The size of the node allocated on disk. Not all is necessarily in use. + BLOCKNUM thisnodename; // Which block number is this node? // These two LSNs are used to decide when to make a copy of a node instead of overwriting it. // In the TOKULOGGER is a field called checkpoint_lsn which is the lsn of the most recent checkpoint LSN disk_lsn; // The LSN as of the most recent version on disk. (Updated by brt-serialize) This lsn is saved in the node. @@ -80,7 +80,7 @@ struct brtnode { #define BNC_SUBTREE_FINGERPRINT(node,i) ((node)->u.n.childinfos[i].subtree_fingerprint) #define BNC_SUBTREE_LEAFENTRY_ESTIMATE(node,i) ((node)->u.n.childinfos[i].leafentry_estimate) -#define BNC_DISKOFF(node,i) ((node)->u.n.childinfos[i].diskoff) +#define BNC_BLOCKNUM(node,i) ((node)->u.n.childinfos[i].blocknum) #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 BNC_HAVE_FULLHASH(node,i) ((node)->u.n.childinfos[i].have_fullhash) @@ -109,7 +109,7 @@ enum { struct remembered_hash { BOOL valid; // set to FALSE if the fullhash is invalid FILENUM fnum; - DISKOFF root; + BLOCKNUM root; u_int32_t fullhash; // fullhash is the hashed value of fnum and root. }; @@ -118,15 +118,19 @@ struct brt_header { u_int32_t fullhash; int layout_version; unsigned int nodesize; - DISKOFF freelist; - DISKOFF unused_memory; int n_named_roots; /* -1 if the only one is unnamed */ char **names; // an array of names. NULL if subdatabases are not allowed. - DISKOFF *roots; // an array of DISKOFFs. Element 0 holds the element if no subdatabases allowed. + BLOCKNUM *roots; // An array of the roots of the various dictionaries. Element 0 holds the element if no subdatabases allowed. struct remembered_hash *root_hashes; // an array of hashes of the root offsets. unsigned int *flags_array; // an array of flags. Element 0 holds the element if no subdatabases allowed. FIFO fifo; // all the abort and commit commands. If the header gets flushed to disk, we write the fifo contents beyond the unused_memory. + + // This is the map from block numbers to offsets + //int n_blocks, n_blocks_array_size; + //struct block_descriptor *blocks; + BLOCKNUM free_blocks; // free list for blocks. Use -1 to indicate that there are no free blocks + BLOCKNUM unused_blocks; // first unused block }; struct brt { @@ -153,8 +157,8 @@ struct brt { }; /* serialization code */ -void toku_serialize_brtnode_to(int fd, DISKOFF off, BRTNODE node); -int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t /*fullhash*/, BRTNODE *brtnode); +void toku_serialize_brtnode_to(int fd, BLOCKNUM, BRTNODE node); +int toku_deserialize_brtnode_from (int fd, BLOCKNUM off, u_int32_t /*fullhash*/, BRTNODE *brtnode, int tree_node_size); unsigned int toku_serialize_brtnode_size(BRTNODE node); /* How much space will it take? */ int toku_keycompare (bytevec key1, ITEMLEN key1len, bytevec key2, ITEMLEN key2len); @@ -163,7 +167,7 @@ void toku_verify_counts(BRTNODE); int toku_serialize_brt_header_size (struct brt_header *h); int toku_serialize_brt_header_to (int fd, struct brt_header *h); int toku_serialize_brt_header_to_wbuf (struct wbuf *, struct brt_header *h); -int toku_deserialize_brtheader_from (int fd, DISKOFF off, u_int32_t fullhash, struct brt_header **brth); +int toku_deserialize_brtheader_from (int fd, BLOCKNUM off, u_int32_t fullhash, struct brt_header **brth); int toku_serialize_fifo_at (int fd, off_t freeoff, FIFO fifo); // Write a fifo into a disk, without worrying about fitting it into a block. This write is done at the end of the file. int toku_deserialize_fifo_at (int fd, off_t at, FIFO *fifo); @@ -219,12 +223,12 @@ int toku_unpin_brtnode (BRT brt, BRTNODE node); unsigned int toku_brtnode_which_child (BRTNODE node , DBT *k, DBT *d, BRT t); /* Stuff for testing */ -int toku_testsetup_leaf(BRT brt, DISKOFF *diskoff); -int toku_testsetup_nonleaf (BRT brt, int height, DISKOFF *diskoff, int n_children, DISKOFF *children, u_int32_t *subtree_fingerprints, char **keys, int *keylens); -int toku_testsetup_root(BRT brt, DISKOFF diskoff); -int toku_testsetup_get_sersize(BRT brt, DISKOFF diskoff); // Return the size on disk. -int toku_testsetup_insert_to_leaf (BRT brt, DISKOFF diskoff, char *key, int keylen, char *val, int vallen, u_int32_t *leaf_fingerprint); -int toku_testsetup_insert_to_nonleaf (BRT brt, DISKOFF diskoff, enum brt_cmd_type, char *key, int keylen, char *val, int vallen, u_int32_t *subtree_fingerprint); +int toku_testsetup_leaf(BRT brt, BLOCKNUM *); +int toku_testsetup_nonleaf (BRT brt, int height, BLOCKNUM *diskoff, int n_children, BLOCKNUM *children, u_int32_t *subtree_fingerprints, char **keys, int *keylens); +int toku_testsetup_root(BRT brt, BLOCKNUM); +int toku_testsetup_get_sersize(BRT brt, BLOCKNUM); // Return the size on disk. +int toku_testsetup_insert_to_leaf (BRT brt, BLOCKNUM, char *key, int keylen, char *val, int vallen, u_int32_t *leaf_fingerprint); +int toku_testsetup_insert_to_nonleaf (BRT brt, BLOCKNUM, enum brt_cmd_type, char *key, int keylen, char *val, int vallen, u_int32_t *subtree_fingerprint); int toku_set_func_fsync (int (*fsync_function)(int)); @@ -243,13 +247,14 @@ void *mempool_malloc_from_omt(OMT omt, struct mempool *mp, size_t size); void toku_verify_all_in_mempool(BRTNODE node); -int toku_verify_brtnode (BRT brt, DISKOFF off, bytevec lorange, ITEMLEN lolen, bytevec hirange, ITEMLEN hilen, int recurse) ; +int toku_verify_brtnode (BRT brt, BLOCKNUM blocknum, bytevec lorange, ITEMLEN lolen, bytevec hirange, ITEMLEN hilen, int recurse) ; enum brt_layout_version_e { BRT_LAYOUT_VERSION_5 = 5, BRT_LAYOUT_VERSION_6 = 6, // Diff from 5 to 6: Add leafentry_estimate BRT_LAYOUT_VERSION_7 = 7, // Diff from 6 to 7: Add exact-bit to leafentry_estimate #818, add magic to header #22, add per-subdatase flags #333 BRT_LAYOUT_VERSION_8 = 8, // Diff from 7 to 8: Use murmur instead of crc32. We are going to make a simplification and stop supporting version 7 and before. Current As of Beta 1.0.6 + BRT_LAYOUT_VERSION_9 = 9, // Diff from 8 to 9: Variable-sized blocks and compression. BRT_ANTEULTIMATE_VERSION, // the version after the most recent version BRT_LAYOUT_VERSION = BRT_ANTEULTIMATE_VERSION-1 // A hack so I don't have to change this line. }; diff --git a/newbrt/brt-serialize.c b/newbrt/brt-serialize.c index 6580fc2fb75..8eb04371e0a 100644 --- a/newbrt/brt-serialize.c +++ b/newbrt/brt-serialize.c @@ -9,6 +9,7 @@ #include "kv-pair.h" #include "mempool.h" +#include #include #include #include @@ -111,8 +112,9 @@ const int uncompressed_magic_len = (8 // tokuleaf or tokunode const int compression_header_len = (4 // compressed_len +4); // uncompressed_len -void toku_serialize_brtnode_to (int fd, DISKOFF off, BRTNODE node) { +void toku_serialize_brtnode_to (int fd, BLOCKNUM blocknum, BRTNODE node) { //printf("%s:%d serializing\n", __FILE__, __LINE__); + DISKOFF offset = blocknum.b * node->nodesize; struct wbuf w; int i; unsigned int calculated_size = toku_serialize_brtnode_size(node) - 8; // don't include the compressed or uncompressed sizes @@ -165,7 +167,7 @@ void toku_serialize_brtnode_to (int fd, DISKOFF off, BRTNODE node) { //printf("%s:%d w.ndone=%d (childkeylen[%d]=%d\n", __FILE__, __LINE__, w.ndone, i, node->childkeylens[i]); } for (i=0; iu.n.n_children; i++) { - wbuf_DISKOFF(&w, BNC_DISKOFF(node,i)); + wbuf_BLOCKNUM(&w, BNC_BLOCKNUM(node,i)); //printf("%s:%d w.ndone=%d\n", __FILE__, __LINE__, w.ndone); } @@ -185,7 +187,7 @@ void toku_serialize_brtnode_to (int fd, DISKOFF off, BRTNODE node) { })); } //printf("%s:%d check_local_fingerprint=%8x\n", __FILE__, __LINE__, check_local_fingerprint); - if (check_local_fingerprint!=node->local_fingerprint) printf("%s:%d node=%lld fingerprint expected=%08x actual=%08x\n", __FILE__, __LINE__, (long long)node->thisnodename, check_local_fingerprint, node->local_fingerprint); + if (check_local_fingerprint!=node->local_fingerprint) printf("%s:%d node=%" PRId64 " fingerprint expected=%08x actual=%08x\n", __FILE__, __LINE__, node->thisnodename.b, check_local_fingerprint, node->local_fingerprint); assert(check_local_fingerprint==node->local_fingerprint); } } else { @@ -240,7 +242,7 @@ void toku_serialize_brtnode_to (int fd, DISKOFF off, BRTNODE node) { { // If the node has never been written, then write the whole buffer, including the zeros size_t n_to_write = uncompressed_magic_len + compression_header_len + compressed_len; - ssize_t r=pwrite(fd, compressed_buf, n_to_write, off); + ssize_t r=pwrite(fd, compressed_buf, n_to_write, offset); if (r<0) printf("r=%ld errno=%d\n", (long)r, errno); assert(r==(ssize_t)n_to_write); } @@ -251,7 +253,8 @@ void toku_serialize_brtnode_to (int fd, DISKOFF off, BRTNODE node) { toku_free(compressed_buf); } -int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTNODE *brtnode) { +int toku_deserialize_brtnode_from (int fd, BLOCKNUM blocknum, u_int32_t fullhash, BRTNODE *brtnode, int tree_node_size) { + DISKOFF offset = blocknum.b * tree_node_size; TAGMALLOC(BRTNODE, result); struct rbuf rc; int i; @@ -267,7 +270,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN u_int32_t uncompressed_size; { // get the compressed size - r = pread(fd, uncompressed_header, sizeof(uncompressed_header), off); + r = pread(fd, uncompressed_header, sizeof(uncompressed_header), offset); //printf("%s:%d r=%d the datasize=%d\n", __FILE__, __LINE__, r, ntohl(datasize_n)); if (r!=(int)sizeof(uncompressed_header)) { if (r==-1) r=errno; @@ -285,7 +288,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN assert(compressed_data); { - ssize_t rlen=pread(fd, compressed_data, compressed_size, off+uncompressed_magic_len + compression_header_len); + ssize_t rlen=pread(fd, compressed_data, compressed_size, offset+uncompressed_magic_len + compression_header_len); //printf("%s:%d pread->%d datasize=%d\n", __FILE__, __LINE__, r, datasize); assert((size_t)rlen==compressed_size); //printf("Got %d %d %d %d\n", rc.buf[0], rc.buf[1], rc.buf[2], rc.buf[3]); @@ -324,7 +327,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN result->layout_version = rbuf_int(&rc); { switch (result->layout_version) { - case BRT_LAYOUT_VERSION_8: goto ok_layout_version; + case BRT_LAYOUT_VERSION_9: goto ok_layout_version; // Don't support older versions. } r=DB_BADFORMAT; @@ -335,7 +338,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN result->nodesize = rbuf_int(&rc); result->log_lsn = result->disk_lsn; - result->thisnodename = off; + result->thisnodename = blocknum; result->flags = rbuf_int(&rc); result->height = rbuf_int(&rc); result->rand4fingerprint = rbuf_int(&rc); @@ -376,7 +379,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN result->u.n.totalchildkeylens+=toku_brtnode_pivot_key_len(result, result->u.n.childkeys[i]); } for (i=0; iu.n.n_children; i++) { - BNC_DISKOFF(result,i) = rbuf_diskoff(&rc); + BNC_BLOCKNUM(result,i) = rbuf_blocknum(&rc); BNC_HAVE_FULLHASH(result, i) = FALSE; BNC_NBYTESINBUF(result,i) = 0; //printf("Child %d at %lld\n", i, result->children[i]); @@ -567,21 +570,21 @@ int toku_serialize_brt_header_to_wbuf (struct wbuf *wbuf, struct brt_header *h) wbuf_int (wbuf, size); wbuf_int (wbuf, BRT_LAYOUT_VERSION); wbuf_int (wbuf, h->nodesize); - wbuf_DISKOFF(wbuf, h->freelist); - wbuf_DISKOFF(wbuf, h->unused_memory); + wbuf_BLOCKNUM(wbuf, h->free_blocks); + wbuf_BLOCKNUM(wbuf, h->unused_blocks); wbuf_int (wbuf, h->n_named_roots); if (h->n_named_roots>=0) { int i; for (i=0; in_named_roots; i++) { char *s = h->names[i]; unsigned int l = 1+strlen(s); - wbuf_DISKOFF(wbuf, h->roots[i]); + wbuf_BLOCKNUM(wbuf, h->roots[i]); wbuf_int (wbuf, h->flags_array[i]); wbuf_bytes (wbuf, s, l); assert(l>0 && s[l-1]==0); } } else { - wbuf_DISKOFF(wbuf, h->roots[0]); + wbuf_BLOCKNUM(wbuf, h->roots[0]); wbuf_int (wbuf, h->flags_array[0]); } assert(wbuf->ndone<=wbuf->size); @@ -623,10 +626,11 @@ int deserialize_brtheader_7_or_later(u_int32_t size, int fd, DISKOFF off, struct h->dirty=0; h->layout_version = rbuf_int(&rc); h->nodesize = rbuf_int(&rc); - assert(h->layout_version==BRT_LAYOUT_VERSION_8); - h->freelist = rbuf_diskoff(&rc); - h->unused_memory = rbuf_diskoff(&rc); + assert(h->layout_version==BRT_LAYOUT_VERSION_9); + h->free_blocks = rbuf_blocknum(&rc); + h->unused_blocks = rbuf_blocknum(&rc); h->n_named_roots = rbuf_int(&rc); + h->free_blocks = make_blocknum(-1); if (h->n_named_roots>=0) { int i; int n_to_malloc = (h->n_named_roots == 0) ? 1 : h->n_named_roots; @@ -636,7 +640,7 @@ int deserialize_brtheader_7_or_later(u_int32_t size, int fd, DISKOFF off, struct MALLOC_N(n_to_malloc, h->names); if (h->names==0) { ret=errno; if (0) { died5: if (h->n_named_roots>=0) free(h->names); } goto died4; } for (i=0; in_named_roots; i++) { h->root_hashes[i].valid = FALSE; - h->roots[i] = rbuf_diskoff(&rc); + h->roots[i] = rbuf_blocknum(&rc); h->flags_array[i] = rbuf_int(&rc); bytevec nameptr; unsigned int len; @@ -651,7 +655,7 @@ int deserialize_brtheader_7_or_later(u_int32_t size, int fd, DISKOFF off, struct MALLOC_N(n_to_malloc, h->roots); if (h->roots==0) { ret=errno; goto died2; } MALLOC_N(n_to_malloc, h->root_hashes); if (h->root_hashes==0) { ret=errno; goto died3; } h->names = 0; - h->roots[0] = rbuf_diskoff(&rc); + h->roots[0] = rbuf_blocknum(&rc); h->root_hashes[0].valid = FALSE; h->flags_array[0] = rbuf_int(&rc); } @@ -661,19 +665,20 @@ int deserialize_brtheader_7_or_later(u_int32_t size, int fd, DISKOFF off, struct return 0; } -int toku_deserialize_brtheader_from (int fd, DISKOFF off, u_int32_t fullhash, struct brt_header **brth) { +int toku_deserialize_brtheader_from (int fd, BLOCKNUM blocknum, u_int32_t fullhash, struct brt_header **brth) { //printf("%s:%d calling MALLOC\n", __FILE__, __LINE__); - assert(off==0); + assert(blocknum.b==0); + DISKOFF offset = 0; //printf("%s:%d malloced %p\n", __FILE__, __LINE__, h); char magic[12]; - ssize_t r = pread(fd, magic, 12, off); + ssize_t r = pread(fd, magic, 12, offset); if (r==0) return -1; if (r<0) return errno; if (r!=12) return EINVAL; assert(memcmp(magic,"tokudata",8)==0); // It's version 7 or later, and the magi clooks OK - return deserialize_brtheader_7_or_later(ntohl(*(int*)(&magic[8])), fd, off, brth, fullhash); + return deserialize_brtheader_7_or_later(ntohl(*(int*)(&magic[8])), fd, offset, brth, fullhash); } unsigned int toku_brt_pivot_key_len (BRT brt, struct kv_pair *pk) { diff --git a/newbrt/brt-test-helpers.c b/newbrt/brt-test-helpers.c index d2cac121a66..17b30c98b26 100644 --- a/newbrt/brt-test-helpers.c +++ b/newbrt/brt-test-helpers.c @@ -1,13 +1,13 @@ #include "brt-internal.h" #include "toku_assert.h" -int toku_testsetup_leaf(BRT brt, DISKOFF *diskoff) { +int toku_testsetup_leaf(BRT brt, BLOCKNUM *blocknum) { BRTNODE node; int r = toku_read_and_pin_brt_header(brt->cf, &brt->h); if (r!=0) return r; toku_create_new_brtnode(brt, &node, 0, (TOKULOGGER)0); - *diskoff = node->thisnodename; + *blocknum = node->thisnodename; r = toku_unpin_brtnode(brt, node); if (r!=0) return r; r = toku_unpin_brt_header(brt); @@ -16,7 +16,7 @@ int toku_testsetup_leaf(BRT brt, DISKOFF *diskoff) { } // 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.) -int toku_testsetup_nonleaf (BRT brt, int height, DISKOFF *diskoff, int n_children, DISKOFF *children, u_int32_t *subtree_fingerprints, char **keys, int *keylens) { +int toku_testsetup_nonleaf (BRT brt, int height, BLOCKNUM *blocknum, int n_children, BLOCKNUM *children, u_int32_t *subtree_fingerprints, char **keys, int *keylens) { BRTNODE node; assert(n_children<=BRT_FANOUT); int r = toku_read_and_pin_brt_header(brt->cf, &brt->h); @@ -31,7 +31,7 @@ int toku_testsetup_nonleaf (BRT brt, int height, DISKOFF *diskoff, int n_childre for (i=0; iu.n.childinfos[i] = (struct brtnode_nonleaf_childinfo){ .subtree_fingerprint = subtree_fingerprints[i], .leafentry_estimate = 0, - .diskoff = children[i], + .blocknum = children[i], .n_bytes_in_buffer = 0 }; r = toku_fifo_create(&BNC_BUFFER(node,i)); if (r!=0) return r; } @@ -39,7 +39,7 @@ int toku_testsetup_nonleaf (BRT brt, int height, DISKOFF *diskoff, int n_childre node->u.n.childkeys[i] = kv_pair_malloc(keys[i], keylens[i], 0, 0); node->u.n.totalchildkeylens += keylens[i]; } - *diskoff = node->thisnodename; + *blocknum = node->thisnodename; r = toku_unpin_brtnode(brt, node); if (r!=0) return r; r = toku_unpin_brt_header(brt); @@ -47,16 +47,16 @@ int toku_testsetup_nonleaf (BRT brt, int height, DISKOFF *diskoff, int n_childre return 0; } -int toku_testsetup_root(BRT brt, DISKOFF diskoff) { +int toku_testsetup_root(BRT brt, BLOCKNUM blocknum) { int r = toku_read_and_pin_brt_header(brt->cf, &brt->h); if (r!=0) return r; - brt->h->roots[0] = diskoff; + brt->h->roots[0] = blocknum; brt->h->root_hashes[0].valid = FALSE; r = toku_unpin_brt_header(brt); return r; } -int toku_testsetup_get_sersize(BRT brt, DISKOFF diskoff) // Return the size on disk +int toku_testsetup_get_sersize(BRT brt, BLOCKNUM diskoff) // Return the size on disk { void *node_v; int r = toku_cachetable_get_and_pin(brt->cf, diskoff, toku_cachetable_hash(brt->cf, diskoff), &node_v, NULL, @@ -68,10 +68,10 @@ int toku_testsetup_get_sersize(BRT brt, DISKOFF diskoff) // Return the size on d return size; } -int toku_testsetup_insert_to_leaf (BRT brt, DISKOFF diskoff, char *key, int keylen, char *val, int vallen, u_int32_t *subtree_fingerprint) { +int toku_testsetup_insert_to_leaf (BRT brt, BLOCKNUM blocknum, char *key, int keylen, char *val, int vallen, u_int32_t *subtree_fingerprint) { void *node_v; int r; - r = toku_cachetable_get_and_pin(brt->cf, diskoff, toku_cachetable_hash(brt->cf, diskoff), &node_v, NULL, + r = toku_cachetable_get_and_pin(brt->cf, blocknum, toku_cachetable_hash(brt->cf, blocknum), &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt); if (r!=0) return r; BRTNODE node=node_v; @@ -120,10 +120,10 @@ int toku_testsetup_insert_to_leaf (BRT brt, DISKOFF diskoff, char *key, int keyl return r; } -int toku_testsetup_insert_to_nonleaf (BRT brt, DISKOFF diskoff, enum brt_cmd_type cmdtype, char *key, int keylen, char *val, int vallen, u_int32_t *subtree_fingerprint) { +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) { void *node_v; int r; - r = toku_cachetable_get_and_pin(brt->cf, diskoff, toku_cachetable_hash(brt->cf, diskoff), &node_v, NULL, + r = toku_cachetable_get_and_pin(brt->cf, blocknum, toku_cachetable_hash(brt->cf, blocknum), &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt); if (r!=0) return r; BRTNODE node=node_v; diff --git a/newbrt/brt-verify.c b/newbrt/brt-verify.c index a4d6321dc35..d087833e33f 100644 --- a/newbrt/brt-verify.c +++ b/newbrt/brt-verify.c @@ -59,13 +59,13 @@ static int compare_leafentries (BRT brt, LEAFENTRY a, LEAFENTRY b) { return cmp; } -int toku_verify_brtnode (BRT brt, DISKOFF off, bytevec lorange, ITEMLEN lolen, bytevec hirange, ITEMLEN hilen, int recurse) { +int toku_verify_brtnode (BRT brt, BLOCKNUM blocknum, bytevec lorange, ITEMLEN lolen, bytevec hirange, ITEMLEN hilen, int recurse) { int result=0; BRTNODE node; void *node_v; int r; - u_int32_t fullhash = toku_cachetable_hash(brt->cf, off); - if ((r = toku_cachetable_get_and_pin(brt->cf, off, fullhash, &node_v, NULL, + u_int32_t fullhash = toku_cachetable_hash(brt->cf, blocknum); + if ((r = toku_cachetable_get_and_pin(brt->cf, blocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, (void*)(long)brt->h->nodesize))) return r; //printf("%s:%d pin %p\n", __FILE__, __LINE__, node_v); @@ -128,7 +128,7 @@ int toku_verify_brtnode (BRT brt, DISKOFF off, bytevec lorange, ITEMLEN lolen, b if (hirange) assert(brt->compare_fun(brt->db, &k2, toku_fill_dbt(&k3, hirange, hilen)) <=0); } if (recurse) { - result|=toku_verify_brtnode(brt, BNC_DISKOFF(node, i), + result|=toku_verify_brtnode(brt, BNC_BLOCKNUM(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]), @@ -149,7 +149,7 @@ int toku_verify_brtnode (BRT brt, DISKOFF off, bytevec lorange, ITEMLEN lolen, b LEAFENTRY prev=0; toku_omt_iterate(node->u.l.buffer, check_increasing, &prev); } - if ((r = toku_cachetable_unpin(brt->cf, off, fullhash, 0, 0))) return r; + if ((r = toku_cachetable_unpin(brt->cf, blocknum, fullhash, 0, 0))) return r; return result; } diff --git a/newbrt/brt.c b/newbrt/brt.c index 8ab9e7298bf..7bbfaa9d1de 100644 --- a/newbrt/brt.c +++ b/newbrt/brt.c @@ -51,7 +51,6 @@ extern long long n_items_malloced; -static int malloc_diskblock (DISKOFF *res, BRT brt, int size, TOKULOGGER); static void verify_local_fingerprint_nonleaf (BRTNODE node); // We invalidate all the OMTCURSORS any time we push into the root of the BRT for that OMT. @@ -161,18 +160,18 @@ static int brt_compare_pivot(BRT brt, DBT *key, DBT *data, bytevec ck) { return cmp; } -void toku_brtnode_flush_callback (CACHEFILE cachefile, DISKOFF nodename, void *brtnode_v, long size __attribute((unused)), BOOL write_me, BOOL keep_me, LSN modified_lsn __attribute__((__unused__)) , BOOL rename_p __attribute__((__unused__))) { +void toku_brtnode_flush_callback (CACHEFILE cachefile, BLOCKNUM nodename, void *brtnode_v, long size __attribute((unused)), BOOL write_me, BOOL keep_me, LSN modified_lsn __attribute__((__unused__)) , BOOL rename_p __attribute__((__unused__))) { BRTNODE brtnode = brtnode_v; // if ((write_me || keep_me) && (brtnode->height==0)) { // toku_pma_verify_fingerprint(brtnode->u.l.buffer, brtnode->rand4fingerprint, brtnode->subtree_fingerprint); // } if (0) { - printf("%s:%d toku_brtnode_flush_callback %p thisnodename=%lld keep_me=%d height=%d", __FILE__, __LINE__, brtnode, (long long)brtnode->thisnodename, keep_me, brtnode->height); + printf("%s:%d toku_brtnode_flush_callback %p thisnodename=%" PRId64 " keep_me=%d height=%d", __FILE__, __LINE__, brtnode, brtnode->thisnodename.b, keep_me, brtnode->height); if (brtnode->height==0) printf(" buf=%p mempool-base=%p", brtnode->u.l.buffer, brtnode->u.l.buffer_mempool.base); printf("\n"); } //if (modified_lsn.lsn > brtnode->lsn.lsn) brtnode->lsn=modified_lsn; - assert(brtnode->thisnodename==nodename); + assert(brtnode->thisnodename.b==nodename.b); //printf("%s:%d %p->mdict[0]=%p\n", __FILE__, __LINE__, brtnode, brtnode->mdicts[0]); if (write_me) { toku_serialize_brtnode_to(toku_cachefile_fd(cachefile), brtnode->thisnodename, brtnode); @@ -184,9 +183,11 @@ void toku_brtnode_flush_callback (CACHEFILE cachefile, DISKOFF nodename, void *b //printf("%s:%d n_items_malloced=%lld\n", __FILE__, __LINE__, n_items_malloced); } -int toku_brtnode_fetch_callback (CACHEFILE cachefile, DISKOFF nodename, u_int32_t fullhash, void **brtnode_pv, long *sizep, void*UU(extraargs), LSN *written_lsn) { +int toku_brtnode_fetch_callback (CACHEFILE cachefile, BLOCKNUM nodename, u_int32_t fullhash, void **brtnode_pv, long *sizep, void*extraargs, LSN *written_lsn) { + assert(extraargs); + BRT brt = extraargs; BRTNODE *result=(BRTNODE*)brtnode_pv; - int r = toku_deserialize_brtnode_from(toku_cachefile_fd(cachefile), nodename, fullhash, result); + int r = toku_deserialize_brtnode_from(toku_cachefile_fd(cachefile), nodename, fullhash, result, brt->nodesize); if (r == 0) { *sizep = brtnode_memory_size(*result); *written_lsn = (*result)->disk_lsn; @@ -211,27 +212,28 @@ void toku_brtheader_free (struct brt_header *h) { toku_free(h); } -void toku_brtheader_flush_callback (CACHEFILE cachefile, DISKOFF nodename, void *header_v, long size __attribute((unused)), BOOL write_me, BOOL keep_me, LSN lsn __attribute__((__unused__)), BOOL rename_p __attribute__((__unused__))) { +void toku_brtheader_flush_callback (CACHEFILE cachefile, BLOCKNUM nodename, void *header_v, long size __attribute((unused)), BOOL write_me, BOOL keep_me, LSN lsn __attribute__((__unused__)), BOOL rename_p __attribute__((__unused__))) { struct brt_header *h = header_v; - assert(nodename==0); + assert(nodename.b==0); assert(!h->dirty); // shouldn't be dirty once it is unpinned. if (write_me) { toku_serialize_brt_header_to(toku_cachefile_fd(cachefile), h); - toku_serialize_fifo_at(toku_cachefile_fd(cachefile), h->unused_memory, h->fifo); + toku_serialize_fifo_at(toku_cachefile_fd(cachefile), h->unused_blocks.b*h->nodesize, h->fifo); } if (!keep_me) { toku_brtheader_free(h); } } -int toku_brtheader_fetch_callback (CACHEFILE cachefile, DISKOFF nodename, u_int32_t fullhash, void **headerp_v, long *sizep __attribute__((unused)), void*extraargs __attribute__((__unused__)), LSN *written_lsn) { +int toku_brtheader_fetch_callback (CACHEFILE cachefile, BLOCKNUM nodename, u_int32_t fullhash, void **headerp_v, long *sizep __attribute__((unused)), void*extraargs __attribute__((__unused__)), LSN *written_lsn) { int r; struct brt_header **h = (struct brt_header **)headerp_v; - assert(nodename==0); + assert(nodename.b==0); if ((r = toku_deserialize_brtheader_from(toku_cachefile_fd(cachefile), nodename, fullhash, h))) return r; - if ((r = toku_deserialize_fifo_at(toku_cachefile_fd(cachefile), (*h)->unused_memory, &(*h)->fifo))) return r; + if ((r = toku_deserialize_fifo_at(toku_cachefile_fd(cachefile), (*h)->unused_blocks.b*(*h)->nodesize, &(*h)->fifo))) return r; //printf("%s:%d fifo=%p\nn", __FILE__, __LINE__, (*h)->fifo); written_lsn->lsn = 0; // !!! WRONG. This should be stored or kept redundantly or something. + assert((*h)->free_blocks.b==-1); return 0; } @@ -239,19 +241,22 @@ int toku_read_and_pin_brt_header (CACHEFILE cf, struct brt_header **header) { void *header_p; //fprintf(stderr, "%s:%d read_and_pin_brt_header(...)\n", __FILE__, __LINE__); u_int32_t fullhash = toku_cachefile_fullhash_of_header(cf); - int r = toku_cachetable_get_and_pin(cf, 0, fullhash, &header_p, NULL, + BLOCKNUM blocknum = make_blocknum(0); + int r = toku_cachetable_get_and_pin(cf, blocknum, fullhash, &header_p, NULL, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0); if (r!=0) return r; struct brt_header *bheader = header_p; assert(bheader->fullhash==fullhash); *header = bheader; + assert((*header)->free_blocks.b==-1); return 0; } int toku_unpin_brt_header (BRT brt) { int dirty = brt->h->dirty; brt->h->dirty=0; // Unpinning it may make it go way. - int r = toku_cachetable_unpin(brt->cf, 0, brt->h->fullhash, dirty, 0); + BLOCKNUM blocknum = make_blocknum(0); + int r = toku_cachetable_unpin(brt->cf, blocknum, brt->h->fullhash, dirty, 0); brt->h=0; return r; } @@ -272,34 +277,12 @@ typedef struct kvpair { unsigned int vallen; } *KVPAIR; -/* Forgot to handle the case where there is something in the freelist. */ -static int malloc_diskblock_header_is_in_memory (DISKOFF *res, BRT brt, int size, TOKULOGGER logger) { - DISKOFF result = brt->h->unused_memory; - brt->h->unused_memory+=size; - brt->h->dirty = 1; - int r = toku_log_changeunusedmemory(logger, (LSN*)0, 0, toku_cachefile_filenum(brt->cf), result, brt->h->unused_memory); +int allocate_diskblocknumber (BLOCKNUM *res, BRT brt, TOKULOGGER logger __attribute__((__unused__))) { + assert(brt->h->free_blocks.b == -1); // no blocks in the free list + BLOCKNUM result = brt->h->unused_blocks; + brt->h->unused_blocks.b++; *res = result; - char *MALLOC_N(size, buf); - memset(buf, 0, size); - int r2 = pwrite(toku_cachefile_fd(brt->cf), buf, size, *res); - assert(r2==size); - toku_free(buf); - return r; -} - -int malloc_diskblock (DISKOFF *res, BRT brt, int size, TOKULOGGER logger) { -#if 0 - int r = read_and_pin_brt_header(brt->fd, &brt->h); - assert(r==0); - { - DISKOFF result = malloc_diskblock_header_is_in_memory(brt, size); - r = write_brt_header(brt->fd, &brt->h); - assert(r==0); - return result; - } -#else - return malloc_diskblock_header_is_in_memory(res, brt,size, logger); -#endif + return 0; } u_int32_t mp_pool_size_for_nodesize (u_int32_t nodesize) { @@ -328,14 +311,14 @@ static inline u_int32_t myrandom (void) { return rstate; } -static void initialize_brtnode (BRT t, BRTNODE n, DISKOFF nodename, int height) { +static void initialize_brtnode (BRT t, BRTNODE n, BLOCKNUM nodename, int height) { n->tag = TYP_BRTNODE; n->nodesize = t->h->nodesize; n->flags = t->flags; n->thisnodename = nodename; n->disk_lsn.lsn = 0; // a new one can always be 0. n->log_lsn = n->disk_lsn; - n->layout_version = BRT_LAYOUT_VERSION_7; + n->layout_version = BRT_LAYOUT_VERSION; n->height = height; n->rand4fingerprint = random(); n->local_fingerprint = 0; @@ -369,12 +352,11 @@ static void initialize_brtnode (BRT t, BRTNODE n, DISKOFF nodename, int height) int toku_create_new_brtnode (BRT t, BRTNODE *result, int height, TOKULOGGER logger) { TAGMALLOC(BRTNODE, n); int r; - DISKOFF name; - r = malloc_diskblock(&name, t, t->h->nodesize, logger); + BLOCKNUM name; + r = allocate_diskblocknumber (&name, t, logger); assert(r==0); assert(n); assert(t->h->nodesize>0); - //printf("%s:%d malloced %lld (and malloc again=%lld)\n", __FILE__, __LINE__, name, malloc_diskblock(t, t->nodesize)); n->ever_been_written = 0; initialize_brtnode(t, n, name, height); *result = n; @@ -572,7 +554,7 @@ static int log_and_save_brtenq(TOKULOGGER logger, BRT t, BRTNODE node, int child u_int32_t old_fingerprint = *fingerprint; u_int32_t fdiff=node->rand4fingerprint*toku_calc_fingerprint_cmd(type, xid, key, keylen, data, datalen); u_int32_t new_fingerprint = old_fingerprint + fdiff; - //printf("%s:%d node=%lld fingerprint old=%08x new=%08x diff=%08x xid=%lld\n", __FILE__, __LINE__, (long long)node->thisnodename, old_fingerprint, new_fingerprint, fdiff, (long long)xid); + //printf("%s:%d node=%lld fingerprint old=%08x new=%08x diff=%08x xid=%lld\n", __FILE__, __LINE__, node->thisnodename, old_fingerprint, new_fingerprint, fdiff, (long long)xid); *fingerprint = new_fingerprint; if (t->txn_that_created != xid) { int r = toku_log_brtenq(logger, &node->log_lsn, 0, toku_cachefile_filenum(t->cf), node->thisnodename, childnum, xid, type, keybs, databs); @@ -616,14 +598,14 @@ static int brt_nonleaf_split (BRT t, BRTNODE node, BRTNODE *nodea, BRTNODE *node int targchild = i-n_children_in_a; FIFO from_htab = BNC_BUFFER(node,i); FIFO to_htab = BNC_BUFFER(B, targchild); - DISKOFF thischilddiskoff = BNC_DISKOFF(node, i); + BLOCKNUM thischildblocknum = BNC_BLOCKNUM(node, i); - BNC_DISKOFF(B, targchild) = thischilddiskoff; + BNC_BLOCKNUM(B, targchild) = thischildblocknum; BNC_HAVE_FULLHASH(B,targchild) = BNC_HAVE_FULLHASH(node,i); BNC_FULLHASH(B,targchild) = BNC_FULLHASH(node, i); - int r = toku_log_addchild(logger, (LSN*)0, 0, fnum, B->thisnodename, targchild, thischilddiskoff, BNC_SUBTREE_FINGERPRINT(node, i)); + int r = toku_log_addchild(logger, (LSN*)0, 0, fnum, B->thisnodename, targchild, thischildblocknum, BNC_SUBTREE_FINGERPRINT(node, i)); if (r!=0) return r; while (1) { @@ -662,7 +644,7 @@ static int brt_nonleaf_split (BRT t, BRTNODE node, BRTNODE *nodea, BRTNODE *node BYTESTRING bs = { .len = kv_pair_keylen(node->u.n.childkeys[i-1]), .data = kv_pair_key(node->u.n.childkeys[i-1]) }; assert(i>0); - r = toku_log_delchild(logger, (LSN*)0, 0, fnum, node->thisnodename, n_children_in_a, thischilddiskoff, BNC_SUBTREE_FINGERPRINT(node, i), bs); + r = toku_log_delchild(logger, (LSN*)0, 0, fnum, node->thisnodename, n_children_in_a, thischildblocknum, BNC_SUBTREE_FINGERPRINT(node, i), bs); if (r!=0) return r; if (i>n_children_in_a) { r = toku_log_setpivot(logger, (LSN*)0, 0, fnum, B->thisnodename, targchild-1, bs); @@ -673,7 +655,7 @@ static int brt_nonleaf_split (BRT t, BRTNODE node, BRTNODE *nodea, BRTNODE *node node->u.n.childkeys[i-1] = 0; } } - BNC_DISKOFF(node, i) = 0; + BNC_BLOCKNUM(node, i) = make_blocknum(0); BNC_HAVE_FULLHASH(node, i) = FALSE; BNC_SUBTREE_FINGERPRINT(B, targchild) = BNC_SUBTREE_FINGERPRINT(node, i); @@ -895,8 +877,8 @@ static int handle_split_of_child (BRT t, BRTNODE node, int childnum, r = toku_log_addchild(logger, (LSN*)0, 0, toku_cachefile_filenum(t->cf), node->thisnodename, childnum+1, childb->thisnodename, 0); node->u.n.n_children++; - assert(BNC_DISKOFF(node, childnum)==childa->thisnodename); // use the same child - BNC_DISKOFF(node, childnum+1) = childb->thisnodename; + assert(BNC_BLOCKNUM(node, childnum).b==childa->thisnodename.b); // use the same child + BNC_BLOCKNUM(node, childnum+1) = childb->thisnodename; BNC_HAVE_FULLHASH(node, childnum+1) = TRUE; BNC_FULLHASH(node, childnum+1) = childb->fullhash; // BNC_SUBTREE_FINGERPRINT(node, childnum)=0; // leave the subtreefingerprint alone for the child, so we can log the change @@ -1036,8 +1018,8 @@ static int handle_split_of_child (BRT t, BRTNODE node, int childnum, assert((*nodeb)->height>0); assert((*nodea)->u.n.n_children>0); assert((*nodeb)->u.n.n_children>0); - assert(BNC_DISKOFF(*nodea, (*nodea)->u.n.n_children-1)!=0); - assert(BNC_DISKOFF(*nodeb, (*nodeb)->u.n.n_children-1)!=0); + assert(BNC_BLOCKNUM(*nodea, (*nodea)->u.n.n_children-1).b!=0); + assert(BNC_BLOCKNUM(*nodeb, (*nodeb)->u.n.n_children-1).b!=0); assert(toku_serialize_brtnode_size(*nodea)<=(*nodea)->nodesize); assert(toku_serialize_brtnode_size(*nodeb)<=(*nodeb)->nodesize); //verify_local_fingerprint_nonleaf(*nodea); @@ -1059,12 +1041,12 @@ static u_int32_t compute_child_fullhash (CACHEFILE cf, BRTNODE node, int childnu switch (BNC_HAVE_FULLHASH(node, childnum)) { case TRUE: { - assert(BNC_FULLHASH(node, childnum)==toku_cachetable_hash(cf, BNC_DISKOFF(node, childnum))); + assert(BNC_FULLHASH(node, childnum)==toku_cachetable_hash(cf, BNC_BLOCKNUM(node, childnum))); return BNC_FULLHASH(node, childnum); } case FALSE: { - u_int32_t child_fullhash = toku_cachetable_hash(cf, BNC_DISKOFF(node, childnum)); + u_int32_t child_fullhash = toku_cachetable_hash(cf, BNC_BLOCKNUM(node, childnum)); BNC_HAVE_FULLHASH(node, childnum) = TRUE; BNC_FULLHASH(node, childnum) = child_fullhash; return child_fullhash; @@ -1082,19 +1064,19 @@ static int push_some_brt_cmds_down (BRT t, BRTNODE node, int childnum, BRTNODE child; int r; assert(node->height>0); - DISKOFF targetchild = BNC_DISKOFF(node, childnum); - assert(targetchild>=0 && targetchildh->unused_memory); // This assertion could fail in a concurrent setting since another process might have bumped unused memory. + BLOCKNUM targetchild = BNC_BLOCKNUM(node, childnum); + assert(targetchild.b>=0 && targetchild.bh->unused_blocks.b); // This assertion could fail in a concurrent setting since another process might have bumped unused memory. u_int32_t childfullhash = compute_child_fullhash(t->cf, node, childnum); r = toku_cachetable_get_and_pin(t->cf, targetchild, childfullhash, &childnode_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, t); if (r!=0) return r; //printf("%s:%d pin %p\n", __FILE__, __LINE__, childnode_v); child=childnode_v; - assert(child->thisnodename!=0); + assert(child->thisnodename.b!=0); //verify_local_fingerprint_nonleaf(child); VERIFY_NODE(child); //printf("%s:%d height=%d n_bytes_in_buffer = {%d, %d, %d, ...}\n", __FILE__, __LINE__, child->height, child->n_bytes_in_buffer[0], child->n_bytes_in_buffer[1], child->n_bytes_in_buffer[2]); - if (child->height>0 && child->u.n.n_children>0) assert(BNC_DISKOFF(child, child->u.n.n_children-1)!=0); + if (child->height>0 && child->u.n.n_children>0) assert(BNC_BLOCKNUM(child, child->u.n.n_children-1).b!=0); if (0) { static int count=0; @@ -1168,7 +1150,7 @@ static int brtnode_maybe_push_down(BRT t, BRTNODE node, int *did_split, BRTNODE * But if the child pushes something to its child and our buffer has gotten small enough, then we stop pushing. */ int childnum; find_heaviest_child(node, &childnum); - assert(BNC_DISKOFF(node, childnum)!=0); + assert(BNC_BLOCKNUM(node, childnum).b!=0); int r = push_some_brt_cmds_down(t, node, childnum, did_split, nodea, nodeb, splitk, logger); if (r!=0) return r; assert(*did_split==0 || *did_split==1); @@ -1177,8 +1159,8 @@ static int brtnode_maybe_push_down(BRT t, BRTNODE node, int *did_split, BRTNODE assert(toku_serialize_brtnode_size(*nodeb)<=(*nodeb)->nodesize); assert((*nodea)->u.n.n_children>0); assert((*nodeb)->u.n.n_children>0); - assert(BNC_DISKOFF(*nodea, (*nodea)->u.n.n_children-1)!=0); - assert(BNC_DISKOFF(*nodeb, (*nodeb)->u.n.n_children-1)!=0); + assert(BNC_BLOCKNUM(*nodea, (*nodea)->u.n.n_children-1).b!=0); + assert(BNC_BLOCKNUM(*nodeb, (*nodeb)->u.n.n_children-1).b!=0); //verify_local_fingerprint_nonleaf(*nodea); //verify_local_fingerprint_nonleaf(*nodeb); } else { @@ -1747,12 +1729,12 @@ static int brt_nonleaf_put_cmd_child_node (BRT t, BRTNODE node, BRT_CMD cmd, *did_split = 0; - DISKOFF childdiskoff=BNC_DISKOFF(node, childnum); + BLOCKNUM childblocknum=BNC_BLOCKNUM(node, childnum); u_int32_t fullhash = compute_child_fullhash(t->cf, node, childnum); if (maybe) - r = toku_cachetable_maybe_get_and_pin(t->cf, childdiskoff, fullhash, &child_v); + r = toku_cachetable_maybe_get_and_pin(t->cf, childblocknum, fullhash, &child_v); else - r = toku_cachetable_get_and_pin(t->cf, childdiskoff, fullhash, &child_v, NULL, + r = toku_cachetable_get_and_pin(t->cf, childblocknum, fullhash, &child_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, t); if (r != 0) return r; @@ -1846,8 +1828,8 @@ static int brt_nonleaf_cmd_once (BRT t, BRTNODE node, BRT_CMD cmd, assert(toku_serialize_brtnode_size(*nodeb)<=(*nodeb)->nodesize); assert((*nodea)->u.n.n_children>0); assert((*nodeb)->u.n.n_children>0); - assert(BNC_DISKOFF(*nodea, (*nodea)->u.n.n_children-1)!=0); - assert(BNC_DISKOFF(*nodeb, (*nodeb)->u.n.n_children-1)!=0); + assert(BNC_BLOCKNUM(*nodea, (*nodea)->u.n.n_children-1).b!=0); + assert(BNC_BLOCKNUM(*nodeb, (*nodeb)->u.n.n_children-1).b!=0); } else { assert(toku_serialize_brtnode_size(node)<=node->nodesize); } @@ -1910,8 +1892,8 @@ static int brt_nonleaf_cmd_many (BRT t, BRTNODE node, BRT_CMD cmd, assert(toku_serialize_brtnode_size(*nodeb)<=(*nodeb)->nodesize); assert((*nodea)->u.n.n_children>0); assert((*nodeb)->u.n.n_children>0); - assert(BNC_DISKOFF(*nodea,(*nodea)->u.n.n_children-1)!=0); - assert(BNC_DISKOFF(*nodeb,(*nodeb)->u.n.n_children-1)!=0); + assert(BNC_BLOCKNUM(*nodea,(*nodea)->u.n.n_children-1).b!=0); + assert(BNC_BLOCKNUM(*nodeb,(*nodeb)->u.n.n_children-1).b!=0); } else { assert(toku_serialize_brtnode_size(node)<=node->nodesize); } @@ -2009,24 +1991,22 @@ int toku_brt_create_cachetable(CACHETABLE *ct, long cachesize, LSN initial_lsn, return toku_create_cachetable(ct, cachesize, initial_lsn, logger); } -static int setup_initial_brt_root_node (BRT t, DISKOFF offset, TOKULOGGER logger) { +static int setup_initial_brt_root_node (BRT t, BLOCKNUM blocknum, TOKULOGGER logger) { int r; TAGMALLOC(BRTNODE, node); assert(node); node->ever_been_written = 0; //printf("%s:%d\n", __FILE__, __LINE__); - initialize_brtnode(t, node, - offset, /* the location is one nodesize offset from 0. */ - 0); + initialize_brtnode(t, node, blocknum, 0); // node->brt = t; if (0) { printf("%s:%d for tree %p node %p mdict_create--> %p\n", __FILE__, __LINE__, t, node, node->u.l.buffer); - printf("%s:%d put root at %lld\n", __FILE__, __LINE__, offset); + printf("%s:%d put root at %" PRId64 "\n", __FILE__, __LINE__, blocknum.b); } //printf("%s:%d putting %p (%lld)\n", __FILE__, __LINE__, node, node->thisnodename); - u_int32_t fullhash = toku_cachetable_hash(t->cf, offset); + u_int32_t fullhash = toku_cachetable_hash(t->cf, blocknum); node->fullhash = fullhash; - r=toku_cachetable_put(t->cf, offset, fullhash, + r=toku_cachetable_put(t->cf, blocknum, fullhash, node, brtnode_memory_size(node), toku_brtnode_flush_callback, toku_brtnode_fetch_callback, t); if (r!=0) { @@ -2034,7 +2014,7 @@ static int setup_initial_brt_root_node (BRT t, DISKOFF offset, TOKULOGGER logger return r; } // verify_local_fingerprint_nonleaf(node); - toku_log_newbrtnode(logger, &node->log_lsn, 0, toku_cachefile_filenum(t->cf), offset, 0, t->h->nodesize, (t->flags&TOKU_DB_DUPSORT)!=0, node->rand4fingerprint); + toku_log_newbrtnode(logger, &node->log_lsn, 0, toku_cachefile_filenum(t->cf), blocknum, 0, t->h->nodesize, (t->flags&TOKU_DB_DUPSORT)!=0, node->rand4fingerprint); r = toku_unpin_brtnode(t, node); if (r!=0) { toku_free(node); @@ -2114,7 +2094,7 @@ static void compute_and_fill_remembered_hash (BRT brt, int rootnum) { static u_int32_t get_roothash (BRT brt, int rootnum) { struct remembered_hash *rh = &brt->h->root_hashes[rootnum]; - CACHEKEY root = brt->h->roots[rootnum]; + BLOCKNUM root = brt->h->roots[rootnum]; // compare cf first, since cf is NULL for invalid entries. assert(rh); //printf("v=%d\n", rh->valid); @@ -2122,7 +2102,7 @@ static u_int32_t get_roothash (BRT brt, int rootnum) { //printf("f=%d\n", rh->fnum.fileid); //printf("cf=%d\n", toku_cachefile_filenum(brt->cf).fileid); if (rh->fnum.fileid == toku_cachefile_filenum(brt->cf).fileid) - if (rh->root == root) + if (rh->root.b == root.b) return rh->fullhash; } compute_and_fill_remembered_hash(brt, rootnum); @@ -2159,6 +2139,7 @@ static int brt_open_file(BRT brt, const char *fname, const char *fname_in_env, i // allocate and initialize a brt header. static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) { int r; + BLOCKNUM root = make_blocknum(1); assert(t->h == 0); if ((MALLOC(t->h))==0) { @@ -2172,8 +2153,8 @@ static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) { if ((MALLOC_N(1, t->h->flags_array))==0) { r = errno; if (0) { died3: toku_free(t->h->flags_array); } goto died2; } t->h->flags_array[0] = t->flags; t->h->nodesize=t->nodesize; - t->h->freelist=-1; - t->h->unused_memory=2*t->nodesize; + t->h->free_blocks = make_blocknum(-1); + t->h->unused_blocks=make_blocknum(2); toku_fifo_create(&t->h->fifo); t->root_put_counter = global_root_put_counter++; if (dbname) { @@ -2182,12 +2163,12 @@ static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) { if ((MALLOC_N(1, t->h->roots))==0) { assert(errno==ENOMEM); r=ENOMEM; if (0) { died5: if (dbname) toku_free(t->h->roots); } goto died4; } if ((MALLOC_N(1, t->h->root_hashes))==0) { assert(errno==ENOMEM); r=ENOMEM; if (0) { died6: if (dbname) toku_free(t->h->root_hashes); } goto died5; } if ((t->h->names[0] = toku_strdup(dbname))==0) { assert(errno==ENOMEM); r=ENOMEM; if (0) { died7: if (dbname) toku_free(t->h->names[0]); } goto died6; } - t->h->roots[0] = t->nodesize; + t->h->roots[0] = root; // Block 0 is the header. Block 1 is the root. compute_and_fill_remembered_hash(t, 0); } else { MALLOC_N(1, t->h->roots); assert(t->h->roots); MALLOC_N(1, t->h->root_hashes); assert(t->h->root_hashes); - t->h->roots[0] = t->nodesize; + t->h->roots[0] = root; compute_and_fill_remembered_hash(t, 0); t->h->n_named_roots = -1; t->h->names=0; @@ -2197,8 +2178,8 @@ static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) { LOGGEDBRTHEADER lh = {.size= toku_serialize_brt_header_size(t->h), .flags = t->flags, .nodesize = t->h->nodesize, - .freelist = t->h->freelist, - .unused_memory = t->h->unused_memory, + .free_blocks = t->h->free_blocks, + .unused_blocks = t->h->unused_blocks, .n_named_roots = t->h->n_named_roots }; if (t->h->n_named_roots>=0) { lh.u.many.names = t->h->names; @@ -2208,11 +2189,12 @@ static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) { } if ((r=toku_log_fheader(toku_txn_logger(txn), (LSN*)0, 0, toku_txn_get_txnid(txn), toku_cachefile_filenum(t->cf), lh))) { goto died7; } } - if ((r=setup_initial_brt_root_node(t, t->nodesize, toku_txn_logger(txn)))!=0) { goto died7; } + if ((r=setup_initial_brt_root_node(t, root, toku_txn_logger(txn)))!=0) { goto died7; } //printf("%s:%d putting %p (%d)\n", __FILE__, __LINE__, t->h, 0); u_int32_t fullhash = toku_cachefile_fullhash_of_header(t->cf); t->h->fullhash = fullhash; - if ((r=toku_cachetable_put(t->cf, 0, fullhash, t->h, 0, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0))) { goto died7; } + assert(t->h->free_blocks.b==-1); + if ((r=toku_cachetable_put(t->cf, header_blocknum, fullhash, t->h, 0, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0))) { goto died7; } return r; } @@ -2266,7 +2248,7 @@ int toku_brt_open(BRT t, const char *fname, const char *fname_in_env, const char //printf("%s:%d %d alloced\n", __FILE__, __LINE__, get_n_items_malloced()); toku_print_malloced_items(); if (0) { died_after_read_and_pin: - toku_cachetable_unpin(t->cf, 0, toku_cachefile_fullhash_of_header(t->cf), 0, 0); // unpin the header + toku_cachetable_unpin(t->cf, header_blocknum, toku_cachefile_fullhash_of_header(t->cf), 0, 0); // unpin the header goto died1; } if (is_create) { @@ -2304,7 +2286,7 @@ int toku_brt_open(BRT t, const char *fname, const char *fname_in_env, const char t->h->n_named_roots++; if ((t->h->names[t->h->n_named_roots-1] = toku_strdup(dbname)) == 0) { assert(errno==ENOMEM); r=ENOMEM; goto died_after_read_and_pin; } //printf("%s:%d t=%p\n", __FILE__, __LINE__, t); - r = malloc_diskblock_header_is_in_memory(&t->h->roots[t->h->n_named_roots-1], t, t->h->nodesize, toku_txn_logger(txn)); + r = allocate_diskblocknumber(&t->h->roots[t->h->n_named_roots-1], t, toku_txn_logger(txn)); if (r!=0) goto died_after_read_and_pin; t->h->dirty = 1; compute_and_fill_remembered_hash(t, t->h->n_named_roots-1); @@ -2500,8 +2482,8 @@ static int brt_init_new_root(BRT brt, BRTNODE nodea, BRTNODE nodeb, DBT splitk, int r; int new_height = nodea->height+1; int new_nodesize = brt->h->nodesize; - DISKOFF newroot_diskoff; - r=malloc_diskblock(&newroot_diskoff, brt, new_nodesize, logger); + BLOCKNUM newroot_diskoff; + r = allocate_diskblocknumber(&newroot_diskoff, brt, logger); assert(r==0); assert(newroot); newroot->ever_been_written = 0; @@ -2523,8 +2505,8 @@ static int brt_init_new_root(BRT brt, BRTNODE nodea, BRTNODE nodeb, DBT splitk, //printf("%s:%d Splitkey=%p %s\n", __FILE__, __LINE__, splitkey, splitkey); newroot->u.n.childkeys[0] = splitk.data; newroot->u.n.totalchildkeylens=splitk.size; - BNC_DISKOFF(newroot,0)=nodea->thisnodename; - BNC_DISKOFF(newroot,1)=nodeb->thisnodename; + BNC_BLOCKNUM(newroot,0)=nodea->thisnodename; + BNC_BLOCKNUM(newroot,1)=nodeb->thisnodename; BNC_HAVE_FULLHASH(newroot, 0) = FALSE; BNC_HAVE_FULLHASH(newroot, 1) = FALSE; r=toku_fifo_create(&BNC_BUFFER(newroot,0)); if (r!=0) return r; @@ -2578,7 +2560,7 @@ int toku_cachefile_root_put_cmd (CACHEFILE cf, BRT_CMD cmd, TOKULOGGER logger) { if (r!=0) return r; } h->dirty = 0; - r = toku_cachetable_unpin(cf, 0, h->fullhash, 1, 0); + r = toku_cachetable_unpin(cf, header_blocknum, h->fullhash, 1, 0); return 0; } @@ -2596,7 +2578,7 @@ static int push_something(BRT brt, BRTNODE *nodep, CACHEKEY *rootp, BRT_CMD cmd, //printf("%s:%d did_split=%d nodeb=%p nodeb->thisnodename=%lld nodeb->nodesize=%d\n", __FILE__, __LINE__, did_split, nodeb, nodeb->thisnodename, nodeb->nodesize); //printf("Did split, splitkey=%s\n", splitkey); - if (nodeb->height>0) assert(BNC_DISKOFF(nodeb,nodeb->u.n.n_children-1)!=0); + if (nodeb->height>0) assert(BNC_BLOCKNUM(nodeb,nodeb->u.n.n_children-1).b!=0); assert(nodeb->nodesize>0); r = brt_init_new_root(brt, nodea, nodeb, splitk, rootp, logger, nodep); assert(r == 0); @@ -2715,23 +2697,23 @@ int toku_brt_delete_both(BRT brt, DBT *key, DBT *val, TOKUTXN txn) { return r; } -int toku_dump_brtnode (BRT brt, DISKOFF off, int depth, bytevec lorange, ITEMLEN lolen, bytevec hirange, ITEMLEN hilen) { +int toku_dump_brtnode (BRT brt, BLOCKNUM blocknum, int depth, bytevec lorange, ITEMLEN lolen, bytevec hirange, ITEMLEN hilen) { int result=0; BRTNODE node; void *node_v; - u_int32_t fullhash = toku_cachetable_hash(brt->cf, off); - int r = toku_cachetable_get_and_pin(brt->cf, off, fullhash, + u_int32_t fullhash = toku_cachetable_hash(brt->cf, blocknum); + int r = toku_cachetable_get_and_pin(brt->cf, blocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt); assert(r==0); printf("%s:%d pin %p\n", __FILE__, __LINE__, node_v); node=node_v; assert(node->fullhash==fullhash); - result=toku_verify_brtnode(brt, off, lorange, lolen, hirange, hilen, 0); + result=toku_verify_brtnode(brt, blocknum, lorange, lolen, hirange, hilen, 0); printf("%*sNode=%p\n", depth, "", node); if (node->height>0) { - printf("%*sNode %lld nodesize=%d height=%d n_children=%d n_bytes_in_buffers=%d keyrange=%s %s\n", - depth, "", off, node->nodesize, node->height, node->u.n.n_children, node->u.n.n_bytes_in_buffers, (char*)lorange, (char*)hirange); + printf("%*sNode %"PRId64" nodesize=%d height=%d n_children=%d n_bytes_in_buffers=%d keyrange=%s %s\n", + depth, "", blocknum.b, node->nodesize, node->height, node->u.n.n_children, node->u.n.n_bytes_in_buffers, (char*)lorange, (char*)hirange); //printf("%s %s\n", lorange ? lorange : "NULL", hirange ? hirange : "NULL"); { int i; @@ -2750,7 +2732,7 @@ int toku_dump_brtnode (BRT brt, DISKOFF off, int depth, bytevec lorange, ITEMLEN if (i>0) { printf("%*spivot %d len=%d %d\n", depth+1, "", i-1, node->u.n.childkeys[i-1]->keylen, ntohl(*(int*)&node->u.n.childkeys[i-1]->key)); } - toku_dump_brtnode(brt, BNC_DISKOFF(node, i), depth+4, + toku_dump_brtnode(brt, BNC_BLOCKNUM(node, i), depth+4, (i==0) ? lorange : 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 : node->u.n.childkeys[i], @@ -2759,13 +2741,13 @@ int toku_dump_brtnode (BRT brt, DISKOFF off, int depth, bytevec lorange, ITEMLEN } } } else { - printf("%*sNode %lld nodesize=%d height=%d n_bytes_in_buffer=%d keyrange=%d %d\n", - depth, "", off, node->nodesize, node->height, node->u.l.n_bytes_in_buffer, lorange ? ntohl(*(int*)lorange) : 0, hirange ? ntohl(*(int*)hirange) : 0); + printf("%*sNode %" PRId64 " nodesize=%d height=%d n_bytes_in_buffer=%d keyrange=%d %d\n", + depth, "", blocknum.b, node->nodesize, node->height, node->u.l.n_bytes_in_buffer, lorange ? ntohl(*(int*)lorange) : 0, hirange ? ntohl(*(int*)hirange) : 0); //GPMA_ITERATE(node->u.l.buffer, idx, len, data, // printf(" (%d)%u ", len, *(int*)le_any_key(data))); printf("\n"); } - r = toku_cachetable_unpin(brt->cf, off, fullhash, 0, 0); + r = toku_cachetable_unpin(brt->cf, blocknum, fullhash, 0, 0); assert(r==0); return result; } @@ -2803,7 +2785,7 @@ static int show_brtnode_blocknumbers (BRT brt, DISKOFF off) { printf(" %lld", off/brt->h->nodesize); if (node->height>0) { for (i=0; iu.n.n_children; i++) { - if ((r=show_brtnode_blocknumbers(brt, BNC_DISKOFF(node, i)))) goto died0; + if ((r=show_brtnode_blocknumbers(brt, BNC_BLOCKNUM(node, i)))) goto died0; } } r = toku_cachetable_unpin(brt->cf, off, 0, 0); @@ -2854,9 +2836,9 @@ static int brt_search_child(BRT brt, BRTNODE node, int childnum, brt_search_t *s } void *node_v; - DISKOFF childdiskoff = BNC_DISKOFF(node,childnum); + BLOCKNUM childblocknum = BNC_BLOCKNUM(node,childnum); u_int32_t fullhash = compute_child_fullhash(brt->cf, node, childnum); - rr = toku_cachetable_get_and_pin(brt->cf, childdiskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt); + rr = toku_cachetable_get_and_pin(brt->cf, childblocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt); assert(rr == 0); for (;;) { @@ -3804,7 +3786,7 @@ static void toku_brt_keyrange_internal (BRT brt, CACHEKEY nodename, u_int32_t fu } else { // nextcomp>=0 and prevcomp<=0, so something in the subtree could match // but they are not both zero, so it's not the whole subtree, so we need to recurse - toku_brt_keyrange_internal(brt, BNC_DISKOFF(node, i), compute_child_fullhash(brt->cf, node, i), key, less, equal, greater); + toku_brt_keyrange_internal(brt, BNC_BLOCKNUM(node, i), compute_child_fullhash(brt->cf, node, i), key, less, equal, greater); } } } else { diff --git a/newbrt/brtdump.c b/newbrt/brtdump.c index 984182c030c..368bbba5cf9 100644 --- a/newbrt/brtdump.c +++ b/newbrt/brtdump.c @@ -26,30 +26,30 @@ void print_item (bytevec val, ITEMLEN len) { void dump_header (int f, struct brt_header **header) { struct brt_header *h; int r; - r = toku_deserialize_brtheader_from (f, 0, 0/*pass 0 for hash. It doesn't matter.*/, &h); assert(r==0); + r = toku_deserialize_brtheader_from (f, header_blocknum, 0/*pass 0 for hash. It doesn't matter.*/, &h); assert(r==0); printf("brtheader:\n"); if (h->layout_version==BRT_LAYOUT_VERSION_6) printf(" layout_version<=6\n"); else printf(" layout_version=%d\n", h->layout_version); printf(" dirty=%d\n", h->dirty); printf(" nodesize=%d\n", h->nodesize); - printf(" freelist=%lld\n", h->freelist); - printf(" unused_memory=%lld\n", h->unused_memory); + printf(" free_blocks=%" PRId64 "\n", h->free_blocks.b); + printf(" unused_memory=%" PRId64 "\n", h->unused_blocks.b); if (h->n_named_roots==-1) { - printf(" unnamed_root=%lld\n", h->roots[0]); + printf(" unnamed_root=%" PRId64 "\n", h->roots[0].b); printf(" flags=%d\n", h->flags_array[0]); } else { printf(" n_named_roots=%d\n", h->n_named_roots); if (h->n_named_roots>=0) { int i; for (i=0; in_named_roots; i++) { - printf(" %s -> %lld\n", h->names[i], h->roots[i]); + printf(" %s -> %" PRId64 "\n", h->names[i], h->roots[i].b); printf(" flags=%d\n", h->flags_array[i]); } } } *header = h; printf("Fifo:\n"); - r = toku_deserialize_fifo_at(f, h->unused_memory, &h->fifo); + r = toku_deserialize_fifo_at(f, h->unused_blocks.b*h->nodesize, &h->fifo); printf(" fifo has %d entries\n", toku_fifo_n_entries(h->fifo)); if (dump_data) { FIFO_ITERATE(h->fifo, key, keylen, data, datalen, type, xid, @@ -83,16 +83,16 @@ int print_le(OMTVALUE lev, u_int32_t UU(idx), void *UU(v)) { return 0; } -void dump_node (int f, DISKOFF off) { +void dump_node (int f, BLOCKNUM blocknum, int tree_node_size) { BRTNODE n; - int r = toku_deserialize_brtnode_from (f, off, 0 /*pass zero for hash, it doesn't matter*/, &n); + int r = toku_deserialize_brtnode_from (f, blocknum, 0 /*pass zero for hash, it doesn't matter*/, &n, tree_node_size); assert(r==0); assert(n!=0); printf("brtnode\n"); printf(" nodesize =%u\n", n->nodesize); printf(" sizeonddisk =%d\n", toku_serialize_brtnode_size(n)); printf(" flags =%u\n", n->flags); - printf(" thisnodename=%lld\n", n->thisnodename); + printf(" thisnodename=%" PRId64 "\n", n->thisnodename.b); printf(" disk_lsn =%" PRId64 "\n", n->disk_lsn.lsn); //printf(" log_lsn =%lld\n", n->log_lsn.lsn); // The log_lsn is a memory-only value. printf(" height =%d\n", n->height); @@ -126,7 +126,7 @@ void dump_node (int f, DISKOFF off) { } printf(" children:\n"); for (i=0; iu.n.n_children; i++) { - printf(" child %d: %lld\n", i, BNC_DISKOFF(n, i)); + printf(" child %d: %" PRId64 "\n", i, BNC_BLOCKNUM(n, i).b); printf(" buffer contains %d bytes (%d items)\n", BNC_NBYTESINBUF(n, i), toku_fifo_n_entries(BNC_BUFFER(n,i))); if (dump_data) { FIFO_ITERATE(BNC_BUFFER(n,i), key, keylen, data, datalen, typ, xid, @@ -180,9 +180,9 @@ int main (int argc, const char *argv[]) { int f = open(n, O_RDONLY); assert(f>=0); struct brt_header *h; dump_header(f, &h); - DISKOFF off; - for (off=h->nodesize; offunused_memory; off+=h->nodesize) { - dump_node(f, off); + BLOCKNUM blocknum; + for (blocknum.b=1; blocknum.bunused_blocks.b; blocknum.b++) { + dump_node(f, blocknum, h->nodesize); } toku_brtheader_free(h); toku_malloc_cleanup(); diff --git a/newbrt/brttypes.h b/newbrt/brttypes.h index cbd5c128e7a..ab79bbcede2 100644 --- a/newbrt/brttypes.h +++ b/newbrt/brttypes.h @@ -10,6 +10,7 @@ #define _FILE_OFFSET_BITS 64 #include "../include/db.h" +#include typedef struct brt *BRT; struct brt_header; @@ -21,6 +22,10 @@ typedef const void *bytevec; typedef long long DISKOFF; /* Offset in a disk. -1 is the NULL pointer. */ typedef u_int64_t TXNID; +typedef struct s_blocknum { int64_t b; } BLOCKNUM; // make a struct so that we will notice type problems. + +static inline BLOCKNUM make_blocknum(int64_t b) { BLOCKNUM result={b}; return result; } +static const BLOCKNUM header_blocknum = {0}; typedef struct { u_int32_t len; @@ -46,16 +51,16 @@ typedef struct loggedbrtheader { u_int32_t size; u_int32_t flags; u_int32_t nodesize; - DISKOFF freelist; - DISKOFF unused_memory; + BLOCKNUM free_blocks; + BLOCKNUM unused_blocks; int32_t n_named_roots; // -1 for the union below to be "one". union { struct { char **names; - DISKOFF *roots; + BLOCKNUM *roots; } many; struct { - DISKOFF root; + BLOCKNUM root; } one; } u; } LOGGEDBRTHEADER; diff --git a/newbrt/cachetable.c b/newbrt/cachetable.c index 8bdc128e3fe..cd2f1752fd7 100644 --- a/newbrt/cachetable.c +++ b/newbrt/cachetable.c @@ -2,12 +2,13 @@ #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." #include +#include +#include #include -#include #include #include #include -#include +#include #include "cachetable.h" #include "hashfun.h" @@ -17,7 +18,6 @@ #include "log_header.h" #include "threadpool.h" #include "cachetable-rwlock.h" -#include // execute the cachetable callbacks using a writer thread 0->no 1->yes #define DO_WRITER_THREAD 1 @@ -233,7 +233,7 @@ int toku_cachetable_openfd (CACHEFILE *cf, CACHETABLE t, int fd, const char *fna newcf->filenum.fileid = next_filenum_to_use.fileid++; cachefile_init_filenum(newcf, fd, fname, fileid); newcf->refcount = 1; - newcf->header_fullhash = toku_cachetable_hash(newcf, 0); + newcf->header_fullhash = toku_cachetable_hash(newcf, header_blocknum); newcf->next = t->cachefiles; t->cachefiles = newcf; *cf = newcf; @@ -340,7 +340,7 @@ int toku_cachetable_assert_all_unpinned (CACHETABLE t) { for (p=t->table[i]; p; p=p->hash_chain) { assert(ctpair_pinned(&p->rwlock)>=0); if (ctpair_pinned(&p->rwlock)) { - printf("%s:%d pinned: %lld (%p)\n", __FILE__, __LINE__, p->key, p->value); + printf("%s:%d pinned: %" PRId64 " (%p)\n", __FILE__, __LINE__, p->key.b, p->value); some_pinned=1; } } @@ -359,7 +359,7 @@ int toku_cachefile_count_pinned (CACHEFILE cf, int print_them) { for (p=t->table[i]; p; p=p->hash_chain) { assert(ctpair_pinned(&p->rwlock)>=0); if (ctpair_pinned(&p->rwlock) && (cf==0 || p->cachefile==cf)) { - if (print_them) printf("%s:%d pinned: %lld (%p)\n", __FILE__, __LINE__, p->key, p->value); + if (print_them) printf("%s:%d pinned: %"PRId64" (%p)\n", __FILE__, __LINE__, p->key.b, p->value); n_pinned++; } } @@ -386,10 +386,10 @@ static inline u_int32_t final (u_int32_t a, u_int32_t b, u_int32_t c) { return c; } -u_int32_t toku_cachetable_hash (CACHEFILE cachefile, CACHEKEY key) +u_int32_t toku_cachetable_hash (CACHEFILE cachefile, BLOCKNUM key) // Effect: Return a 32-bit hash key. The hash key shall be suitable for using with bitmasking for a table of size power-of-two. { - return final(cachefile->filenum.fileid, (u_int32_t)(key>>32), (u_int32_t)key); + return final(cachefile->filenum.fileid, (u_int32_t)(key.b>>32), (u_int32_t)key.b); } #if 0 @@ -708,7 +708,7 @@ int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, v PAIR p; for (p=ct->table[fullhash&(cachefile->cachetable->table_size-1)]; p; p=p->hash_chain) { count++; - if (p->key==key && p->cachefile==cachefile) { + if (p->key.b==key.b && p->cachefile==cachefile) { // Semantically, these two asserts are not strictly right. After all, when are two functions eq? // In practice, the functions better be the same. assert(p->flush_callback==flush_callback); @@ -742,7 +742,7 @@ int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t ful cachetable_wait_write(t); for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { count++; - if (p->key==key && p->cachefile==cachefile) { + if (p->key.b==key.b && p->cachefile==cachefile) { *value = p->value; if (sizep) *sizep = p->size; ctpair_read_lock(&p->rwlock, &t->mutex); @@ -783,7 +783,8 @@ int toku_cachetable_maybe_get_and_pin (CACHEFILE cachefile, CACHEKEY key, u_int3 cachetable_lock(t); for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { count++; - if (p->key==key && p->cachefile==cachefile && !p->writing) { + if (p->key.b==key.b && p->cachefile==cachefile && !p->writing) { + note_hash_count(count); *value = p->value; ctpair_read_lock(&p->rwlock, &t->mutex); lru_touch(t,p); @@ -809,7 +810,7 @@ int toku_cachetable_unpin(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, cachetable_lock(t); for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { count++; - if (p->key==key && p->cachefile==cachefile) { + if (p->key.b==key.b && p->cachefile==cachefile) { assert(p->rwlock.pinned>0); ctpair_read_unlock(&p->rwlock); p->dirty |= dirty; @@ -848,7 +849,7 @@ int toku_cachetable_rename (CACHEFILE cachefile, CACHEKEY oldkey, CACHEKEY newke p; ptr_to_p = &p->hash_chain, p = *ptr_to_p) { count++; - if (p->key==oldkey && p->cachefile==cachefile) { + if (p->key.b==oldkey.b && p->cachefile==cachefile) { note_hash_count(count); *ptr_to_p = p->hash_chain; p->key = newkey; @@ -1005,7 +1006,7 @@ int toku_cachetable_remove (CACHEFILE cachefile, CACHEKEY key, int write_me) { cachetable_lock(t); for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { count++; - if (p->key==key && p->cachefile==cachefile) { + if (p->key.b==key.b && p->cachefile==cachefile) { flush_and_remove(t, p, write_me); if ((4 * t->n_in_table < t->table_size) && (t->table_size>4)) cachetable_rehash(t, t->table_size/2); @@ -1156,7 +1157,7 @@ void toku_cachetable_print_state (CACHETABLE ct) { if (p != 0) { printf("t[%d]=", i); for (p=ct->table[i]; p; p=p->hash_chain) { - printf(" {%lld, %p, dirty=%d, pin=%d, size=%ld}", p->key, p->cachefile, p->dirty, p->rwlock.pinned, p->size); + printf(" {%"PRId64", %p, dirty=%d, pin=%d, size=%ld}", p->key.b, p->cachefile, p->dirty, p->rwlock.pinned, p->size); } printf("\n"); } @@ -1186,7 +1187,8 @@ int toku_cachetable_get_key_state (CACHETABLE ct, CACHEKEY key, CACHEFILE cf, vo cachetable_lock(ct); for (p = ct->table[fullhash&(ct->table_size-1)]; p; p = p->hash_chain) { count++; - if (p->key == key && p->cachefile == cf) { + if (p->key.b == key.b && p->cachefile == cf) { + note_hash_count(count); if (value_ptr) *value_ptr = p->value; if (dirty_ptr) diff --git a/newbrt/cachetable.h b/newbrt/cachetable.h index aa728d07d3d..1bcde7a38da 100644 --- a/newbrt/cachetable.h +++ b/newbrt/cachetable.h @@ -20,7 +20,7 @@ * size limit is the upper bound of the sum of size of the entries in the cache table (total number of bytes) */ -typedef long long CACHEKEY; +typedef BLOCKNUM CACHEKEY; // create a new cachetable // returns: if success, 0 is returned and result points to the new cachetable diff --git a/newbrt/log-internal.h b/newbrt/log-internal.h index eb50871954e..74ad9c8476b 100644 --- a/newbrt/log-internal.h +++ b/newbrt/log-internal.h @@ -116,6 +116,9 @@ static inline int toku_logsizeof_FILENUM (FILENUM v __attribute__((__unused__))) static inline int toku_logsizeof_DISKOFF (DISKOFF v __attribute__((__unused__))) { return 8; } +static inline int toku_logsizeof_BLOCKNUM (BLOCKNUM v __attribute__((__unused__))) { + return 8; +} static inline int toku_logsizeof_TXNID (TXNID txnid __attribute__((__unused__))) { return 8; diff --git a/newbrt/log.c b/newbrt/log.c index 752a8b7cb98..1cd133017ab 100644 --- a/newbrt/log.c +++ b/newbrt/log.c @@ -618,6 +618,10 @@ int toku_fread_DISKOFF (FILE *f, DISKOFF *diskoff, struct x1764 *checksum, u_int int r = toku_fread_u_int64_t (f, (u_int64_t*)diskoff, checksum, len); // sign conversion will be OK. return r; } +int toku_fread_BLOCKNUM (FILE *f, BLOCKNUM *blocknum, struct x1764 *checksum, u_int32_t *len) { + int r = toku_fread_u_int64_t (f, (u_int64_t*)&blocknum->b, checksum, len); // sign conversion will be OK. + return r; +} int toku_fread_TXNID (FILE *f, TXNID *txnid, struct x1764 *checksum, u_int32_t *len) { return toku_fread_u_int64_t (f, txnid, checksum, len); } @@ -644,11 +648,11 @@ int toku_fread_LOGGEDBRTHEADER (FILE *f, LOGGEDBRTHEADER *v, struct x1764 *check r = toku_fread_u_int32_t(f, &v->size, checksum, len); if (r!=0) return r; r = toku_fread_u_int32_t(f, &v->flags, checksum, len); if (r!=0) return r; r = toku_fread_u_int32_t(f, &v->nodesize, checksum, len); if (r!=0) return r; - r = toku_fread_DISKOFF (f, &v->freelist, checksum, len); if (r!=0) return r; - r = toku_fread_DISKOFF (f, &v->unused_memory, checksum, len); if (r!=0) return r; + r = toku_fread_BLOCKNUM (f, &v->free_blocks, checksum, len); if (r!=0) return r; + r = toku_fread_BLOCKNUM (f, &v->unused_blocks, checksum, len); if (r!=0) return r; r = toku_fread_int32_t (f, &v->n_named_roots, checksum, len); if (r!=0) return r; assert(v->n_named_roots==-1); - r = toku_fread_DISKOFF (f, &v->u.one.root, checksum, len); if (r!=0) return r; + r = toku_fread_BLOCKNUM (f, &v->u.one.root, checksum, len); if (r!=0) return r; return 0; } @@ -740,11 +744,19 @@ int toku_logprint_DISKOFF (FILE *outf, FILE *inf, const char *fieldname, struct fprintf(outf, " %s=%lld", fieldname, v); return 0; } +int toku_logprint_BLOCKNUM (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, u_int32_t *len, const char *format __attribute__((__unused__))) { + BLOCKNUM v; + int r = toku_fread_BLOCKNUM(inf, &v, checksum, len); + if (r!=0) return r; + fprintf(outf, " %s=%"PRId64, fieldname, v.b); + return 0; +} + int toku_logprint_LOGGEDBRTHEADER (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *checksum, u_int32_t *len, const char *format __attribute__((__unused__))) { LOGGEDBRTHEADER v; int r = toku_fread_LOGGEDBRTHEADER(inf, &v, checksum, len); if (r!=0) return r; - fprintf(outf, " %s={size=%d flags=%d nodesize=%d freelist=%lld unused_memory=%lld n_named_roots=%d", fieldname, v.size, v.flags, v.nodesize, v.freelist, v.unused_memory, v.n_named_roots); + fprintf(outf, " %s={size=%d flags=%d nodesize=%d free_blocks=%" PRId64 " unused_memory=%" PRId64 " n_named_roots=%d", fieldname, v.size, v.flags, v.nodesize, v.free_blocks.b, v.unused_blocks.b, v.n_named_roots); return 0; } diff --git a/newbrt/log.h b/newbrt/log.h index 7b47d3ad930..bb19fc3b7a5 100644 --- a/newbrt/log.h +++ b/newbrt/log.h @@ -57,6 +57,7 @@ int toku_fread_u_int32_t (FILE *f, u_int32_t *v, struct x1764 *, u_int32_t *len) int toku_fread_LSN (FILE *f, LSN *lsn, struct x1764 *, u_int32_t *len); int toku_fread_FILENUM (FILE *f, FILENUM *filenum, struct x1764 *, u_int32_t *len); int toku_fread_DISKOFF (FILE *f, DISKOFF *diskoff, struct x1764 *, u_int32_t *len); +int toku_fread_BLOCKNUM (FILE *f, BLOCKNUM *, struct x1764 *, u_int32_t *len); int toku_fread_TXNID (FILE *f, TXNID *txnid, struct x1764 *, u_int32_t *len); // fills in the bs with malloced data. int toku_fread_BYTESTRING (FILE *f, BYTESTRING *bs, struct x1764 *, u_int32_t *len); @@ -68,6 +69,7 @@ int toku_logprint_TXNID (FILE *outf, FILE *inf, const char *fieldname, int toku_logprint_BYTESTRING (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *, u_int32_t *len, const char *); int toku_logprint_FILENUM (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *, u_int32_t *len, const char *); int toku_logprint_DISKOFF (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *, u_int32_t *len, const char *); +int toku_logprint_BLOCKNUM (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *, u_int32_t *len, const char *); int toku_logprint_u_int8_t (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *, u_int32_t *len, const char *); int toku_logprint_u_int32_t (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *, u_int32_t *len, const char *); int toku_logprint_LOGGEDBRTHEADER (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *, u_int32_t *len, const char *); diff --git a/newbrt/logformat.c b/newbrt/logformat.c index 20721330918..a8c770bd30e 100644 --- a/newbrt/logformat.c +++ b/newbrt/logformat.c @@ -83,7 +83,7 @@ const struct logtype logtypes[] = { {"xbegin", 'b', FA{{"TXNID", "parenttxnid", 0},NULLFIELD}}, #if 0 {"tl_delete", 'D', FA{{"FILENUM", "filenum", 0}, // tl logentries can be used, by themselves, to rebuild the whole DB from scratch. - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"BYTESTRING", "key", 0}, {"BYTESTRING", "data", 0}, NULLFIELD}}, @@ -97,46 +97,46 @@ const struct logtype logtypes[] = { {"LOGGEDBRTHEADER", "header", 0}, NULLFIELD}}, {"newbrtnode", 'N', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"u_int32_t", "height", 0}, {"u_int32_t", "nodesize", 0}, {"u_int8_t", "is_dup_sort", 0}, {"u_int32_t", "rand4fingerprint", "%08x"}, NULLFIELD}}, {"changeunnamedroot", 'u', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "oldroot", 0}, - {"DISKOFF", "newroot", 0}, + {"BLOCKNUM", "oldroot", 0}, + {"BLOCKNUM", "newroot", 0}, NULLFIELD}}, {"changenamedroot", 'n', FA{{"FILENUM", "filenum", 0}, {"BYTESTRING", "name", 0}, - {"DISKOFF", "oldroot", 0}, - {"DISKOFF", "newroot", 0}, + {"BLOCKNUM", "oldroot", 0}, + {"BLOCKNUM", "newroot", 0}, NULLFIELD}}, {"changeunusedmemory", 'm', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "oldunused", 0}, - {"DISKOFF", "newunused", 0}, + {"BLOCKNUM", "oldunused", 0}, + {"BLOCKNUM", "newunused", 0}, NULLFIELD}}, {"addchild", 'c', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"u_int32_t", "childnum", 0}, // children scoot over - {"DISKOFF", "child", 0}, + {"BLOCKNUM", "child", 0}, {"u_int32_t", "childfingerprint", "%08x"}, NULLFIELD}}, {"delchild", 'r', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"u_int32_t", "childnum", 0}, // children scoot over - {"DISKOFF", "child", 0}, + {"BLOCKNUM", "child", 0}, {"u_int32_t", "childfingerprint", "%08x"}, {"BYTESTRING", "pivotkey", 0}, NULLFIELD}}, {"setchild", 'i', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"u_int32_t", "childnum", 0}, - {"DISKOFF", "oldchild", 0}, - {"DISKOFF", "newchild", 0}, + {"BLOCKNUM", "oldchild", 0}, + {"BLOCKNUM", "newchild", 0}, NULLFIELD}}, {"setpivot", 'k', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"u_int32_t", "childnum", 0}, {"BYTESTRING", "pivotkey", 0}, NULLFIELD}}, @@ -152,11 +152,11 @@ const struct logtype logtypes[] = { NULLFIELD}}, // Note that brtdeq and brtenq don't name the new size or fingerprint. We can calculate them properly. {"brtdeq", 'U', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"u_int32_t", "childnum", 0}, NULLFIELD}}, {"brtenq", 'Q', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"u_int32_t", "childnum", 0}, {"TXNID", "xid", 0}, {"u_int32_t", "typ", 0}, @@ -165,13 +165,13 @@ const struct logtype logtypes[] = { NULLFIELD}}, // {"insertinleaf", 'I', FA{{"TXNID", "txnid", 0}, // {"FILENUM", "filenum", 0}, -// {"DISKOFF", "diskoff", 0}, +// {"BLOCKNUM", "blocknum", 0}, // {"u_int32_t", "pmaidx", 0}, // {"BYTESTRING", "key", 0}, // {"BYTESTRING", "data", 0}, // NULLFIELD}}, // {"replaceleafentry", 'L', FA{{"FILENUM", "filenum", 0}, -// {"DISKOFF", "diskoff", 0}, +// {"BLOCKNUM", "blocknum", 0}, // {"u_int32_t", "pmaidx", 0}, // {"LEAFENTRY", "oldleafentry", 0}, // {"LEAFENTRY", "newleafentry", 0}, @@ -185,17 +185,17 @@ const struct logtype logtypes[] = { {"deqrootentry", 'A', FA{{"FILENUM", "filenum", 0}, NULLFIELD}}, {"insertleafentry", 'I', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"u_int32_t", "idx", 0}, {"LEAFENTRY", "newleafentry", 0}, NULLFIELD}}, {"deleteleafentry", 'D', FA{{"FILENUM", "filenum", 0}, - {"DISKOFF", "diskoff", 0}, + {"BLOCKNUM", "blocknum", 0}, {"u_int32_t", "idx", 0}, NULLFIELD}}, {"leafsplit", 's', FA{{"FILENUM", "filenum", 0}, // log the creation of a new node by splitting stuff out of an old node - {"DISKOFF", "old_diskoff", 0}, - {"DISKOFF", "new_diskoff", 0}, + {"BLOCKNUM", "old_blocknum", 0}, + {"BLOCKNUM", "new_blocknum", 0}, {"u_int32_t", "old_n", 0}, {"u_int32_t", "split_at", 0}, {"u_int32_t", "new_nodesize", 0}, diff --git a/newbrt/rbuf.h b/newbrt/rbuf.h index b5cc939e703..7d7221fe1e3 100644 --- a/newbrt/rbuf.h +++ b/newbrt/rbuf.h @@ -56,10 +56,17 @@ static inline unsigned long long rbuf_ulonglong (struct rbuf *r) { return ((unsigned long long)(i0)<<32) | ((unsigned long long)(i1)); } +static inline signed long long rbuf_longlong (struct rbuf *r) { + return (signed long long)rbuf_ulonglong(r); +} + static inline DISKOFF rbuf_diskoff (struct rbuf *r) { - unsigned i0 = rbuf_int(r); - unsigned i1 = rbuf_int(r); - return ((unsigned long long)(i0)<<32) | ((unsigned long long)(i1)); + return rbuf_ulonglong(r); +} + +static inline BLOCKNUM rbuf_blocknum (struct rbuf *r) { + BLOCKNUM result = make_blocknum(rbuf_longlong(r)); + return result; } static inline void rbuf_TXNID (struct rbuf *r, TXNID *txnid) { diff --git a/newbrt/recover.c b/newbrt/recover.c index 8c7dd370207..d701c8b2161 100644 --- a/newbrt/recover.c +++ b/newbrt/recover.c @@ -136,8 +136,8 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,L h->dirty=0; h->flags_array[0] = header.flags; h->nodesize = header.nodesize; - h->freelist = header.freelist; - h->unused_memory = header.unused_memory; + h->free_blocks = header.free_blocks; + h->unused_blocks = header.unused_blocks; h->n_named_roots = header.n_named_roots; r=toku_fifo_create(&h->fifo); assert(r==0); @@ -149,9 +149,9 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,L } else { assert(0); } - u_int32_t fullhash = toku_cachetable_hash(pair->cf, 0); + u_int32_t fullhash = toku_cachetable_hash(pair->cf, header_blocknum); h->fullhash = fullhash; - toku_cachetable_put(pair->cf, 0, fullhash, h, 0, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0); + toku_cachetable_put(pair->cf, header_blocknum, fullhash, h, 0, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0); if (pair->brt) { toku_free(pair->brt->h); } else { @@ -172,17 +172,17 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,L assert(r==0); } -void toku_recover_newbrtnode (LSN lsn, FILENUM filenum,DISKOFF diskoff,u_int32_t height,u_int32_t nodesize,u_int8_t is_dup_sort,u_int32_t rand4fingerprint) { +void toku_recover_newbrtnode (LSN lsn, FILENUM filenum, BLOCKNUM blocknum,u_int32_t height,u_int32_t nodesize,u_int8_t is_dup_sort,u_int32_t rand4fingerprint) { int r; struct cf_pair *pair = NULL; r = find_cachefile(filenum, &pair); assert(r==0); TAGMALLOC(BRTNODE, n); n->nodesize = nodesize; - n->thisnodename = diskoff; + n->thisnodename = blocknum; n->log_lsn = n->disk_lsn = lsn; //printf("%s:%d %p->disk_lsn=%"PRId64"\n", __FILE__, __LINE__, n, n->disk_lsn.lsn); - n->layout_version = BRT_LAYOUT_VERSION_7; + n->layout_version = BRT_LAYOUT_VERSION; n->height = height; n->rand4fingerprint = rand4fingerprint; n->flags = is_dup_sort ? TOKU_DB_DUPSORT : 0; // Don't have TOKU_DB_DUP ??? @@ -207,25 +207,25 @@ void toku_recover_newbrtnode (LSN lsn, FILENUM filenum,DISKOFF diskoff,u_int32_t MALLOC_N(2,n->u.n.childkeys); } // Now put it in the cachetable - u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); + u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum); n->fullhash = fullhash; - toku_cachetable_put(pair->cf, diskoff, fullhash, n, toku_serialize_brtnode_size(n), toku_brtnode_flush_callback, toku_brtnode_fetch_callback, 0); + toku_cachetable_put(pair->cf, blocknum, fullhash, n, toku_serialize_brtnode_size(n), toku_brtnode_flush_callback, toku_brtnode_fetch_callback, 0); VERIFY_COUNTS(n); n->log_lsn = lsn; - r = toku_cachetable_unpin(pair->cf, diskoff, fullhash, 1, toku_serialize_brtnode_size(n)); + r = toku_cachetable_unpin(pair->cf, blocknum, fullhash, 1, toku_serialize_brtnode_size(n)); assert(r==0); } -static void recover_setup_node (FILENUM filenum, DISKOFF diskoff, CACHEFILE *cf, BRTNODE *resultnode) { +static void recover_setup_node (FILENUM filenum, BLOCKNUM blocknum, CACHEFILE *cf, BRTNODE *resultnode) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); assert(r==0); assert(pair->brt); void *node_v; - u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); - r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, + u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum); + r = toku_cachetable_get_and_pin(pair->cf, blocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); assert(r==0); BRTNODE node = node_v; @@ -239,8 +239,8 @@ static void toku_recover_deqrootentry (LSN lsn __attribute__((__unused__)), FILE int r = find_cachefile(filenum, &pair); assert(r==0); void *h_v; - u_int32_t fullhash = toku_cachetable_hash(pair->cf, 0); - r = toku_cachetable_get_and_pin(pair->cf, 0, fullhash, + u_int32_t fullhash = toku_cachetable_hash(pair->cf, header_blocknum); + r = toku_cachetable_get_and_pin(pair->cf, header_blocknum, fullhash, &h_v, NULL, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0); assert(r==0); struct brt_header *h=h_v; @@ -252,7 +252,7 @@ static void toku_recover_deqrootentry (LSN lsn __attribute__((__unused__)), FILE assert(r==0); r = toku_fifo_deq(h->fifo); assert(r==0); - r = toku_cachetable_unpin(pair->cf, 0, fullhash, 1, 0); + r = toku_cachetable_unpin(pair->cf, header_blocknum, fullhash, 1, 0); assert(r==0); } @@ -261,23 +261,23 @@ void toku_recover_enqrootentry (LSN lsn __attribute__((__unused__)), FILENUM fil int r = find_cachefile(filenum, &pair); assert(r==0); void *h_v; - u_int32_t fullhash = toku_cachetable_hash(pair->cf, 0); - r = toku_cachetable_get_and_pin(pair->cf, 0, fullhash, &h_v, NULL, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0); + u_int32_t fullhash = toku_cachetable_hash(pair->cf, header_blocknum); + r = toku_cachetable_get_and_pin(pair->cf, header_blocknum, fullhash, &h_v, NULL, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0); assert(r==0); struct brt_header *h=h_v; r = toku_fifo_enq(h->fifo, key.data, key.len, val.data, val.len, typ, xid); assert(r==0); - r = toku_cachetable_unpin(pair->cf, 0, fullhash, 1, 0); + r = toku_cachetable_unpin(pair->cf, header_blocknum, fullhash, 1, 0); assert(r==0); toku_free(key.data); toku_free(val.data); } -void toku_recover_brtdeq (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t childnum) { +void toku_recover_brtdeq (LSN lsn, FILENUM filenum, BLOCKNUM blocknum, u_int32_t childnum) { CACHEFILE cf; BRTNODE node; int r; - recover_setup_node(filenum, diskoff, &cf, &node); + recover_setup_node(filenum, blocknum, &cf, &node); assert(node->height>0); //printf("deq: %lld expected_old_fingerprint=%08x actual=%08x new=%08x\n", diskoff, oldfingerprint, node->local_fingerprint, newfingerprint); bytevec actual_key=0, actual_data=0; @@ -293,23 +293,23 @@ void toku_recover_brtdeq (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t c node->u.n.n_bytes_in_buffers -= sizediff; BNC_NBYTESINBUF(node, childnum) -= sizediff; r = toku_fifo_deq(BNC_BUFFER(node, childnum)); // don't deq till were' done looking at the data. - r = toku_cachetable_unpin(cf, diskoff, node->fullhash, 1, toku_serialize_brtnode_size(node)); + r = toku_cachetable_unpin(cf, blocknum, node->fullhash, 1, toku_serialize_brtnode_size(node)); assert(r==0); } -void toku_recover_brtenq (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t childnum, TXNID xid, u_int32_t typ, BYTESTRING key, BYTESTRING data) { +void toku_recover_brtenq (LSN lsn, FILENUM filenum, BLOCKNUM blocknum, u_int32_t childnum, TXNID xid, u_int32_t typ, BYTESTRING key, BYTESTRING data) { CACHEFILE cf; BRTNODE node; int r; - recover_setup_node(filenum, diskoff, &cf, &node); + recover_setup_node(filenum, blocknum, &cf, &node); assert(node->height>0); - //printf("enq: %lld expected_old_fingerprint=%08x actual=%08x new=%08x\n", diskoff, oldfingerprint, node->local_fingerprint, newfingerprint); + //printf("enq: %lld expected_old_fingerprint=%08x actual=%08x new=%08x\n", blocknum, oldfingerprint, node->local_fingerprint, newfingerprint); r = toku_fifo_enq(BNC_BUFFER(node, childnum), key.data, key.len, data.data, data.len, typ, xid); assert(r==0); node->local_fingerprint += node->rand4fingerprint * toku_calc_fingerprint_cmd(typ, xid, key.data, key.len, data.data, data.len); node->log_lsn = lsn; u_int32_t sizediff = key.len + data.len + KEY_VALUE_OVERHEAD + BRT_CMD_OVERHEAD; - r = toku_cachetable_unpin(cf, diskoff, node->fullhash, 1, toku_serialize_brtnode_size(node)); + r = toku_cachetable_unpin(cf, blocknum, node->fullhash, 1, toku_serialize_brtnode_size(node)); assert(r==0); node->u.n.n_bytes_in_buffers += sizediff; BNC_NBYTESINBUF(node, childnum) += sizediff; @@ -317,10 +317,10 @@ void toku_recover_brtenq (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t c toku_free(data.data); } -void toku_recover_addchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t childnum, DISKOFF child, u_int32_t childfingerprint) { +void toku_recover_addchild (LSN lsn, FILENUM filenum, BLOCKNUM blocknum, u_int32_t childnum, BLOCKNUM child, u_int32_t childfingerprint) { CACHEFILE cf; BRTNODE node; - recover_setup_node(filenum, diskoff, &cf, &node); + recover_setup_node(filenum, blocknum, &cf, &node); assert(node->height>0); assert(childnum <= (unsigned)node->u.n.n_children); unsigned int i; @@ -335,25 +335,25 @@ void toku_recover_addchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t if (childnum>0) { node->u.n.childkeys [childnum-1] = 0; } - BNC_DISKOFF(node, childnum) = child; + BNC_BLOCKNUM(node, childnum) = child; BNC_SUBTREE_FINGERPRINT(node, childnum) = childfingerprint; BNC_SUBTREE_LEAFENTRY_ESTIMATE(node, childnum) = 0; int r= toku_fifo_create(&BNC_BUFFER(node, childnum)); assert(r==0); BNC_NBYTESINBUF(node, childnum) = 0; node->u.n.n_children++; node->log_lsn = lsn; - r = toku_cachetable_unpin(cf, diskoff, node->fullhash, 1, toku_serialize_brtnode_size(node)); + r = toku_cachetable_unpin(cf, blocknum, node->fullhash, 1, toku_serialize_brtnode_size(node)); assert(r==0); } -void toku_recover_delchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t childnum, DISKOFF child, u_int32_t childfingerprint, BYTESTRING pivotkey) { +void toku_recover_delchild (LSN lsn, FILENUM filenum, BLOCKNUM blocknum, u_int32_t childnum, BLOCKNUM child, u_int32_t childfingerprint, BYTESTRING pivotkey) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); assert(r==0); void *node_v; assert(pair->brt); - u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); - r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); + u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum); + r = toku_cachetable_get_and_pin(pair->cf, blocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); assert(r==0); BRTNODE node = node_v; assert(node->height>0); @@ -361,7 +361,7 @@ void toku_recover_delchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t assert(childnum < (unsigned)node->u.n.n_children); assert(node->u.n.childinfos[childnum].subtree_fingerprint == childfingerprint); - assert(BNC_DISKOFF(node, childnum)==child); + assert(BNC_BLOCKNUM(node, childnum).b==child.b); assert(toku_fifo_n_entries(BNC_BUFFER(node,childnum))==0); assert(BNC_NBYTESINBUF(node,childnum)==0); assert(node->u.n.n_children>2); // Must be at least two children. @@ -378,37 +378,37 @@ void toku_recover_delchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t node->u.n.n_children--; node->log_lsn = lsn; - r = toku_cachetable_unpin(pair->cf, diskoff, node->fullhash, 1, toku_serialize_brtnode_size(node)); + r = toku_cachetable_unpin(pair->cf, blocknum, node->fullhash, 1, toku_serialize_brtnode_size(node)); assert(r==0); toku_free(pivotkey.data); } -void toku_recover_setchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t childnum, DISKOFF UU(oldchild), DISKOFF newchild) { +void toku_recover_setchild (LSN lsn, FILENUM filenum, BLOCKNUM blocknum, u_int32_t childnum, BLOCKNUM UU(oldchild), BLOCKNUM newchild) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); assert(r==0); void *node_v; assert(pair->brt); - u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); - r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); + u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum); + r = toku_cachetable_get_and_pin(pair->cf, blocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); assert(r==0); BRTNODE node = node_v; assert(node->fullhash == fullhash); assert(node->height>0); assert(childnum < (unsigned)node->u.n.n_children); - BNC_DISKOFF(node, childnum) = newchild; + BNC_BLOCKNUM(node, childnum) = newchild; node->log_lsn = lsn; - r = toku_cachetable_unpin(pair->cf, diskoff, node->fullhash, 1, toku_serialize_brtnode_size(node)); + r = toku_cachetable_unpin(pair->cf, blocknum, node->fullhash, 1, toku_serialize_brtnode_size(node)); assert(r==0); } -void toku_recover_setpivot (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t childnum, BYTESTRING pivotkey) { +void toku_recover_setpivot (LSN lsn, FILENUM filenum, BLOCKNUM blocknum, u_int32_t childnum, BYTESTRING pivotkey) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); assert(r==0); void *node_v; assert(pair->brt); - u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); - r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); + u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum); + r = toku_cachetable_get_and_pin(pair->cf, blocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); assert(r==0); BRTNODE node = node_v; assert(node->fullhash==fullhash); @@ -420,20 +420,20 @@ void toku_recover_setpivot (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t node->u.n.totalchildkeylens += toku_brt_pivot_key_len(pair->brt, node->u.n.childkeys[childnum]); node->log_lsn = lsn; - r = toku_cachetable_unpin(pair->cf, diskoff, node->fullhash, 1, toku_serialize_brtnode_size(node)); + r = toku_cachetable_unpin(pair->cf, blocknum, node->fullhash, 1, toku_serialize_brtnode_size(node)); assert(r==0); toku_free(pivotkey.data); } -void toku_recover_changechildfingerprint (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t childnum, u_int32_t UU(oldfingerprint), u_int32_t newfingerprint) { +void toku_recover_changechildfingerprint (LSN lsn, FILENUM filenum, BLOCKNUM blocknum, u_int32_t childnum, u_int32_t UU(oldfingerprint), u_int32_t newfingerprint) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); assert(r==0); void *node_v; assert(pair->brt); - u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); - r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); + u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum); + r = toku_cachetable_get_and_pin(pair->cf, blocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); assert(r==0); BRTNODE node = node_v; assert(node->fullhash == fullhash); @@ -441,7 +441,7 @@ void toku_recover_changechildfingerprint (LSN lsn, FILENUM filenum, DISKOFF disk assert((signed)childnum <= node->u.n.n_children); // we allow the childnum to be one too large. BNC_SUBTREE_FINGERPRINT(node, childnum) = newfingerprint; node->log_lsn = lsn; - r = toku_cachetable_unpin(pair->cf, diskoff, node->fullhash, 1, toku_serialize_brtnode_size(node)); + r = toku_cachetable_unpin(pair->cf, blocknum, node->fullhash, 1, toku_serialize_brtnode_size(node)); assert(r==0); } @@ -503,13 +503,13 @@ static int fill_buf (OMTVALUE lev, u_int32_t idx, void *varray) { // The memory for the new node should have already been allocated. -void toku_recover_leafsplit (LSN lsn, FILENUM filenum, DISKOFF old_diskoff, DISKOFF new_diskoff, u_int32_t old_n, u_int32_t new_n, u_int32_t new_node_size, u_int32_t new_rand4, u_int8_t is_dup_sort) { +void toku_recover_leafsplit (LSN lsn, FILENUM filenum, BLOCKNUM old_blocknum, BLOCKNUM new_blocknum, u_int32_t old_n, u_int32_t new_n, u_int32_t new_node_size, u_int32_t new_rand4, u_int8_t is_dup_sort) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); void *nodeA_v; assert(pair->brt); - u_int32_t oldn_fullhash = toku_cachetable_hash(pair->cf, old_diskoff); - r = toku_cachetable_get_and_pin(pair->cf, old_diskoff, oldn_fullhash, &nodeA_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); + u_int32_t oldn_fullhash = toku_cachetable_hash(pair->cf, old_blocknum); + r = toku_cachetable_get_and_pin(pair->cf, old_blocknum, oldn_fullhash, &nodeA_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); assert(r==0); BRTNODE oldn = nodeA_v; assert(oldn->fullhash==oldn_fullhash); @@ -517,14 +517,14 @@ void toku_recover_leafsplit (LSN lsn, FILENUM filenum, DISKOFF old_diskoff, DISK TAGMALLOC(BRTNODE, newn); assert(newn); - //printf("%s:%d leafsplit %p (%lld) %p (%lld)\n", __FILE__, __LINE__, oldn, old_diskoff, newn, new_diskoff); + //printf("%s:%d leafsplit %p (%lld) %p (%lld)\n", __FILE__, __LINE__, oldn, old_blocknum, newn, new_blocknum); - newn->fullhash = toku_cachetable_hash(pair->cf, new_diskoff); + newn->fullhash = toku_cachetable_hash(pair->cf, new_blocknum); newn->nodesize = new_node_size; - newn->thisnodename = new_diskoff; + newn->thisnodename = new_blocknum; newn->log_lsn = newn->disk_lsn = lsn; //printf("%s:%d %p->disk_lsn=%"PRId64"\n", __FILE__, __LINE__, n, n->disk_lsn.lsn); - newn->layout_version = BRT_LAYOUT_VERSION_7; + newn->layout_version = BRT_LAYOUT_VERSION; newn->height = 0; newn->rand4fingerprint = new_rand4; newn->flags = is_dup_sort ? TOKU_DB_DUPSORT : 0; // Don't have TOKU_DB_DUP ??? @@ -580,24 +580,24 @@ void toku_recover_leafsplit (LSN lsn, FILENUM filenum, DISKOFF old_diskoff, DISK toku_verify_all_in_mempool(oldn); toku_verify_counts(oldn); toku_verify_all_in_mempool(newn); toku_verify_counts(newn); - toku_cachetable_put(pair->cf, new_diskoff, newn->fullhash, + toku_cachetable_put(pair->cf, new_blocknum, newn->fullhash, newn, toku_serialize_brtnode_size(newn), toku_brtnode_flush_callback, toku_brtnode_fetch_callback, 0); newn->log_lsn = lsn; - r = toku_cachetable_unpin(pair->cf, new_diskoff, newn->fullhash, 1, toku_serialize_brtnode_size(newn)); + r = toku_cachetable_unpin(pair->cf, new_blocknum, newn->fullhash, 1, toku_serialize_brtnode_size(newn)); assert(r==0); oldn->log_lsn = lsn; - r = toku_cachetable_unpin(pair->cf, old_diskoff, oldn->fullhash, 1, toku_serialize_brtnode_size(oldn)); + r = toku_cachetable_unpin(pair->cf, old_blocknum, oldn->fullhash, 1, toku_serialize_brtnode_size(oldn)); assert(r==0); } -void toku_recover_insertleafentry (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t idx, LEAFENTRY newleafentry) { +void toku_recover_insertleafentry (LSN lsn, FILENUM filenum, BLOCKNUM blocknum, u_int32_t idx, LEAFENTRY newleafentry) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); assert(r==0); void *node_v; assert(pair->brt); - u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); - r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); + u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum); + r = toku_cachetable_get_and_pin(pair->cf, blocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); assert(r==0); BRTNODE node = node_v; assert(node->fullhash==fullhash); @@ -614,19 +614,19 @@ void toku_recover_insertleafentry (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_ node->u.l.n_bytes_in_buffer += OMT_ITEM_OVERHEAD + leafentry_disksize(newleafentry); node->local_fingerprint += node->rand4fingerprint * toku_le_crc(newleafentry); } - r = toku_cachetable_unpin(pair->cf, diskoff, node->fullhash, 1, toku_serialize_brtnode_size(node)); + r = toku_cachetable_unpin(pair->cf, blocknum, node->fullhash, 1, toku_serialize_brtnode_size(node)); assert(r==0); toku_free_LEAFENTRY(newleafentry); } -void toku_recover_deleteleafentry (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t idx) { +void toku_recover_deleteleafentry (LSN lsn, FILENUM filenum, BLOCKNUM blocknum, u_int32_t idx) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); assert(r==0); void *node_v; assert(pair->brt); - u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); - r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); + u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum); + r = toku_cachetable_get_and_pin(pair->cf, blocknum, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); assert(r==0); BRTNODE node = node_v; assert(node->fullhash==fullhash); @@ -646,11 +646,11 @@ void toku_recover_deleteleafentry (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_ r = toku_omt_delete_at(node->u.l.buffer, idx); assert(r==0); } - r = toku_cachetable_unpin(pair->cf, diskoff, node->fullhash, 1, toku_serialize_brtnode_size(node)); + r = toku_cachetable_unpin(pair->cf, blocknum, node->fullhash, 1, toku_serialize_brtnode_size(node)); assert(r==0); } -void toku_recover_changeunnamedroot (LSN UU(lsn), FILENUM filenum, DISKOFF UU(oldroot), DISKOFF newroot) { +void toku_recover_changeunnamedroot (LSN UU(lsn), FILENUM filenum, BLOCKNUM UU(oldroot), BLOCKNUM newroot) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); assert(r==0); @@ -661,16 +661,16 @@ void toku_recover_changeunnamedroot (LSN UU(lsn), FILENUM filenum, DISKOFF UU(ol pair->brt->h->root_hashes[0].valid = FALSE; r = toku_unpin_brt_header(pair->brt); } -void toku_recover_changenamedroot (LSN UU(lsn), FILENUM UU(filenum), BYTESTRING UU(name), DISKOFF UU(oldroot), DISKOFF UU(newroot)) { assert(0); } +void toku_recover_changenamedroot (LSN UU(lsn), FILENUM UU(filenum), BYTESTRING UU(name), BLOCKNUM UU(oldroot), BLOCKNUM UU(newroot)) { assert(0); } -void toku_recover_changeunusedmemory (LSN UU(lsn), FILENUM filenum, DISKOFF UU(oldunused), DISKOFF newunused) { +void toku_recover_changeunusedmemory (LSN UU(lsn), FILENUM filenum, BLOCKNUM UU(oldunused), BLOCKNUM newunused) { struct cf_pair *pair = NULL; int r = find_cachefile(filenum, &pair); assert(r==0); assert(pair->brt); r = toku_read_and_pin_brt_header(pair->cf, &pair->brt->h); assert(r==0); - pair->brt->h->unused_memory = newunused; + pair->brt->h->unused_blocks = newunused; r = toku_unpin_brt_header(pair->brt); } diff --git a/newbrt/tests/brt-serialize-test.c b/newbrt/tests/brt-serialize-test.c index a1368ccfcd7..64cb6c2e927 100644 --- a/newbrt/tests/brt-serialize-test.c +++ b/newbrt/tests/brt-serialize-test.c @@ -25,7 +25,7 @@ static void test_serialize(void) { sn.nodesize = nodesize; sn.ever_been_written = 0; sn.flags = 0x11223344; - sn.thisnodename = sn.nodesize*20; + sn.thisnodename.b = 20; sn.disk_lsn.lsn = 789; sn.log_lsn.lsn = 123456; sn.layout_version = BRT_LAYOUT_VERSION; @@ -38,8 +38,8 @@ static void test_serialize(void) { MALLOC_N(1, sn.u.n.childkeys); sn.u.n.childkeys[0] = kv_pair_malloc(hello_string, 6, 0, 0); sn.u.n.totalchildkeylens = 6; - BNC_DISKOFF(&sn, 0) = sn.nodesize*30; - BNC_DISKOFF(&sn, 1) = sn.nodesize*35; + BNC_BLOCKNUM(&sn, 0).b = 30; + BNC_BLOCKNUM(&sn, 1).b = 35; BNC_SUBTREE_FINGERPRINT(&sn, 0) = random(); BNC_SUBTREE_FINGERPRINT(&sn, 1) = random(); BNC_SUBTREE_LEAFENTRY_ESTIMATE(&sn, 0) = random() + (((long long)random())<<32); @@ -53,12 +53,13 @@ static void test_serialize(void) { BNC_NBYTESINBUF(&sn, 1) = 1*(BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+2+5); sn.u.n.n_bytes_in_buffers = 3*(BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+2+5); - toku_serialize_brtnode_to(fd, sn.nodesize*(DISKOFF)20, &sn); assert(r==0); - - r = toku_deserialize_brtnode_from(fd, nodesize*(DISKOFF)20, 0/*pass zero for hash*/, &dn); + toku_serialize_brtnode_to(fd, make_blocknum(20), &sn); assert(r==0); + + r = toku_deserialize_brtnode_from(fd, make_blocknum(20), 0/*pass zero for hash*/, &dn, nodesize); assert(r==0); - assert(dn->thisnodename==nodesize*20); + assert(dn->thisnodename.b==20); + assert(dn->disk_lsn.lsn==123456); assert(dn->layout_version ==BRT_LAYOUT_VERSION); assert(dn->height == 1); @@ -67,8 +68,8 @@ 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(BNC_DISKOFF(dn,0)==nodesize*30); - assert(BNC_DISKOFF(dn,1)==nodesize*35); + assert(BNC_BLOCKNUM(dn,0).b==30); + assert(BNC_BLOCKNUM(dn,1).b==35); { int i; for (i=0; i<2; i++) { diff --git a/newbrt/tests/cachetable-count-pinned-test.c b/newbrt/tests/cachetable-count-pinned-test.c index dac87cd0963..9c5893953d1 100644 --- a/newbrt/tests/cachetable-count-pinned-test.c +++ b/newbrt/tests/cachetable-count-pinned-test.c @@ -25,24 +25,24 @@ void cachetable_count_pinned_test(int n) { int i; for (i=1; i<=n; i++) { u_int32_t hi; - hi = toku_cachetable_hash(f1, i); - r = toku_cachetable_put(f1, i, hi, (void *)(long)i, 1, flush, fetch, 0); + hi = toku_cachetable_hash(f1, make_blocknum(i)); + r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, 1, flush, fetch, 0); assert(r == 0); assert(toku_cachefile_count_pinned(f1, 0) == i); void *v; - r = toku_cachetable_maybe_get_and_pin(f1, i, hi, &v); + r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(i), hi, &v); assert(r == 0); assert(toku_cachefile_count_pinned(f1, 0) == i); - r = toku_cachetable_unpin(f1, i, hi, CACHETABLE_CLEAN, 1); + r = toku_cachetable_unpin(f1, make_blocknum(i), hi, CACHETABLE_CLEAN, 1); assert(r == 0); assert(toku_cachefile_count_pinned(f1, 0) == i); } for (i=n; i>0; i--) { u_int32_t hi; - hi = toku_cachetable_hash(f1, i); - r = toku_cachetable_unpin(f1, i, hi, CACHETABLE_CLEAN, 1); + hi = toku_cachetable_hash(f1, make_blocknum(i)); + r = toku_cachetable_unpin(f1, make_blocknum(i), hi, CACHETABLE_CLEAN, 1); assert(r == 0); if (i-1) assert(toku_cachetable_assert_all_unpinned(ct)); assert(toku_cachefile_count_pinned(f1, 0) == i-1); diff --git a/newbrt/tests/cachetable-debug-test.c b/newbrt/tests/cachetable-debug-test.c index 167ed5e060e..1d51c9707d7 100644 --- a/newbrt/tests/cachetable-debug-test.c +++ b/newbrt/tests/cachetable-debug-test.c @@ -33,19 +33,19 @@ void cachetable_debug_test(int n) { for (i=1; i<=n; i++) { const int item_size = 1; u_int32_t hi; - hi = toku_cachetable_hash(f1, i); - r = toku_cachetable_put(f1, i, hi, (void *)(long)i, item_size, flush, fetch, 0); + hi = toku_cachetable_hash(f1, make_blocknum(i)); + r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, item_size, flush, fetch, 0); assert(r == 0); void *v; int dirty; long long pinned; long pair_size; - r = toku_cachetable_get_key_state(ct, i, f1, &v, &dirty, &pinned, &pair_size); + r = toku_cachetable_get_key_state(ct, make_blocknum(i), f1, &v, &dirty, &pinned, &pair_size); assert(r == 0); assert(v == (void *)(long)i); assert(dirty == CACHETABLE_DIRTY); assert(pinned == 1); assert(pair_size == item_size); - r = toku_cachetable_unpin(f1, i, hi, CACHETABLE_CLEAN, 1); + r = toku_cachetable_unpin(f1, make_blocknum(i), hi, CACHETABLE_CLEAN, 1); assert(r == 0); toku_cachetable_get_state(ct, &num_entries, &hash_size, &size_current, &size_limit); diff --git a/newbrt/tests/cachetable-flush-test.c b/newbrt/tests/cachetable-flush-test.c index 3550421bfe5..4839b535afb 100644 --- a/newbrt/tests/cachetable-flush-test.c +++ b/newbrt/tests/cachetable-flush-test.c @@ -31,15 +31,15 @@ void test_cachetable_flush(int n) { int i; for (i=0; i0; i--) { u_int32_t hi; - hi = toku_cachetable_hash(f1, i); - r = toku_cachetable_unpin(f1, i, hi, CACHETABLE_CLEAN, 1); + hi = toku_cachetable_hash(f1, make_blocknum(i)); + r = toku_cachetable_unpin(f1, make_blocknum(i), hi, CACHETABLE_CLEAN, 1); assert(r == 0); assert(toku_cachefile_count_pinned(f1, 0) == i-1); } assert(toku_cachefile_count_pinned(f1, 1) == 0); toku_cachetable_verify(ct); - CACHEKEY k = n+1; + CACHEKEY k = make_blocknum(n+1); r = toku_cachetable_unpin(f1, k, toku_cachetable_hash(f1, k), CACHETABLE_CLEAN, 1); assert(r != 0); diff --git a/newbrt/tests/cachetable-rename-test.c b/newbrt/tests/cachetable-rename-test.c index 58f71ee3651..0513b9ec248 100644 --- a/newbrt/tests/cachetable-rename-test.c +++ b/newbrt/tests/cachetable-rename-test.c @@ -55,10 +55,10 @@ static void r_flush (CACHEFILE f __attribute__((__unused__)), test_mutex_lock(); for (i=0; i0) { // Rename something int objnum = random()%n_keys; - CACHEKEY nkey = random(); + CACHEKEY nkey = make_blocknum(random()); test_mutex_lock(); CACHEKEY okey = keys[objnum]; test_mutex_unlock(); void *current_value; long current_size; - if (verbose) printf("Rename %llx to %llx\n", okey, nkey); + if (verbose) printf("Rename %" PRIx64 " to %" PRIx64 "\n", okey.b, nkey.b); r = toku_cachetable_get_and_pin(f, okey, toku_cachetable_hash(f, okey), ¤t_value, ¤t_size, r_flush, r_fetch, 0); if (r == -42) continue; assert(r==0); @@ -139,7 +139,7 @@ static void test_rename (void) { // get_and_pin may reorganize the keys[], so we need to find it again int j; for (j=0; j < n_keys; j++) - if (keys[j] == okey) + if (keys[j].b == okey.b) break; assert(j < n_keys); keys[j]=nkey; @@ -151,7 +151,7 @@ static void test_rename (void) { // test rename fails if old key does not exist in the cachetable CACHEKEY okey, nkey; while (1) { - okey = random(); + okey = make_blocknum(random()); void *v; r = toku_cachetable_maybe_get_and_pin(f, okey, toku_cachetable_hash(f, okey), &v); if (r != 0) @@ -159,7 +159,7 @@ static void test_rename (void) { r = toku_cachetable_unpin(f, okey, toku_cachetable_hash(f, okey), CACHETABLE_CLEAN, 1); assert(r == 0); } - nkey = random(); + nkey = make_blocknum(random()); r = toku_cachetable_rename(f, okey, nkey); assert(r != 0); diff --git a/newbrt/tests/cachetable-scan.c b/newbrt/tests/cachetable-scan.c index b0c4c25a22a..3a8c8e7d9aa 100644 --- a/newbrt/tests/cachetable-scan.c +++ b/newbrt/tests/cachetable-scan.c @@ -26,7 +26,7 @@ static void f_flush (CACHEFILE f, BOOL rename_p __attribute__((__unused__))) { assert(size==BLOCKSIZE); if (write_me) { - int r = pwrite(toku_cachefile_fd(f), value, BLOCKSIZE, key); + int r = pwrite(toku_cachefile_fd(f), value, BLOCKSIZE, key.b); assert(r==BLOCKSIZE); } if (!keep_me) { @@ -42,7 +42,7 @@ static int f_fetch (CACHEFILE f, void*extraargs __attribute__((__unused__)), LSN *modified_lsn __attribute__((__unused__))) { void *buf = malloc(BLOCKSIZE); - int r = pread(toku_cachefile_fd(f), buf, BLOCKSIZE, key); + int r = pread(toku_cachefile_fd(f), buf, BLOCKSIZE, key.b); assert(r==BLOCKSIZE); *value = buf; *sizep = BLOCKSIZE; @@ -66,7 +66,7 @@ static void writeit (void) { int i, r; for (i=0; i #include #include #include @@ -81,14 +82,14 @@ struct item { static volatile int expect_n_flushes=0; static volatile CACHEKEY flushes[100]; -static void expect1(CACHEKEY key) { +static void expect1(int64_t blocknum_n) { expect_n_flushes=1; - flushes[0]=key; - if (verbose) printf("%s:%d %lld\n", __FUNCTION__, 0, key); + flushes[0].b=blocknum_n; + //if (verbose) printf("%s:%d %lld\n", __FUNCTION__, 0, key.b); } -static void expectN(CACHEKEY key) { - if (verbose) printf("%s:%d %lld\n", __FUNCTION__, expect_n_flushes, key); - flushes[expect_n_flushes++]=key; +static void expectN(int64_t blocknum_n) { + //if (verbose) printf("%s:%d %lld\n", __FUNCTION__, expect_n_flushes, key); + flushes[expect_n_flushes++].b=blocknum_n; } static CACHEFILE expect_f; @@ -99,39 +100,39 @@ static void flush (CACHEFILE f, CACHEKEY key, void*value, long size __attribute_ if (keep_me) return; - if (verbose) printf("Flushing %lld (it=>key=%lld)\n", key, it->key); + if (verbose) printf("Flushing %" PRId64 " (it=>key=%" PRId64 ")\n", key.b, it->key.b); assert(expect_f==f); assert(strcmp(it->something,"something")==0); - assert(it->key==key); + assert(it->key.b==key.b); /* Verify that we expected the flush. */ for (i=0; ikey=key; + it->key.b=key; it->something="something"; return it; } -static CACHEKEY did_fetch=-1; +static CACHEKEY did_fetch={-1}; static int fetch (CACHEFILE f, CACHEKEY key, u_int32_t fullhash __attribute__((__unused__)), void**value, long *sizep __attribute__((__unused__)), void*extraargs, LSN *written_lsn) { - if (verbose) printf("Fetch %lld\n", key); + if (verbose) printf("Fetch %" PRId64 "\n", key.b); assert (expect_f==f); assert((long)extraargs==23); - *value = make_item(key); + *value = make_item(key.b); did_fetch=key; written_lsn->lsn = 0; return 0; @@ -158,89 +159,89 @@ static void test0 (void) { expect_f = f; expect_n_flushes=0; - u_int32_t h1 = toku_cachetable_hash(f, 1); - u_int32_t h2 = toku_cachetable_hash(f, 2); - u_int32_t h3 = toku_cachetable_hash(f, 3); - u_int32_t h4 = toku_cachetable_hash(f, 4); - u_int32_t h5 = toku_cachetable_hash(f, 5); - u_int32_t h6 = toku_cachetable_hash(f, 6); - u_int32_t h7 = toku_cachetable_hash(f, 7); - r=toku_cachetable_put(f, 1, h1, make_item(1), test_object_size, flush, fetch, t3); /* 1P */ /* this is the lru list. 1 is pinned. */ + u_int32_t h1 = toku_cachetable_hash(f, make_blocknum(1)); + u_int32_t h2 = toku_cachetable_hash(f, make_blocknum(2)); + u_int32_t h3 = toku_cachetable_hash(f, make_blocknum(3)); + u_int32_t h4 = toku_cachetable_hash(f, make_blocknum(4)); + u_int32_t h5 = toku_cachetable_hash(f, make_blocknum(5)); + u_int32_t h6 = toku_cachetable_hash(f, make_blocknum(6)); + u_int32_t h7 = toku_cachetable_hash(f, make_blocknum(7)); + r=toku_cachetable_put(f, make_blocknum(1), h1, make_item(1), test_object_size, flush, fetch, t3); /* 1P */ /* this is the lru list. 1 is pinned. */ assert(r==0); assert(expect_n_flushes==0); expect_n_flushes=0; - r=toku_cachetable_put(f, 2, h2, make_item(2), test_object_size, flush, fetch, t3); + r=toku_cachetable_put(f, make_blocknum(2), h2, make_item(2), test_object_size, flush, fetch, t3); assert(r==0); - r=toku_cachetable_unpin(f, 2, h2, CACHETABLE_DIRTY, 1); /* 2U 1P */ + r=toku_cachetable_unpin(f, make_blocknum(2), h2, CACHETABLE_DIRTY, 1); /* 2U 1P */ assert(expect_n_flushes==0); expect_n_flushes=0; - r=toku_cachetable_put(f, 3, h3, make_item(3), test_object_size, flush, fetch, t3); + r=toku_cachetable_put(f, make_blocknum(3), h3, make_item(3), test_object_size, flush, fetch, t3); assert(r==0); assert(expect_n_flushes==0); /* 3P 2U 1P */ /* 3 is most recently used (pinned), 2 is next (unpinned), 1 is least recent (pinned) */ expect_n_flushes=0; - r=toku_cachetable_put(f, 4, h4, make_item(4), test_object_size, flush, fetch, t3); + r=toku_cachetable_put(f, make_blocknum(4), h4, make_item(4), test_object_size, flush, fetch, t3); assert(r==0); assert(expect_n_flushes==0); /* 4P 3P 2U 1P */ expect_n_flushes=0; - r=toku_cachetable_put(f, 5, h5, make_item(5), test_object_size, flush, fetch, t3); + r=toku_cachetable_put(f, make_blocknum(5), h5, make_item(5), test_object_size, flush, fetch, t3); assert(r==0); - r=toku_cachetable_unpin(f, 5, h5, CACHETABLE_DIRTY, test_object_size); + r=toku_cachetable_unpin(f, make_blocknum(5), h5, CACHETABLE_DIRTY, test_object_size); assert(r==0); - r=toku_cachetable_unpin(f, 3, h3, CACHETABLE_DIRTY, test_object_size); + r=toku_cachetable_unpin(f, make_blocknum(3), h3, CACHETABLE_DIRTY, test_object_size); assert(r==0); assert(expect_n_flushes==0); /* 5U 4P 3U 2U 1P */ expect1(2); /* 2 is the oldest unpinned item. */ - r=toku_cachetable_put(f, 6, h6, make_item(6), test_object_size, flush, fetch, t3); /* 6P 5U 4P 3U 1P */ + r=toku_cachetable_put(f, make_blocknum(6), h6, make_item(6), test_object_size, flush, fetch, t3); /* 6P 5U 4P 3U 1P */ assert(r==0); while (expect_n_flushes != 0) pthread_yield(); assert(expect_n_flushes==0); expect1(3); - r=toku_cachetable_put(f, 7, h7, make_item(7), test_object_size, flush, fetch, t3); + r=toku_cachetable_put(f, make_blocknum(7), h7, make_item(7), test_object_size, flush, fetch, t3); assert(r==0); while (expect_n_flushes != 0) pthread_yield(); assert(expect_n_flushes==0); - r=toku_cachetable_unpin(f, 7, h7, CACHETABLE_DIRTY, test_object_size); /* 7U 6P 5U 4P 1P */ + r=toku_cachetable_unpin(f, make_blocknum(7), h7, CACHETABLE_DIRTY, test_object_size); /* 7U 6P 5U 4P 1P */ assert(r==0); { void *item_v=0; expect_n_flushes=0; - r=toku_cachetable_get_and_pin(f, 5, toku_cachetable_hash(f, 5), &item_v, NULL, flush, fetch, t3); /* 5P 7U 6P 4P 1P */ + r=toku_cachetable_get_and_pin(f, make_blocknum(5), toku_cachetable_hash(f, make_blocknum(5)), &item_v, NULL, flush, fetch, t3); /* 5P 7U 6P 4P 1P */ assert(r==0); - assert(((struct item *)item_v)->key==5); + assert(((struct item *)item_v)->key.b==5); assert(strcmp(((struct item *)item_v)->something,"something")==0); assert(expect_n_flushes==0); } { void *item_v=0; - r=toku_cachetable_unpin(f, 4, h4, CACHETABLE_DIRTY, test_object_size); + r=toku_cachetable_unpin(f, make_blocknum(4), h4, CACHETABLE_DIRTY, test_object_size); assert(r==0); expect1(4); - did_fetch=-1; - r=toku_cachetable_get_and_pin(f, 2, toku_cachetable_hash(f, 2), &item_v, NULL, flush, fetch, t3); /* 2p 5P 7U 6P 1P */ + did_fetch=make_blocknum(-1); + r=toku_cachetable_get_and_pin(f, make_blocknum(2), toku_cachetable_hash(f, make_blocknum(2)), &item_v, NULL, flush, fetch, t3); /* 2p 5P 7U 6P 1P */ assert(r==0); - assert(did_fetch==2); /* Expect that 2 is fetched in. */ - assert(((struct item *)item_v)->key==2); + assert(did_fetch.b==2); /* Expect that 2 is fetched in. */ + assert(((struct item *)item_v)->key.b==2); assert(strcmp(((struct item *)item_v)->something,"something")==0); while (expect_n_flushes != 0) pthread_yield(); assert(expect_n_flushes==0); } - r=toku_cachetable_unpin(f, 2, h2, CACHETABLE_DIRTY, test_object_size); + r=toku_cachetable_unpin(f, make_blocknum(2), h2, CACHETABLE_DIRTY, test_object_size); assert(r==0); - r=toku_cachetable_unpin(f, 5, h5, CACHETABLE_DIRTY, test_object_size); + r=toku_cachetable_unpin(f, make_blocknum(5), h5, CACHETABLE_DIRTY, test_object_size); assert(r==0); - r=toku_cachetable_unpin(f, 6, h6, CACHETABLE_DIRTY, test_object_size); + r=toku_cachetable_unpin(f, make_blocknum(6), h6, CACHETABLE_DIRTY, test_object_size); assert(r==0); - r=toku_cachetable_unpin(f, 1, h1, CACHETABLE_DIRTY, test_object_size); + r=toku_cachetable_unpin(f, make_blocknum(1), h1, CACHETABLE_DIRTY, test_object_size); assert(r==0); r=toku_cachetable_assert_all_unpinned(t); assert(r==0); @@ -293,26 +294,26 @@ static void test_nested_pin (void) { expect_f = f; i0=0; i1=0; - u_int32_t f1hash = toku_cachetable_hash(f, 1); - r = toku_cachetable_put(f, 1, f1hash, &i0, 1, flush_n, fetch_n, f2); + u_int32_t f1hash = toku_cachetable_hash(f, make_blocknum(1)); + r = toku_cachetable_put(f, make_blocknum(1), f1hash, &i0, 1, flush_n, fetch_n, f2); assert(r==0); - r = toku_cachetable_get_and_pin(f, 1, f1hash, &vv, NULL, flush_n, fetch_n, f2); + r = toku_cachetable_get_and_pin(f, make_blocknum(1), f1hash, &vv, NULL, flush_n, fetch_n, f2); assert(r==0); assert(vv==&i0); assert(i0==0); - r = toku_cachetable_unpin(f, 1, f1hash, 0, test_object_size); + r = toku_cachetable_unpin(f, make_blocknum(1), f1hash, 0, test_object_size); assert(r==0); - r = toku_cachetable_maybe_get_and_pin(f, 1, f1hash, &vv2); + r = toku_cachetable_maybe_get_and_pin(f, make_blocknum(1), f1hash, &vv2); assert(r==0); assert(vv2==vv); - r = toku_cachetable_unpin(f, 1, f1hash, 0, test_object_size); + r = toku_cachetable_unpin(f, make_blocknum(1), f1hash, 0, test_object_size); assert(r==0); - u_int32_t f2hash = toku_cachetable_hash(f, 2); - r = toku_cachetable_put(f, 2, f2hash, &i1, test_object_size, flush_n, fetch_n, f2); + u_int32_t f2hash = toku_cachetable_hash(f, make_blocknum(2)); + r = toku_cachetable_put(f, make_blocknum(2), f2hash, &i1, test_object_size, flush_n, fetch_n, f2); assert(r==0); // The other one is pinned, but now the cachetable fails gracefully: It allows the pin to happen - r = toku_cachetable_unpin(f, 1, f1hash, 0, test_object_size); + r = toku_cachetable_unpin(f, make_blocknum(1), f1hash, 0, test_object_size); assert(r==0); - r = toku_cachetable_unpin(f, 2, f2hash, 0, test_object_size); + r = toku_cachetable_unpin(f, make_blocknum(2), f2hash, 0, test_object_size); assert(r==0); // sleep(1); r = toku_cachefile_close(&f, 0); assert(r==0); @@ -333,7 +334,7 @@ static void null_flush (CACHEFILE cf __attribute__((__unused__)), static int add123_fetch (CACHEFILE cf, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep __attribute__((__unused__)), void*extraargs, LSN *written_lsn) { assert(fullhash==toku_cachetable_hash(cf,key)); assert((long)extraargs==123); - *value = (void*)((unsigned long)key+123L); + *value = (void*)((unsigned long)key.b+123L); written_lsn->lsn = 0; return 0; } @@ -341,7 +342,7 @@ static int add123_fetch (CACHEFILE cf, CACHEKEY key, u_int32_t fullhash, void ** static int add222_fetch (CACHEFILE cf, CACHEKEY key, u_int32_t fullhash, void **value, long *sizep __attribute__((__unused__)), void*extraargs, LSN *written_lsn) { assert(fullhash==toku_cachetable_hash(cf,key)); assert((long)extraargs==222); - *value = (void*)((unsigned long)key+222L); + *value = (void*)((unsigned long)key.b+222L); written_lsn->lsn = 0; return 0; } @@ -366,39 +367,39 @@ static void test_multi_filehandles (void) { assert(f1==f2); assert(f1!=f3); - r = toku_cachetable_put(f1, 1, toku_cachetable_hash(f1, 1), (void*)124, test_object_size, null_flush, add123_fetch, (void*)123); assert(r==0); - r = toku_cachetable_get_and_pin(f2, 1, toku_cachetable_hash(f2, 1), &v, NULL, null_flush, add123_fetch, (void*)123); assert(r==0); + r = toku_cachetable_put(f1, make_blocknum(1), toku_cachetable_hash(f1, make_blocknum(1)), (void*)124, test_object_size, null_flush, add123_fetch, (void*)123); assert(r==0); + r = toku_cachetable_get_and_pin(f2, make_blocknum(1), toku_cachetable_hash(f2, make_blocknum(1)), &v, NULL, null_flush, add123_fetch, (void*)123); assert(r==0); assert((unsigned long)v==124); - r = toku_cachetable_get_and_pin(f2, 2, toku_cachetable_hash(f2, 2), &v, NULL, null_flush, add123_fetch, (void*)123); assert(r==0); + r = toku_cachetable_get_and_pin(f2, make_blocknum(2), toku_cachetable_hash(f2, make_blocknum(2)), &v, NULL, null_flush, add123_fetch, (void*)123); assert(r==0); assert((unsigned long)v==125); - r = toku_cachetable_get_and_pin(f3, 2, toku_cachetable_hash(f3, 2), &v, NULL, null_flush, add222_fetch, (void*)222); assert(r==0); + r = toku_cachetable_get_and_pin(f3, make_blocknum(2), toku_cachetable_hash(f3, make_blocknum(2)), &v, NULL, null_flush, add222_fetch, (void*)222); assert(r==0); assert((unsigned long)v==224); - r = toku_cachetable_maybe_get_and_pin(f1, 2, toku_cachetable_hash(f1, 2), &v); assert(r==0); + r = toku_cachetable_maybe_get_and_pin(f1, make_blocknum(2), toku_cachetable_hash(f1, make_blocknum(2)), &v); assert(r==0); assert((unsigned long)v==125); - r = toku_cachetable_unpin(f1, 1, toku_cachetable_hash(f1, 1), CACHETABLE_CLEAN, 0); assert(r==0); - r = toku_cachetable_unpin(f1, 2, toku_cachetable_hash(f1, 2), CACHETABLE_CLEAN, 0); assert(r==0); + r = toku_cachetable_unpin(f1, make_blocknum(1), toku_cachetable_hash(f1, make_blocknum(1)), CACHETABLE_CLEAN, 0); assert(r==0); + r = toku_cachetable_unpin(f1, make_blocknum(2), toku_cachetable_hash(f1, make_blocknum(2)), CACHETABLE_CLEAN, 0); assert(r==0); r = toku_cachefile_close(&f1, 0); assert(r==0); - r = toku_cachetable_unpin(f2, 1, toku_cachetable_hash(f2, 1), CACHETABLE_CLEAN, 0); assert(r==0); - r = toku_cachetable_unpin(f2, 2, toku_cachetable_hash(f2, 2), CACHETABLE_CLEAN, 0); assert(r==0); + r = toku_cachetable_unpin(f2, make_blocknum(1), toku_cachetable_hash(f2, make_blocknum(1)), CACHETABLE_CLEAN, 0); assert(r==0); + r = toku_cachetable_unpin(f2, make_blocknum(2), toku_cachetable_hash(f2, make_blocknum(2)), CACHETABLE_CLEAN, 0); assert(r==0); r = toku_cachefile_close(&f2, 0); assert(r==0); - r = toku_cachetable_unpin(f3, 2, toku_cachetable_hash(f3, 2), CACHETABLE_CLEAN, 0); assert(r==0); + r = toku_cachetable_unpin(f3, make_blocknum(2), toku_cachetable_hash(f3, make_blocknum(2)), CACHETABLE_CLEAN, 0); assert(r==0); r = toku_cachefile_close(&f3, 0); assert(r==0); r = toku_cachetable_close(&t); assert(r==0); } static void test_dirty_flush(CACHEFILE f, CACHEKEY key, void *value, long size, BOOL do_write, BOOL keep, LSN modified_lsn __attribute__((__unused__)), BOOL rename_p __attribute__((__unused__))) { - if (verbose) printf("test_dirty_flush %p %lld %p %ld %d %d\n", f, key, value, size, do_write, keep); + if (verbose) printf("test_dirty_flush %p %" PRId64 " %p %ld %d %d\n", f, key.b, value, size, do_write, keep); } static int test_dirty_fetch(CACHEFILE f, CACHEKEY key, u_int32_t fullhash, void **value_ptr, long *size_ptr, void *arg, LSN *written_lsn) { *value_ptr = arg; written_lsn->lsn = 0; assert(fullhash==toku_cachetable_hash(f,key)); - if (verbose) printf("test_dirty_fetch %p %lld %p %ld %p\n", f, key, *value_ptr, *size_ptr, arg); + if (verbose) printf("test_dirty_fetch %p %" PRId64 " %p %ld %p\n", f, key.b, *value_ptr, *size_ptr, arg); return 0; } @@ -419,7 +420,7 @@ static void test_dirty() { r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, 0777); assert(r == 0); - key = 1; value = (void*)1; + key = make_blocknum(1); value = (void*)1; u_int32_t hkey = toku_cachetable_hash(f, key); r = toku_cachetable_put(f, key, hkey, value, test_object_size, test_dirty_flush, 0, 0); assert(r == 0); @@ -456,7 +457,7 @@ static void test_dirty() { assert(dirty == 1); assert(pinned == 0); - key = 2; + key = make_blocknum(2); hkey = toku_cachetable_hash(f, key); r = toku_cachetable_get_and_pin(f, key, hkey, &value, NULL, test_dirty_flush, @@ -508,7 +509,7 @@ static int test_size_debug; static CACHEKEY test_size_flush_key; static void test_size_flush_callback(CACHEFILE f, CACHEKEY key, void *value, long size, BOOL do_write, BOOL keep, LSN modified_lsn __attribute__((__unused__)), BOOL rename_p __attribute__((__unused__))) { - if (test_size_debug && verbose) printf("test_size_flush %p %lld %p %ld %d %d\n", f, key, value, size, do_write, keep); + if (test_size_debug && verbose) printf("test_size_flush %p %" PRId64 " %p %ld %d %d\n", f, key.b, value, size, do_write, keep); if (keep) { assert(do_write != 0); test_size_flush_key = key; @@ -533,7 +534,7 @@ static void test_size_resize() { r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, 0777); assert(r == 0); - CACHEKEY key = 42; + CACHEKEY key = make_blocknum(42); void *value = (void *) -42; u_int32_t hkey = toku_cachetable_hash(f, key); @@ -587,12 +588,12 @@ static void test_size_flush() { assert(r == 0); /* put 2*n keys into the table, ensure flushes occur in key order */ - test_size_flush_key = -1; + test_size_flush_key = make_blocknum(-1); int i; - CACHEKEY expect_flush_key = 0; + CACHEKEY expect_flush_key = make_blocknum(0); for (i=0; i<2*n; i++) { - CACHEKEY key = i; + CACHEKEY key = make_blocknum(i); void *value = (void *)(long)-i; // printf("test_size put %lld %p %lld\n", key, value, size); u_int32_t hkey = toku_cachetable_hash(f, key); @@ -616,10 +617,10 @@ static void test_size_flush() { assert(entry_value == value); assert(entry_size == size); - if (test_size_flush_key != -1) { - assert(test_size_flush_key == expect_flush_key); - assert(expect_flush_key == i-n); - expect_flush_key += 1; + if (test_size_flush_key.b != -1) { + assert(test_size_flush_key.b == expect_flush_key.b); + assert(expect_flush_key.b == i-n); + expect_flush_key.b += 1; } r = toku_cachetable_unpin(f, key, hkey, CACHETABLE_CLEAN, size); diff --git a/newbrt/tests/cachetable-test2.c b/newbrt/tests/cachetable-test2.c index 7c457fcdf2b..6c9755d5e7c 100644 --- a/newbrt/tests/cachetable-test2.c +++ b/newbrt/tests/cachetable-test2.c @@ -1,16 +1,17 @@ /* -*- mode: C; c-basic-offset: 4 -*- */ #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." -#include "memory.h" -#include "cachetable.h" -#include "toku_assert.h" - +#include #include #include #include #include #include +#include "memory.h" +#include "cachetable.h" +#include "toku_assert.h" + #include "test.h" // this mutex is used by some of the tests to serialize access to some @@ -51,7 +52,7 @@ static void print_ints(void) { int i; for (i=0; ilsn = 0; return 0; } @@ -162,12 +163,12 @@ static void test_chaining (void) { for (i=0; i0; i--) { u_int32_t hi; - hi = toku_cachetable_hash(f1, i); - r = toku_cachetable_unpin(f1, i, hi, CACHETABLE_CLEAN, 1); + hi = toku_cachetable_hash(f1, make_blocknum(i)); + r = toku_cachetable_unpin(f1, make_blocknum(i), hi, CACHETABLE_CLEAN, 1); assert(r == 0); assert(toku_cachefile_count_pinned(f1, 0) == i-1); } assert(toku_cachefile_count_pinned(f1, 1) == 0); toku_cachetable_verify(ct); - CACHEKEY k = n+1; + CACHEKEY k = make_blocknum(n+1); r = toku_cachetable_unpin(f1, k, toku_cachetable_hash(f1, k), CACHETABLE_CLEAN, 1); assert(r != 0); diff --git a/newbrt/tests/test-del-inorder.c b/newbrt/tests/test-del-inorder.c index afbfa7a7bbb..2d1f19d83f3 100644 --- a/newbrt/tests/test-del-inorder.c +++ b/newbrt/tests/test-del-inorder.c @@ -22,7 +22,7 @@ int fnamelen; char *fname; void doit (void) { - DISKOFF nodea,nodeb; + BLOCKNUM nodea,nodeb; u_int32_t fingerprinta=0; int r; diff --git a/newbrt/tests/test-inc-split.c b/newbrt/tests/test-inc-split.c index f29e40a6faa..c166d24969d 100644 --- a/newbrt/tests/test-inc-split.c +++ b/newbrt/tests/test-inc-split.c @@ -48,7 +48,7 @@ int fnamelen; char *fname; void doit (int ksize __attribute__((__unused__))) { - DISKOFF cnodes[BRT_FANOUT], bnode, anode; + BLOCKNUM cnodes[BRT_FANOUT], bnode, anode; u_int32_t fingerprints[BRT_FANOUT]; char *keys[BRT_FANOUT-1]; diff --git a/newbrt/wbuf.h b/newbrt/wbuf.h index 863a067aa08..a391cb1a171 100644 --- a/newbrt/wbuf.h +++ b/newbrt/wbuf.h @@ -98,6 +98,11 @@ static inline void wbuf_u_int32_t (struct wbuf *w, u_int32_t v) { static inline void wbuf_DISKOFF (struct wbuf *w, DISKOFF off) { wbuf_ulonglong(w, (u_int64_t)off); } +static inline void wbuf_BLOCKNUM (struct wbuf *w, BLOCKNUM b) { + wbuf_ulonglong(w, b.b); +} + + static inline void wbuf_TXNID (struct wbuf *w, TXNID tid) { wbuf_ulonglong(w, tid); @@ -115,15 +120,15 @@ static inline void wbuf_LOGGEDBRTHEADER (struct wbuf *w, LOGGEDBRTHEADER h) { wbuf_uint(w, h.size); wbuf_uint(w, h.flags); wbuf_uint(w, h.nodesize); - wbuf_DISKOFF(w, h.freelist); - wbuf_DISKOFF(w, h.unused_memory); + wbuf_BLOCKNUM(w, h.free_blocks); + wbuf_BLOCKNUM(w, h.unused_blocks); wbuf_int(w, h.n_named_roots); if ((signed)h.n_named_roots==-1) { - wbuf_DISKOFF(w, h.u.one.root); + wbuf_BLOCKNUM(w, h.u.one.root); } else { int i; for (i=0; i