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

Incorporate blocknum code from 1080a. Runs a little, need a big run on...

Incorporate blocknum code from 1080a.  Runs a little, need a big run on coyote.  Addresses #1000, #1080, #1131.

git-svn-id: file:///svn/tokudb.1131b+1080a@6025 c7de825b-a66e-492c-adef-691d508d4ae1
parent c8cda2fc
...@@ -39,7 +39,7 @@ enum { BUFFER_HEADER_SIZE = (4 // height// ...@@ -39,7 +39,7 @@ enum { BUFFER_HEADER_SIZE = (4 // height//
struct brtnode_nonleaf_childinfo { struct brtnode_nonleaf_childinfo {
u_int32_t subtree_fingerprint; u_int32_t subtree_fingerprint;
u_int64_t leafentry_estimate; // estimate how many leafentries are below us. 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? BOOL have_fullhash; // do we have the full hash?
u_int32_t fullhash; // the fullhash of the child u_int32_t fullhash; // the fullhash of the child
FIFO buffer; FIFO buffer;
...@@ -53,7 +53,7 @@ struct brtnode { ...@@ -53,7 +53,7 @@ struct brtnode {
unsigned int nodesize; unsigned int nodesize;
int ever_been_written; int ever_been_written;
unsigned int flags; 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. // 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 // 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. 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 { ...@@ -80,7 +80,7 @@ struct brtnode {
#define BNC_SUBTREE_FINGERPRINT(node,i) ((node)->u.n.childinfos[i].subtree_fingerprint) #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_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_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_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) #define BNC_HAVE_FULLHASH(node,i) ((node)->u.n.childinfos[i].have_fullhash)
...@@ -109,7 +109,7 @@ enum { ...@@ -109,7 +109,7 @@ enum {
struct remembered_hash { struct remembered_hash {
BOOL valid; // set to FALSE if the fullhash is invalid BOOL valid; // set to FALSE if the fullhash is invalid
FILENUM fnum; FILENUM fnum;
DISKOFF root; BLOCKNUM root;
u_int32_t fullhash; // fullhash is the hashed value of fnum and root. u_int32_t fullhash; // fullhash is the hashed value of fnum and root.
}; };
...@@ -118,15 +118,19 @@ struct brt_header { ...@@ -118,15 +118,19 @@ struct brt_header {
u_int32_t fullhash; u_int32_t fullhash;
int layout_version; int layout_version;
unsigned int nodesize; unsigned int nodesize;
DISKOFF freelist;
DISKOFF unused_memory;
int n_named_roots; /* -1 if the only one is unnamed */ int n_named_roots; /* -1 if the only one is unnamed */
char **names; // an array of names. NULL if subdatabases are not allowed. 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. 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. 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. 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 { struct brt {
...@@ -153,8 +157,8 @@ struct brt { ...@@ -153,8 +157,8 @@ struct brt {
}; };
/* serialization code */ /* serialization code */
void toku_serialize_brtnode_to(int fd, DISKOFF off, BRTNODE node); void toku_serialize_brtnode_to(int fd, BLOCKNUM, BRTNODE node);
int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t /*fullhash*/, BRTNODE *brtnode); 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? */ 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); int toku_keycompare (bytevec key1, ITEMLEN key1len, bytevec key2, ITEMLEN key2len);
...@@ -163,7 +167,7 @@ void toku_verify_counts(BRTNODE); ...@@ -163,7 +167,7 @@ void toku_verify_counts(BRTNODE);
int toku_serialize_brt_header_size (struct brt_header *h); 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 (int fd, struct brt_header *h);
int toku_serialize_brt_header_to_wbuf (struct wbuf *, 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_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); int toku_deserialize_fifo_at (int fd, off_t at, FIFO *fifo);
...@@ -219,12 +223,12 @@ int toku_unpin_brtnode (BRT brt, BRTNODE node); ...@@ -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); unsigned int toku_brtnode_which_child (BRTNODE node , DBT *k, DBT *d, BRT t);
/* Stuff for testing */ /* Stuff for testing */
int toku_testsetup_leaf(BRT brt, DISKOFF *diskoff); int toku_testsetup_leaf(BRT brt, BLOCKNUM *);
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 *diskoff, int n_children, BLOCKNUM *children, u_int32_t *subtree_fingerprints, char **keys, int *keylens);
int toku_testsetup_root(BRT brt, DISKOFF diskoff); int toku_testsetup_root(BRT brt, BLOCKNUM);
int toku_testsetup_get_sersize(BRT brt, DISKOFF diskoff); // Return the size on disk. int toku_testsetup_get_sersize(BRT brt, BLOCKNUM); // 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_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, DISKOFF diskoff, enum brt_cmd_type, char *key, int keylen, char *val, int vallen, u_int32_t *subtree_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)); 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); ...@@ -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); 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 { enum brt_layout_version_e {
BRT_LAYOUT_VERSION_5 = 5, BRT_LAYOUT_VERSION_5 = 5,
BRT_LAYOUT_VERSION_6 = 6, // Diff from 5 to 6: Add leafentry_estimate 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_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_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_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. BRT_LAYOUT_VERSION = BRT_ANTEULTIMATE_VERSION-1 // A hack so I don't have to change this line.
}; };
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "kv-pair.h" #include "kv-pair.h"
#include "mempool.h" #include "mempool.h"
#include <inttypes.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <arpa/inet.h> #include <arpa/inet.h>
...@@ -111,8 +112,9 @@ const int uncompressed_magic_len = (8 // tokuleaf or tokunode ...@@ -111,8 +112,9 @@ const int uncompressed_magic_len = (8 // tokuleaf or tokunode
const int compression_header_len = (4 // compressed_len const int compression_header_len = (4 // compressed_len
+4); // uncompressed_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__); //printf("%s:%d serializing\n", __FILE__, __LINE__);
DISKOFF offset = blocknum.b * node->nodesize;
struct wbuf w; struct wbuf w;
int i; int i;
unsigned int calculated_size = toku_serialize_brtnode_size(node) - 8; // don't include the compressed or uncompressed sizes 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) { ...@@ -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]); //printf("%s:%d w.ndone=%d (childkeylen[%d]=%d\n", __FILE__, __LINE__, w.ndone, i, node->childkeylens[i]);
} }
for (i=0; i<node->u.n.n_children; i++) { for (i=0; i<node->u.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); //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) { ...@@ -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); //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); assert(check_local_fingerprint==node->local_fingerprint);
} }
} else { } else {
...@@ -240,7 +242,7 @@ void toku_serialize_brtnode_to (int fd, DISKOFF off, BRTNODE node) { ...@@ -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 // 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; 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); if (r<0) printf("r=%ld errno=%d\n", (long)r, errno);
assert(r==(ssize_t)n_to_write); assert(r==(ssize_t)n_to_write);
} }
...@@ -251,7 +253,8 @@ void toku_serialize_brtnode_to (int fd, DISKOFF off, BRTNODE node) { ...@@ -251,7 +253,8 @@ void toku_serialize_brtnode_to (int fd, DISKOFF off, BRTNODE node) {
toku_free(compressed_buf); 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); TAGMALLOC(BRTNODE, result);
struct rbuf rc; struct rbuf rc;
int i; int i;
...@@ -267,7 +270,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN ...@@ -267,7 +270,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN
u_int32_t uncompressed_size; u_int32_t uncompressed_size;
{ {
// get the compressed 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)); //printf("%s:%d r=%d the datasize=%d\n", __FILE__, __LINE__, r, ntohl(datasize_n));
if (r!=(int)sizeof(uncompressed_header)) { if (r!=(int)sizeof(uncompressed_header)) {
if (r==-1) r=errno; if (r==-1) r=errno;
...@@ -285,7 +288,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN ...@@ -285,7 +288,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN
assert(compressed_data); 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); //printf("%s:%d pread->%d datasize=%d\n", __FILE__, __LINE__, r, datasize);
assert((size_t)rlen==compressed_size); 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]); //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 ...@@ -324,7 +327,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN
result->layout_version = rbuf_int(&rc); result->layout_version = rbuf_int(&rc);
{ {
switch (result->layout_version) { 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. // Don't support older versions.
} }
r=DB_BADFORMAT; r=DB_BADFORMAT;
...@@ -335,7 +338,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN ...@@ -335,7 +338,7 @@ int toku_deserialize_brtnode_from (int fd, DISKOFF off, u_int32_t fullhash, BRTN
result->nodesize = rbuf_int(&rc); result->nodesize = rbuf_int(&rc);
result->log_lsn = result->disk_lsn; result->log_lsn = result->disk_lsn;
result->thisnodename = off; result->thisnodename = blocknum;
result->flags = rbuf_int(&rc); result->flags = rbuf_int(&rc);
result->height = rbuf_int(&rc); result->height = rbuf_int(&rc);
result->rand4fingerprint = 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 ...@@ -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]); result->u.n.totalchildkeylens+=toku_brtnode_pivot_key_len(result, result->u.n.childkeys[i]);
} }
for (i=0; i<result->u.n.n_children; i++) { for (i=0; i<result->u.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_HAVE_FULLHASH(result, i) = FALSE;
BNC_NBYTESINBUF(result,i) = 0; BNC_NBYTESINBUF(result,i) = 0;
//printf("Child %d at %lld\n", i, result->children[i]); //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) ...@@ -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, size);
wbuf_int (wbuf, BRT_LAYOUT_VERSION); wbuf_int (wbuf, BRT_LAYOUT_VERSION);
wbuf_int (wbuf, h->nodesize); wbuf_int (wbuf, h->nodesize);
wbuf_DISKOFF(wbuf, h->freelist); wbuf_BLOCKNUM(wbuf, h->free_blocks);
wbuf_DISKOFF(wbuf, h->unused_memory); wbuf_BLOCKNUM(wbuf, h->unused_blocks);
wbuf_int (wbuf, h->n_named_roots); wbuf_int (wbuf, h->n_named_roots);
if (h->n_named_roots>=0) { if (h->n_named_roots>=0) {
int i; int i;
for (i=0; i<h->n_named_roots; i++) { for (i=0; i<h->n_named_roots; i++) {
char *s = h->names[i]; char *s = h->names[i];
unsigned int l = 1+strlen(s); 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_int (wbuf, h->flags_array[i]);
wbuf_bytes (wbuf, s, l); wbuf_bytes (wbuf, s, l);
assert(l>0 && s[l-1]==0); assert(l>0 && s[l-1]==0);
} }
} else { } else {
wbuf_DISKOFF(wbuf, h->roots[0]); wbuf_BLOCKNUM(wbuf, h->roots[0]);
wbuf_int (wbuf, h->flags_array[0]); wbuf_int (wbuf, h->flags_array[0]);
} }
assert(wbuf->ndone<=wbuf->size); assert(wbuf->ndone<=wbuf->size);
...@@ -623,10 +626,11 @@ int deserialize_brtheader_7_or_later(u_int32_t size, int fd, DISKOFF off, struct ...@@ -623,10 +626,11 @@ int deserialize_brtheader_7_or_later(u_int32_t size, int fd, DISKOFF off, struct
h->dirty=0; h->dirty=0;
h->layout_version = rbuf_int(&rc); h->layout_version = rbuf_int(&rc);
h->nodesize = rbuf_int(&rc); h->nodesize = rbuf_int(&rc);
assert(h->layout_version==BRT_LAYOUT_VERSION_8); assert(h->layout_version==BRT_LAYOUT_VERSION_9);
h->freelist = rbuf_diskoff(&rc); h->free_blocks = rbuf_blocknum(&rc);
h->unused_memory = rbuf_diskoff(&rc); h->unused_blocks = rbuf_blocknum(&rc);
h->n_named_roots = rbuf_int(&rc); h->n_named_roots = rbuf_int(&rc);
h->free_blocks = make_blocknum(-1);
if (h->n_named_roots>=0) { if (h->n_named_roots>=0) {
int i; int i;
int n_to_malloc = (h->n_named_roots == 0) ? 1 : h->n_named_roots; 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 ...@@ -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; } 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; i<h->n_named_roots; i++) { for (i=0; i<h->n_named_roots; i++) {
h->root_hashes[i].valid = FALSE; 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); h->flags_array[i] = rbuf_int(&rc);
bytevec nameptr; bytevec nameptr;
unsigned int len; unsigned int len;
...@@ -651,7 +655,7 @@ int deserialize_brtheader_7_or_later(u_int32_t size, int fd, DISKOFF off, struct ...@@ -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->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; } MALLOC_N(n_to_malloc, h->root_hashes); if (h->root_hashes==0) { ret=errno; goto died3; }
h->names = 0; h->names = 0;
h->roots[0] = rbuf_diskoff(&rc); h->roots[0] = rbuf_blocknum(&rc);
h->root_hashes[0].valid = FALSE; h->root_hashes[0].valid = FALSE;
h->flags_array[0] = rbuf_int(&rc); 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 ...@@ -661,19 +665,20 @@ int deserialize_brtheader_7_or_later(u_int32_t size, int fd, DISKOFF off, struct
return 0; 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__); //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); //printf("%s:%d malloced %p\n", __FILE__, __LINE__, h);
char magic[12]; 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 -1;
if (r<0) return errno; if (r<0) return errno;
if (r!=12) return EINVAL; if (r!=12) return EINVAL;
assert(memcmp(magic,"tokudata",8)==0); assert(memcmp(magic,"tokudata",8)==0);
// It's version 7 or later, and the magi clooks OK // 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) { unsigned int toku_brt_pivot_key_len (BRT brt, struct kv_pair *pk) {
......
#include "brt-internal.h" #include "brt-internal.h"
#include "toku_assert.h" #include "toku_assert.h"
int toku_testsetup_leaf(BRT brt, DISKOFF *diskoff) { int toku_testsetup_leaf(BRT brt, BLOCKNUM *blocknum) {
BRTNODE node; BRTNODE node;
int r = toku_read_and_pin_brt_header(brt->cf, &brt->h); int r = toku_read_and_pin_brt_header(brt->cf, &brt->h);
if (r!=0) return r; if (r!=0) return r;
toku_create_new_brtnode(brt, &node, 0, (TOKULOGGER)0); toku_create_new_brtnode(brt, &node, 0, (TOKULOGGER)0);
*diskoff = node->thisnodename; *blocknum = node->thisnodename;
r = toku_unpin_brtnode(brt, node); r = toku_unpin_brtnode(brt, node);
if (r!=0) return r; if (r!=0) return r;
r = toku_unpin_brt_header(brt); r = toku_unpin_brt_header(brt);
...@@ -16,7 +16,7 @@ int toku_testsetup_leaf(BRT brt, DISKOFF *diskoff) { ...@@ -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.) // 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; BRTNODE node;
assert(n_children<=BRT_FANOUT); assert(n_children<=BRT_FANOUT);
int r = toku_read_and_pin_brt_header(brt->cf, &brt->h); 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 ...@@ -31,7 +31,7 @@ int toku_testsetup_nonleaf (BRT brt, int height, DISKOFF *diskoff, int n_childre
for (i=0; i<n_children; i++) { for (i=0; i<n_children; i++) {
node->u.n.childinfos[i] = (struct brtnode_nonleaf_childinfo){ .subtree_fingerprint = subtree_fingerprints[i], node->u.n.childinfos[i] = (struct brtnode_nonleaf_childinfo){ .subtree_fingerprint = subtree_fingerprints[i],
.leafentry_estimate = 0, .leafentry_estimate = 0,
.diskoff = children[i], .blocknum = children[i],
.n_bytes_in_buffer = 0 }; .n_bytes_in_buffer = 0 };
r = toku_fifo_create(&BNC_BUFFER(node,i)); if (r!=0) return r; 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 ...@@ -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.childkeys[i] = kv_pair_malloc(keys[i], keylens[i], 0, 0);
node->u.n.totalchildkeylens += keylens[i]; node->u.n.totalchildkeylens += keylens[i];
} }
*diskoff = node->thisnodename; *blocknum = node->thisnodename;
r = toku_unpin_brtnode(brt, node); r = toku_unpin_brtnode(brt, node);
if (r!=0) return r; if (r!=0) return r;
r = toku_unpin_brt_header(brt); r = toku_unpin_brt_header(brt);
...@@ -47,16 +47,16 @@ int toku_testsetup_nonleaf (BRT brt, int height, DISKOFF *diskoff, int n_childre ...@@ -47,16 +47,16 @@ int toku_testsetup_nonleaf (BRT brt, int height, DISKOFF *diskoff, int n_childre
return 0; 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); int r = toku_read_and_pin_brt_header(brt->cf, &brt->h);
if (r!=0) return r; if (r!=0) return r;
brt->h->roots[0] = diskoff; brt->h->roots[0] = blocknum;
brt->h->root_hashes[0].valid = FALSE; brt->h->root_hashes[0].valid = FALSE;
r = toku_unpin_brt_header(brt); r = toku_unpin_brt_header(brt);
return r; 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; void *node_v;
int r = toku_cachetable_get_and_pin(brt->cf, diskoff, toku_cachetable_hash(brt->cf, diskoff), &node_v, NULL, 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 ...@@ -68,10 +68,10 @@ int toku_testsetup_get_sersize(BRT brt, DISKOFF diskoff) // Return the size on d
return size; 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; void *node_v;
int r; 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); toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt);
if (r!=0) return r; if (r!=0) return r;
BRTNODE node=node_v; BRTNODE node=node_v;
...@@ -120,10 +120,10 @@ int toku_testsetup_insert_to_leaf (BRT brt, DISKOFF diskoff, char *key, int keyl ...@@ -120,10 +120,10 @@ int toku_testsetup_insert_to_leaf (BRT brt, DISKOFF diskoff, char *key, int keyl
return r; 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; void *node_v;
int r; 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); toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt);
if (r!=0) return r; if (r!=0) return r;
BRTNODE node=node_v; BRTNODE node=node_v;
......
...@@ -59,13 +59,13 @@ static int compare_leafentries (BRT brt, LEAFENTRY a, LEAFENTRY b) { ...@@ -59,13 +59,13 @@ static int compare_leafentries (BRT brt, LEAFENTRY a, LEAFENTRY b) {
return cmp; 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; int result=0;
BRTNODE node; BRTNODE node;
void *node_v; void *node_v;
int r; int r;
u_int32_t fullhash = toku_cachetable_hash(brt->cf, off); u_int32_t fullhash = toku_cachetable_hash(brt->cf, blocknum);
if ((r = toku_cachetable_get_and_pin(brt->cf, off, fullhash, &node_v, NULL, 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))) toku_brtnode_flush_callback, toku_brtnode_fetch_callback, (void*)(long)brt->h->nodesize)))
return r; return r;
//printf("%s:%d pin %p\n", __FILE__, __LINE__, node_v); //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 ...@@ -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 (hirange) assert(brt->compare_fun(brt->db, &k2, toku_fill_dbt(&k3, hirange, hilen)) <=0);
} }
if (recurse) { 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) ? 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==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]), (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 ...@@ -149,7 +149,7 @@ int toku_verify_brtnode (BRT brt, DISKOFF off, bytevec lorange, ITEMLEN lolen, b
LEAFENTRY prev=0; LEAFENTRY prev=0;
toku_omt_iterate(node->u.l.buffer, check_increasing, &prev); 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; return result;
} }
......
...@@ -51,7 +51,6 @@ ...@@ -51,7 +51,6 @@
extern long long n_items_malloced; 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); 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. // 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) { ...@@ -161,18 +160,18 @@ static int brt_compare_pivot(BRT brt, DBT *key, DBT *data, bytevec ck) {
return cmp; 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; BRTNODE brtnode = brtnode_v;
// if ((write_me || keep_me) && (brtnode->height==0)) { // if ((write_me || keep_me) && (brtnode->height==0)) {
// toku_pma_verify_fingerprint(brtnode->u.l.buffer, brtnode->rand4fingerprint, brtnode->subtree_fingerprint); // toku_pma_verify_fingerprint(brtnode->u.l.buffer, brtnode->rand4fingerprint, brtnode->subtree_fingerprint);
// } // }
if (0) { 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); if (brtnode->height==0) printf(" buf=%p mempool-base=%p", brtnode->u.l.buffer, brtnode->u.l.buffer_mempool.base);
printf("\n"); printf("\n");
} }
//if (modified_lsn.lsn > brtnode->lsn.lsn) brtnode->lsn=modified_lsn; //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]); //printf("%s:%d %p->mdict[0]=%p\n", __FILE__, __LINE__, brtnode, brtnode->mdicts[0]);
if (write_me) { if (write_me) {
toku_serialize_brtnode_to(toku_cachefile_fd(cachefile), brtnode->thisnodename, brtnode); 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 ...@@ -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); //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; 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) { if (r == 0) {
*sizep = brtnode_memory_size(*result); *sizep = brtnode_memory_size(*result);
*written_lsn = (*result)->disk_lsn; *written_lsn = (*result)->disk_lsn;
...@@ -211,27 +212,28 @@ void toku_brtheader_free (struct brt_header *h) { ...@@ -211,27 +212,28 @@ void toku_brtheader_free (struct brt_header *h) {
toku_free(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; struct brt_header *h = header_v;
assert(nodename==0); assert(nodename.b==0);
assert(!h->dirty); // shouldn't be dirty once it is unpinned. assert(!h->dirty); // shouldn't be dirty once it is unpinned.
if (write_me) { if (write_me) {
toku_serialize_brt_header_to(toku_cachefile_fd(cachefile), h); 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) { if (!keep_me) {
toku_brtheader_free(h); 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; int r;
struct brt_header **h = (struct brt_header **)headerp_v; 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_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); //printf("%s:%d fifo=%p\nn", __FILE__, __LINE__, (*h)->fifo);
written_lsn->lsn = 0; // !!! WRONG. This should be stored or kept redundantly or something. written_lsn->lsn = 0; // !!! WRONG. This should be stored or kept redundantly or something.
assert((*h)->free_blocks.b==-1);
return 0; return 0;
} }
...@@ -239,19 +241,22 @@ int toku_read_and_pin_brt_header (CACHEFILE cf, struct brt_header **header) { ...@@ -239,19 +241,22 @@ int toku_read_and_pin_brt_header (CACHEFILE cf, struct brt_header **header) {
void *header_p; void *header_p;
//fprintf(stderr, "%s:%d read_and_pin_brt_header(...)\n", __FILE__, __LINE__); //fprintf(stderr, "%s:%d read_and_pin_brt_header(...)\n", __FILE__, __LINE__);
u_int32_t fullhash = toku_cachefile_fullhash_of_header(cf); 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); toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0);
if (r!=0) return r; if (r!=0) return r;
struct brt_header *bheader = header_p; struct brt_header *bheader = header_p;
assert(bheader->fullhash==fullhash); assert(bheader->fullhash==fullhash);
*header = bheader; *header = bheader;
assert((*header)->free_blocks.b==-1);
return 0; return 0;
} }
int toku_unpin_brt_header (BRT brt) { int toku_unpin_brt_header (BRT brt) {
int dirty = brt->h->dirty; int dirty = brt->h->dirty;
brt->h->dirty=0; // Unpinning it may make it go way. 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; brt->h=0;
return r; return r;
} }
...@@ -272,34 +277,12 @@ typedef struct kvpair { ...@@ -272,34 +277,12 @@ typedef struct kvpair {
unsigned int vallen; unsigned int vallen;
} *KVPAIR; } *KVPAIR;
/* Forgot to handle the case where there is something in the freelist. */ int allocate_diskblocknumber (BLOCKNUM *res, BRT brt, TOKULOGGER logger __attribute__((__unused__))) {
static int malloc_diskblock_header_is_in_memory (DISKOFF *res, BRT brt, int size, TOKULOGGER logger) { assert(brt->h->free_blocks.b == -1); // no blocks in the free list
DISKOFF result = brt->h->unused_memory; BLOCKNUM result = brt->h->unused_blocks;
brt->h->unused_memory+=size; brt->h->unused_blocks.b++;
brt->h->dirty = 1;
int r = toku_log_changeunusedmemory(logger, (LSN*)0, 0, toku_cachefile_filenum(brt->cf), result, brt->h->unused_memory);
*res = result; *res = result;
char *MALLOC_N(size, buf); return 0;
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
} }
u_int32_t mp_pool_size_for_nodesize (u_int32_t nodesize) { u_int32_t mp_pool_size_for_nodesize (u_int32_t nodesize) {
...@@ -328,14 +311,14 @@ static inline u_int32_t myrandom (void) { ...@@ -328,14 +311,14 @@ static inline u_int32_t myrandom (void) {
return rstate; 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->tag = TYP_BRTNODE;
n->nodesize = t->h->nodesize; n->nodesize = t->h->nodesize;
n->flags = t->flags; n->flags = t->flags;
n->thisnodename = nodename; n->thisnodename = nodename;
n->disk_lsn.lsn = 0; // a new one can always be 0. n->disk_lsn.lsn = 0; // a new one can always be 0.
n->log_lsn = n->disk_lsn; n->log_lsn = n->disk_lsn;
n->layout_version = BRT_LAYOUT_VERSION_7; n->layout_version = BRT_LAYOUT_VERSION;
n->height = height; n->height = height;
n->rand4fingerprint = random(); n->rand4fingerprint = random();
n->local_fingerprint = 0; n->local_fingerprint = 0;
...@@ -369,12 +352,11 @@ static void initialize_brtnode (BRT t, BRTNODE n, DISKOFF nodename, int height) ...@@ -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) { int toku_create_new_brtnode (BRT t, BRTNODE *result, int height, TOKULOGGER logger) {
TAGMALLOC(BRTNODE, n); TAGMALLOC(BRTNODE, n);
int r; int r;
DISKOFF name; BLOCKNUM name;
r = malloc_diskblock(&name, t, t->h->nodesize, logger); r = allocate_diskblocknumber (&name, t, logger);
assert(r==0); assert(r==0);
assert(n); assert(n);
assert(t->h->nodesize>0); 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; n->ever_been_written = 0;
initialize_brtnode(t, n, name, height); initialize_brtnode(t, n, name, height);
*result = n; *result = n;
...@@ -572,7 +554,7 @@ static int log_and_save_brtenq(TOKULOGGER logger, BRT t, BRTNODE node, int child ...@@ -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 old_fingerprint = *fingerprint;
u_int32_t fdiff=node->rand4fingerprint*toku_calc_fingerprint_cmd(type, xid, key, keylen, data, datalen); u_int32_t fdiff=node->rand4fingerprint*toku_calc_fingerprint_cmd(type, xid, key, keylen, data, datalen);
u_int32_t new_fingerprint = old_fingerprint + fdiff; 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; *fingerprint = new_fingerprint;
if (t->txn_that_created != xid) { 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); 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 ...@@ -616,14 +598,14 @@ static int brt_nonleaf_split (BRT t, BRTNODE node, BRTNODE *nodea, BRTNODE *node
int targchild = i-n_children_in_a; int targchild = i-n_children_in_a;
FIFO from_htab = BNC_BUFFER(node,i); FIFO from_htab = BNC_BUFFER(node,i);
FIFO to_htab = BNC_BUFFER(B, targchild); 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_HAVE_FULLHASH(B,targchild) = BNC_HAVE_FULLHASH(node,i);
BNC_FULLHASH(B,targchild) = BNC_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; if (r!=0) return r;
while (1) { while (1) {
...@@ -662,7 +644,7 @@ static int brt_nonleaf_split (BRT t, BRTNODE node, BRTNODE *nodea, BRTNODE *node ...@@ -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]), BYTESTRING bs = { .len = kv_pair_keylen(node->u.n.childkeys[i-1]),
.data = kv_pair_key(node->u.n.childkeys[i-1]) }; .data = kv_pair_key(node->u.n.childkeys[i-1]) };
assert(i>0); 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 (r!=0) return r;
if (i>n_children_in_a) { if (i>n_children_in_a) {
r = toku_log_setpivot(logger, (LSN*)0, 0, fnum, B->thisnodename, targchild-1, bs); 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 ...@@ -673,7 +655,7 @@ static int brt_nonleaf_split (BRT t, BRTNODE node, BRTNODE *nodea, BRTNODE *node
node->u.n.childkeys[i-1] = 0; 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_HAVE_FULLHASH(node, i) = FALSE;
BNC_SUBTREE_FINGERPRINT(B, targchild) = BNC_SUBTREE_FINGERPRINT(node, i); 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, ...@@ -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); 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++; node->u.n.n_children++;
assert(BNC_DISKOFF(node, childnum)==childa->thisnodename); // use the same child assert(BNC_BLOCKNUM(node, childnum).b==childa->thisnodename.b); // use the same child
BNC_DISKOFF(node, childnum+1) = childb->thisnodename; BNC_BLOCKNUM(node, childnum+1) = childb->thisnodename;
BNC_HAVE_FULLHASH(node, childnum+1) = TRUE; BNC_HAVE_FULLHASH(node, childnum+1) = TRUE;
BNC_FULLHASH(node, childnum+1) = childb->fullhash; 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 // 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, ...@@ -1036,8 +1018,8 @@ static int handle_split_of_child (BRT t, BRTNODE node, int childnum,
assert((*nodeb)->height>0); assert((*nodeb)->height>0);
assert((*nodea)->u.n.n_children>0); assert((*nodea)->u.n.n_children>0);
assert((*nodeb)->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_BLOCKNUM(*nodea, (*nodea)->u.n.n_children-1).b!=0);
assert(BNC_DISKOFF(*nodeb, (*nodeb)->u.n.n_children-1)!=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(*nodea)<=(*nodea)->nodesize);
assert(toku_serialize_brtnode_size(*nodeb)<=(*nodeb)->nodesize); assert(toku_serialize_brtnode_size(*nodeb)<=(*nodeb)->nodesize);
//verify_local_fingerprint_nonleaf(*nodea); //verify_local_fingerprint_nonleaf(*nodea);
...@@ -1059,12 +1041,12 @@ static u_int32_t compute_child_fullhash (CACHEFILE cf, BRTNODE node, int childnu ...@@ -1059,12 +1041,12 @@ static u_int32_t compute_child_fullhash (CACHEFILE cf, BRTNODE node, int childnu
switch (BNC_HAVE_FULLHASH(node, childnum)) { switch (BNC_HAVE_FULLHASH(node, childnum)) {
case TRUE: 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); return BNC_FULLHASH(node, childnum);
} }
case FALSE: 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_HAVE_FULLHASH(node, childnum) = TRUE;
BNC_FULLHASH(node, childnum) = child_fullhash; BNC_FULLHASH(node, childnum) = child_fullhash;
return child_fullhash; return child_fullhash;
...@@ -1082,19 +1064,19 @@ static int push_some_brt_cmds_down (BRT t, BRTNODE node, int childnum, ...@@ -1082,19 +1064,19 @@ static int push_some_brt_cmds_down (BRT t, BRTNODE node, int childnum,
BRTNODE child; BRTNODE child;
int r; int r;
assert(node->height>0); assert(node->height>0);
DISKOFF targetchild = BNC_DISKOFF(node, childnum); BLOCKNUM targetchild = BNC_BLOCKNUM(node, childnum);
assert(targetchild>=0 && targetchild<t->h->unused_memory); // This assertion could fail in a concurrent setting since another process might have bumped unused memory. assert(targetchild.b>=0 && targetchild.b<t->h->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); u_int32_t childfullhash = compute_child_fullhash(t->cf, node, childnum);
r = toku_cachetable_get_and_pin(t->cf, targetchild, childfullhash, &childnode_v, NULL, r = toku_cachetable_get_and_pin(t->cf, targetchild, childfullhash, &childnode_v, NULL,
toku_brtnode_flush_callback, toku_brtnode_fetch_callback, t); toku_brtnode_flush_callback, toku_brtnode_fetch_callback, t);
if (r!=0) return r; if (r!=0) return r;
//printf("%s:%d pin %p\n", __FILE__, __LINE__, childnode_v); //printf("%s:%d pin %p\n", __FILE__, __LINE__, childnode_v);
child=childnode_v; child=childnode_v;
assert(child->thisnodename!=0); assert(child->thisnodename.b!=0);
//verify_local_fingerprint_nonleaf(child); //verify_local_fingerprint_nonleaf(child);
VERIFY_NODE(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]); //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) { if (0) {
static int count=0; static int count=0;
...@@ -1168,7 +1150,7 @@ static int brtnode_maybe_push_down(BRT t, BRTNODE node, int *did_split, BRTNODE ...@@ -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. */ * But if the child pushes something to its child and our buffer has gotten small enough, then we stop pushing. */
int childnum; int childnum;
find_heaviest_child(node, &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); int r = push_some_brt_cmds_down(t, node, childnum, did_split, nodea, nodeb, splitk, logger);
if (r!=0) return r; if (r!=0) return r;
assert(*did_split==0 || *did_split==1); 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 ...@@ -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(toku_serialize_brtnode_size(*nodeb)<=(*nodeb)->nodesize);
assert((*nodea)->u.n.n_children>0); assert((*nodea)->u.n.n_children>0);
assert((*nodeb)->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_BLOCKNUM(*nodea, (*nodea)->u.n.n_children-1).b!=0);
assert(BNC_DISKOFF(*nodeb, (*nodeb)->u.n.n_children-1)!=0); assert(BNC_BLOCKNUM(*nodeb, (*nodeb)->u.n.n_children-1).b!=0);
//verify_local_fingerprint_nonleaf(*nodea); //verify_local_fingerprint_nonleaf(*nodea);
//verify_local_fingerprint_nonleaf(*nodeb); //verify_local_fingerprint_nonleaf(*nodeb);
} else { } else {
...@@ -1747,12 +1729,12 @@ static int brt_nonleaf_put_cmd_child_node (BRT t, BRTNODE node, BRT_CMD cmd, ...@@ -1747,12 +1729,12 @@ static int brt_nonleaf_put_cmd_child_node (BRT t, BRTNODE node, BRT_CMD cmd,
*did_split = 0; *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); u_int32_t fullhash = compute_child_fullhash(t->cf, node, childnum);
if (maybe) 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 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); toku_brtnode_flush_callback, toku_brtnode_fetch_callback, t);
if (r != 0) if (r != 0)
return r; return r;
...@@ -1846,8 +1828,8 @@ static int brt_nonleaf_cmd_once (BRT t, BRTNODE node, BRT_CMD cmd, ...@@ -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(toku_serialize_brtnode_size(*nodeb)<=(*nodeb)->nodesize);
assert((*nodea)->u.n.n_children>0); assert((*nodea)->u.n.n_children>0);
assert((*nodeb)->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_BLOCKNUM(*nodea, (*nodea)->u.n.n_children-1).b!=0);
assert(BNC_DISKOFF(*nodeb, (*nodeb)->u.n.n_children-1)!=0); assert(BNC_BLOCKNUM(*nodeb, (*nodeb)->u.n.n_children-1).b!=0);
} else { } else {
assert(toku_serialize_brtnode_size(node)<=node->nodesize); 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, ...@@ -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(toku_serialize_brtnode_size(*nodeb)<=(*nodeb)->nodesize);
assert((*nodea)->u.n.n_children>0); assert((*nodea)->u.n.n_children>0);
assert((*nodeb)->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_BLOCKNUM(*nodea,(*nodea)->u.n.n_children-1).b!=0);
assert(BNC_DISKOFF(*nodeb,(*nodeb)->u.n.n_children-1)!=0); assert(BNC_BLOCKNUM(*nodeb,(*nodeb)->u.n.n_children-1).b!=0);
} else { } else {
assert(toku_serialize_brtnode_size(node)<=node->nodesize); assert(toku_serialize_brtnode_size(node)<=node->nodesize);
} }
...@@ -2009,24 +1991,22 @@ int toku_brt_create_cachetable(CACHETABLE *ct, long cachesize, LSN initial_lsn, ...@@ -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); 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; int r;
TAGMALLOC(BRTNODE, node); TAGMALLOC(BRTNODE, node);
assert(node); assert(node);
node->ever_been_written = 0; node->ever_been_written = 0;
//printf("%s:%d\n", __FILE__, __LINE__); //printf("%s:%d\n", __FILE__, __LINE__);
initialize_brtnode(t, node, initialize_brtnode(t, node, blocknum, 0);
offset, /* the location is one nodesize offset from 0. */
0);
// node->brt = t; // node->brt = t;
if (0) { 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 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); //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; node->fullhash = fullhash;
r=toku_cachetable_put(t->cf, offset, fullhash, r=toku_cachetable_put(t->cf, blocknum, fullhash,
node, brtnode_memory_size(node), node, brtnode_memory_size(node),
toku_brtnode_flush_callback, toku_brtnode_fetch_callback, t); toku_brtnode_flush_callback, toku_brtnode_fetch_callback, t);
if (r!=0) { if (r!=0) {
...@@ -2034,7 +2014,7 @@ static int setup_initial_brt_root_node (BRT t, DISKOFF offset, TOKULOGGER logger ...@@ -2034,7 +2014,7 @@ static int setup_initial_brt_root_node (BRT t, DISKOFF offset, TOKULOGGER logger
return r; return r;
} }
// verify_local_fingerprint_nonleaf(node); // 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); r = toku_unpin_brtnode(t, node);
if (r!=0) { if (r!=0) {
toku_free(node); toku_free(node);
...@@ -2114,7 +2094,7 @@ static void compute_and_fill_remembered_hash (BRT brt, int rootnum) { ...@@ -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) { static u_int32_t get_roothash (BRT brt, int rootnum) {
struct remembered_hash *rh = &brt->h->root_hashes[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. // compare cf first, since cf is NULL for invalid entries.
assert(rh); assert(rh);
//printf("v=%d\n", rh->valid); //printf("v=%d\n", rh->valid);
...@@ -2122,7 +2102,7 @@ static u_int32_t get_roothash (BRT brt, int rootnum) { ...@@ -2122,7 +2102,7 @@ static u_int32_t get_roothash (BRT brt, int rootnum) {
//printf("f=%d\n", rh->fnum.fileid); //printf("f=%d\n", rh->fnum.fileid);
//printf("cf=%d\n", toku_cachefile_filenum(brt->cf).fileid); //printf("cf=%d\n", toku_cachefile_filenum(brt->cf).fileid);
if (rh->fnum.fileid == 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; return rh->fullhash;
} }
compute_and_fill_remembered_hash(brt, rootnum); 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 ...@@ -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. // allocate and initialize a brt header.
static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) { static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) {
int r; int r;
BLOCKNUM root = make_blocknum(1);
assert(t->h == 0); assert(t->h == 0);
if ((MALLOC(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) { ...@@ -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; } 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->flags_array[0] = t->flags;
t->h->nodesize=t->nodesize; t->h->nodesize=t->nodesize;
t->h->freelist=-1; t->h->free_blocks = make_blocknum(-1);
t->h->unused_memory=2*t->nodesize; t->h->unused_blocks=make_blocknum(2);
toku_fifo_create(&t->h->fifo); toku_fifo_create(&t->h->fifo);
t->root_put_counter = global_root_put_counter++; t->root_put_counter = global_root_put_counter++;
if (dbname) { if (dbname) {
...@@ -2182,12 +2163,12 @@ static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) { ...@@ -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->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 ((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; } 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); compute_and_fill_remembered_hash(t, 0);
} else { } else {
MALLOC_N(1, t->h->roots); assert(t->h->roots); MALLOC_N(1, t->h->roots); assert(t->h->roots);
MALLOC_N(1, t->h->root_hashes); assert(t->h->root_hashes); 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); compute_and_fill_remembered_hash(t, 0);
t->h->n_named_roots = -1; t->h->n_named_roots = -1;
t->h->names=0; t->h->names=0;
...@@ -2197,8 +2178,8 @@ static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) { ...@@ -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), LOGGEDBRTHEADER lh = {.size= toku_serialize_brt_header_size(t->h),
.flags = t->flags, .flags = t->flags,
.nodesize = t->h->nodesize, .nodesize = t->h->nodesize,
.freelist = t->h->freelist, .free_blocks = t->h->free_blocks,
.unused_memory = t->h->unused_memory, .unused_blocks = t->h->unused_blocks,
.n_named_roots = t->h->n_named_roots }; .n_named_roots = t->h->n_named_roots };
if (t->h->n_named_roots>=0) { if (t->h->n_named_roots>=0) {
lh.u.many.names = t->h->names; lh.u.many.names = t->h->names;
...@@ -2208,11 +2189,12 @@ static int brt_alloc_init_header(BRT t, const char *dbname, TOKUTXN txn) { ...@@ -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=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); //printf("%s:%d putting %p (%d)\n", __FILE__, __LINE__, t->h, 0);
u_int32_t fullhash = toku_cachefile_fullhash_of_header(t->cf); u_int32_t fullhash = toku_cachefile_fullhash_of_header(t->cf);
t->h->fullhash = fullhash; 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; return r;
} }
...@@ -2266,7 +2248,7 @@ int toku_brt_open(BRT t, const char *fname, const char *fname_in_env, const char ...@@ -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(); //printf("%s:%d %d alloced\n", __FILE__, __LINE__, get_n_items_malloced()); toku_print_malloced_items();
if (0) { if (0) {
died_after_read_and_pin: 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; goto died1;
} }
if (is_create) { if (is_create) {
...@@ -2304,7 +2286,7 @@ int toku_brt_open(BRT t, const char *fname, const char *fname_in_env, const char ...@@ -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++; 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; } 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); //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; if (r!=0) goto died_after_read_and_pin;
t->h->dirty = 1; t->h->dirty = 1;
compute_and_fill_remembered_hash(t, t->h->n_named_roots-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, ...@@ -2500,8 +2482,8 @@ static int brt_init_new_root(BRT brt, BRTNODE nodea, BRTNODE nodeb, DBT splitk,
int r; int r;
int new_height = nodea->height+1; int new_height = nodea->height+1;
int new_nodesize = brt->h->nodesize; int new_nodesize = brt->h->nodesize;
DISKOFF newroot_diskoff; BLOCKNUM newroot_diskoff;
r=malloc_diskblock(&newroot_diskoff, brt, new_nodesize, logger); r = allocate_diskblocknumber(&newroot_diskoff, brt, logger);
assert(r==0); assert(r==0);
assert(newroot); assert(newroot);
newroot->ever_been_written = 0; newroot->ever_been_written = 0;
...@@ -2523,8 +2505,8 @@ static int brt_init_new_root(BRT brt, BRTNODE nodea, BRTNODE nodeb, DBT splitk, ...@@ -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); //printf("%s:%d Splitkey=%p %s\n", __FILE__, __LINE__, splitkey, splitkey);
newroot->u.n.childkeys[0] = splitk.data; newroot->u.n.childkeys[0] = splitk.data;
newroot->u.n.totalchildkeylens=splitk.size; newroot->u.n.totalchildkeylens=splitk.size;
BNC_DISKOFF(newroot,0)=nodea->thisnodename; BNC_BLOCKNUM(newroot,0)=nodea->thisnodename;
BNC_DISKOFF(newroot,1)=nodeb->thisnodename; BNC_BLOCKNUM(newroot,1)=nodeb->thisnodename;
BNC_HAVE_FULLHASH(newroot, 0) = FALSE; BNC_HAVE_FULLHASH(newroot, 0) = FALSE;
BNC_HAVE_FULLHASH(newroot, 1) = FALSE; BNC_HAVE_FULLHASH(newroot, 1) = FALSE;
r=toku_fifo_create(&BNC_BUFFER(newroot,0)); if (r!=0) return r; 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) { ...@@ -2578,7 +2560,7 @@ int toku_cachefile_root_put_cmd (CACHEFILE cf, BRT_CMD cmd, TOKULOGGER logger) {
if (r!=0) return r; if (r!=0) return r;
} }
h->dirty = 0; 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; return 0;
} }
...@@ -2596,7 +2578,7 @@ static int push_something(BRT brt, BRTNODE *nodep, CACHEKEY *rootp, BRT_CMD cmd, ...@@ -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("%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); //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); assert(nodeb->nodesize>0);
r = brt_init_new_root(brt, nodea, nodeb, splitk, rootp, logger, nodep); r = brt_init_new_root(brt, nodea, nodeb, splitk, rootp, logger, nodep);
assert(r == 0); assert(r == 0);
...@@ -2715,23 +2697,23 @@ int toku_brt_delete_both(BRT brt, DBT *key, DBT *val, TOKUTXN txn) { ...@@ -2715,23 +2697,23 @@ int toku_brt_delete_both(BRT brt, DBT *key, DBT *val, TOKUTXN txn) {
return r; 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; int result=0;
BRTNODE node; BRTNODE node;
void *node_v; void *node_v;
u_int32_t fullhash = toku_cachetable_hash(brt->cf, off); u_int32_t fullhash = toku_cachetable_hash(brt->cf, blocknum);
int r = toku_cachetable_get_and_pin(brt->cf, off, fullhash, int r = toku_cachetable_get_and_pin(brt->cf, blocknum, fullhash,
&node_v, NULL, &node_v, NULL,
toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt); toku_brtnode_flush_callback, toku_brtnode_fetch_callback, brt);
assert(r==0); assert(r==0);
printf("%s:%d pin %p\n", __FILE__, __LINE__, node_v); printf("%s:%d pin %p\n", __FILE__, __LINE__, node_v);
node=node_v; node=node_v;
assert(node->fullhash==fullhash); 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); printf("%*sNode=%p\n", depth, "", node);
if (node->height>0) { if (node->height>0) {
printf("%*sNode %lld nodesize=%d height=%d n_children=%d n_bytes_in_buffers=%d keyrange=%s %s\n", printf("%*sNode %"PRId64" 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); 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"); //printf("%s %s\n", lorange ? lorange : "NULL", hirange ? hirange : "NULL");
{ {
int i; int i;
...@@ -2750,7 +2732,7 @@ int toku_dump_brtnode (BRT brt, DISKOFF off, int depth, bytevec lorange, ITEMLEN ...@@ -2750,7 +2732,7 @@ int toku_dump_brtnode (BRT brt, DISKOFF off, int depth, bytevec lorange, ITEMLEN
if (i>0) { 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)); 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) ? lorange : node->u.n.childkeys[i-1],
(i==0) ? lolen : toku_brt_pivot_key_len(brt, 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], (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 ...@@ -2759,13 +2741,13 @@ int toku_dump_brtnode (BRT brt, DISKOFF off, int depth, bytevec lorange, ITEMLEN
} }
} }
} else { } else {
printf("%*sNode %lld nodesize=%d height=%d n_bytes_in_buffer=%d keyrange=%d %d\n", printf("%*sNode %" PRId64 " 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); 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, //GPMA_ITERATE(node->u.l.buffer, idx, len, data,
// printf(" (%d)%u ", len, *(int*)le_any_key(data))); // printf(" (%d)%u ", len, *(int*)le_any_key(data)));
printf("\n"); 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); assert(r==0);
return result; return result;
} }
...@@ -2803,7 +2785,7 @@ static int show_brtnode_blocknumbers (BRT brt, DISKOFF off) { ...@@ -2803,7 +2785,7 @@ static int show_brtnode_blocknumbers (BRT brt, DISKOFF off) {
printf(" %lld", off/brt->h->nodesize); printf(" %lld", off/brt->h->nodesize);
if (node->height>0) { if (node->height>0) {
for (i=0; i<node->u.n.n_children; i++) { for (i=0; i<node->u.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); 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 ...@@ -2854,9 +2836,9 @@ static int brt_search_child(BRT brt, BRTNODE node, int childnum, brt_search_t *s
} }
void *node_v; 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); 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); assert(rr == 0);
for (;;) { for (;;) {
...@@ -3804,7 +3786,7 @@ static void toku_brt_keyrange_internal (BRT brt, CACHEKEY nodename, u_int32_t fu ...@@ -3804,7 +3786,7 @@ static void toku_brt_keyrange_internal (BRT brt, CACHEKEY nodename, u_int32_t fu
} else { } else {
// nextcomp>=0 and prevcomp<=0, so something in the subtree could match // 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 // 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 { } else {
......
...@@ -26,30 +26,30 @@ void print_item (bytevec val, ITEMLEN len) { ...@@ -26,30 +26,30 @@ void print_item (bytevec val, ITEMLEN len) {
void dump_header (int f, struct brt_header **header) { void dump_header (int f, struct brt_header **header) {
struct brt_header *h; struct brt_header *h;
int r; 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"); printf("brtheader:\n");
if (h->layout_version==BRT_LAYOUT_VERSION_6) printf(" layout_version<=6\n"); if (h->layout_version==BRT_LAYOUT_VERSION_6) printf(" layout_version<=6\n");
else printf(" layout_version=%d\n", h->layout_version); else printf(" layout_version=%d\n", h->layout_version);
printf(" dirty=%d\n", h->dirty); printf(" dirty=%d\n", h->dirty);
printf(" nodesize=%d\n", h->nodesize); printf(" nodesize=%d\n", h->nodesize);
printf(" freelist=%lld\n", h->freelist); printf(" free_blocks=%" PRId64 "\n", h->free_blocks.b);
printf(" unused_memory=%lld\n", h->unused_memory); printf(" unused_memory=%" PRId64 "\n", h->unused_blocks.b);
if (h->n_named_roots==-1) { 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]); printf(" flags=%d\n", h->flags_array[0]);
} else { } else {
printf(" n_named_roots=%d\n", h->n_named_roots); printf(" n_named_roots=%d\n", h->n_named_roots);
if (h->n_named_roots>=0) { if (h->n_named_roots>=0) {
int i; int i;
for (i=0; i<h->n_named_roots; i++) { for (i=0; i<h->n_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]); printf(" flags=%d\n", h->flags_array[i]);
} }
} }
} }
*header = h; *header = h;
printf("Fifo:\n"); 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)); printf(" fifo has %d entries\n", toku_fifo_n_entries(h->fifo));
if (dump_data) { if (dump_data) {
FIFO_ITERATE(h->fifo, key, keylen, data, datalen, type, xid, 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)) { ...@@ -83,16 +83,16 @@ int print_le(OMTVALUE lev, u_int32_t UU(idx), void *UU(v)) {
return 0; return 0;
} }
void dump_node (int f, DISKOFF off) { void dump_node (int f, BLOCKNUM blocknum, int tree_node_size) {
BRTNODE n; 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(r==0);
assert(n!=0); assert(n!=0);
printf("brtnode\n"); printf("brtnode\n");
printf(" nodesize =%u\n", n->nodesize); printf(" nodesize =%u\n", n->nodesize);
printf(" sizeonddisk =%d\n", toku_serialize_brtnode_size(n)); printf(" sizeonddisk =%d\n", toku_serialize_brtnode_size(n));
printf(" flags =%u\n", n->flags); 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(" 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(" log_lsn =%lld\n", n->log_lsn.lsn); // The log_lsn is a memory-only value.
printf(" height =%d\n", n->height); printf(" height =%d\n", n->height);
...@@ -126,7 +126,7 @@ void dump_node (int f, DISKOFF off) { ...@@ -126,7 +126,7 @@ void dump_node (int f, DISKOFF off) {
} }
printf(" children:\n"); printf(" children:\n");
for (i=0; i<n->u.n.n_children; i++) { for (i=0; i<n->u.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))); printf(" buffer contains %d bytes (%d items)\n", BNC_NBYTESINBUF(n, i), toku_fifo_n_entries(BNC_BUFFER(n,i)));
if (dump_data) { if (dump_data) {
FIFO_ITERATE(BNC_BUFFER(n,i), key, keylen, data, datalen, typ, xid, FIFO_ITERATE(BNC_BUFFER(n,i), key, keylen, data, datalen, typ, xid,
...@@ -180,9 +180,9 @@ int main (int argc, const char *argv[]) { ...@@ -180,9 +180,9 @@ int main (int argc, const char *argv[]) {
int f = open(n, O_RDONLY); assert(f>=0); int f = open(n, O_RDONLY); assert(f>=0);
struct brt_header *h; struct brt_header *h;
dump_header(f, &h); dump_header(f, &h);
DISKOFF off; BLOCKNUM blocknum;
for (off=h->nodesize; off<h->unused_memory; off+=h->nodesize) { for (blocknum.b=1; blocknum.b<h->unused_blocks.b; blocknum.b++) {
dump_node(f, off); dump_node(f, blocknum, h->nodesize);
} }
toku_brtheader_free(h); toku_brtheader_free(h);
toku_malloc_cleanup(); toku_malloc_cleanup();
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
#include "../include/db.h" #include "../include/db.h"
#include <inttypes.h>
typedef struct brt *BRT; typedef struct brt *BRT;
struct brt_header; struct brt_header;
...@@ -21,6 +22,10 @@ typedef const void *bytevec; ...@@ -21,6 +22,10 @@ typedef const void *bytevec;
typedef long long DISKOFF; /* Offset in a disk. -1 is the NULL pointer. */ typedef long long DISKOFF; /* Offset in a disk. -1 is the NULL pointer. */
typedef u_int64_t TXNID; 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 { typedef struct {
u_int32_t len; u_int32_t len;
...@@ -46,16 +51,16 @@ typedef struct loggedbrtheader { ...@@ -46,16 +51,16 @@ typedef struct loggedbrtheader {
u_int32_t size; u_int32_t size;
u_int32_t flags; u_int32_t flags;
u_int32_t nodesize; u_int32_t nodesize;
DISKOFF freelist; BLOCKNUM free_blocks;
DISKOFF unused_memory; BLOCKNUM unused_blocks;
int32_t n_named_roots; // -1 for the union below to be "one". int32_t n_named_roots; // -1 for the union below to be "one".
union { union {
struct { struct {
char **names; char **names;
DISKOFF *roots; BLOCKNUM *roots;
} many; } many;
struct { struct {
DISKOFF root; BLOCKNUM root;
} one; } one;
} u; } u;
} LOGGEDBRTHEADER; } LOGGEDBRTHEADER;
......
...@@ -2,12 +2,13 @@ ...@@ -2,12 +2,13 @@
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include <errno.h> #include <errno.h>
#include <malloc.h>
#include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/time.h> #include <sys/time.h>
#include <pthread.h> #include <unistd.h>
#include "cachetable.h" #include "cachetable.h"
#include "hashfun.h" #include "hashfun.h"
...@@ -17,7 +18,6 @@ ...@@ -17,7 +18,6 @@
#include "log_header.h" #include "log_header.h"
#include "threadpool.h" #include "threadpool.h"
#include "cachetable-rwlock.h" #include "cachetable-rwlock.h"
#include <malloc.h>
// execute the cachetable callbacks using a writer thread 0->no 1->yes // execute the cachetable callbacks using a writer thread 0->no 1->yes
#define DO_WRITER_THREAD 1 #define DO_WRITER_THREAD 1
...@@ -233,7 +233,7 @@ int toku_cachetable_openfd (CACHEFILE *cf, CACHETABLE t, int fd, const char *fna ...@@ -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++; newcf->filenum.fileid = next_filenum_to_use.fileid++;
cachefile_init_filenum(newcf, fd, fname, fileid); cachefile_init_filenum(newcf, fd, fname, fileid);
newcf->refcount = 1; newcf->refcount = 1;
newcf->header_fullhash = toku_cachetable_hash(newcf, 0); newcf->header_fullhash = toku_cachetable_hash(newcf, header_blocknum);
newcf->next = t->cachefiles; newcf->next = t->cachefiles;
t->cachefiles = newcf; t->cachefiles = newcf;
*cf = newcf; *cf = newcf;
...@@ -340,7 +340,7 @@ int toku_cachetable_assert_all_unpinned (CACHETABLE t) { ...@@ -340,7 +340,7 @@ int toku_cachetable_assert_all_unpinned (CACHETABLE t) {
for (p=t->table[i]; p; p=p->hash_chain) { for (p=t->table[i]; p; p=p->hash_chain) {
assert(ctpair_pinned(&p->rwlock)>=0); assert(ctpair_pinned(&p->rwlock)>=0);
if (ctpair_pinned(&p->rwlock)) { 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; some_pinned=1;
} }
} }
...@@ -359,7 +359,7 @@ int toku_cachefile_count_pinned (CACHEFILE cf, int print_them) { ...@@ -359,7 +359,7 @@ int toku_cachefile_count_pinned (CACHEFILE cf, int print_them) {
for (p=t->table[i]; p; p=p->hash_chain) { for (p=t->table[i]; p; p=p->hash_chain) {
assert(ctpair_pinned(&p->rwlock)>=0); assert(ctpair_pinned(&p->rwlock)>=0);
if (ctpair_pinned(&p->rwlock) && (cf==0 || p->cachefile==cf)) { 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++; n_pinned++;
} }
} }
...@@ -386,10 +386,10 @@ static inline u_int32_t final (u_int32_t a, u_int32_t b, u_int32_t c) { ...@@ -386,10 +386,10 @@ static inline u_int32_t final (u_int32_t a, u_int32_t b, u_int32_t c) {
return 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. // 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 #if 0
...@@ -708,7 +708,7 @@ int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, v ...@@ -708,7 +708,7 @@ int toku_cachetable_put(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, v
PAIR p; PAIR p;
for (p=ct->table[fullhash&(cachefile->cachetable->table_size-1)]; p; p=p->hash_chain) { for (p=ct->table[fullhash&(cachefile->cachetable->table_size-1)]; p; p=p->hash_chain) {
count++; 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? // Semantically, these two asserts are not strictly right. After all, when are two functions eq?
// In practice, the functions better be the same. // In practice, the functions better be the same.
assert(p->flush_callback==flush_callback); assert(p->flush_callback==flush_callback);
...@@ -742,7 +742,7 @@ int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t ful ...@@ -742,7 +742,7 @@ int toku_cachetable_get_and_pin(CACHEFILE cachefile, CACHEKEY key, u_int32_t ful
cachetable_wait_write(t); cachetable_wait_write(t);
for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) {
count++; count++;
if (p->key==key && p->cachefile==cachefile) { if (p->key.b==key.b && p->cachefile==cachefile) {
*value = p->value; *value = p->value;
if (sizep) *sizep = p->size; if (sizep) *sizep = p->size;
ctpair_read_lock(&p->rwlock, &t->mutex); ctpair_read_lock(&p->rwlock, &t->mutex);
...@@ -783,7 +783,8 @@ int toku_cachetable_maybe_get_and_pin (CACHEFILE cachefile, CACHEKEY key, u_int3 ...@@ -783,7 +783,8 @@ int toku_cachetable_maybe_get_and_pin (CACHEFILE cachefile, CACHEKEY key, u_int3
cachetable_lock(t); cachetable_lock(t);
for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) {
count++; 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; *value = p->value;
ctpair_read_lock(&p->rwlock, &t->mutex); ctpair_read_lock(&p->rwlock, &t->mutex);
lru_touch(t,p); lru_touch(t,p);
...@@ -809,7 +810,7 @@ int toku_cachetable_unpin(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash, ...@@ -809,7 +810,7 @@ int toku_cachetable_unpin(CACHEFILE cachefile, CACHEKEY key, u_int32_t fullhash,
cachetable_lock(t); cachetable_lock(t);
for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) {
count++; count++;
if (p->key==key && p->cachefile==cachefile) { if (p->key.b==key.b && p->cachefile==cachefile) {
assert(p->rwlock.pinned>0); assert(p->rwlock.pinned>0);
ctpair_read_unlock(&p->rwlock); ctpair_read_unlock(&p->rwlock);
p->dirty |= dirty; p->dirty |= dirty;
...@@ -848,7 +849,7 @@ int toku_cachetable_rename (CACHEFILE cachefile, CACHEKEY oldkey, CACHEKEY newke ...@@ -848,7 +849,7 @@ int toku_cachetable_rename (CACHEFILE cachefile, CACHEKEY oldkey, CACHEKEY newke
p; p;
ptr_to_p = &p->hash_chain, p = *ptr_to_p) { ptr_to_p = &p->hash_chain, p = *ptr_to_p) {
count++; count++;
if (p->key==oldkey && p->cachefile==cachefile) { if (p->key.b==oldkey.b && p->cachefile==cachefile) {
note_hash_count(count); note_hash_count(count);
*ptr_to_p = p->hash_chain; *ptr_to_p = p->hash_chain;
p->key = newkey; p->key = newkey;
...@@ -1005,7 +1006,7 @@ int toku_cachetable_remove (CACHEFILE cachefile, CACHEKEY key, int write_me) { ...@@ -1005,7 +1006,7 @@ int toku_cachetable_remove (CACHEFILE cachefile, CACHEKEY key, int write_me) {
cachetable_lock(t); cachetable_lock(t);
for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) { for (p=t->table[fullhash&(t->table_size-1)]; p; p=p->hash_chain) {
count++; count++;
if (p->key==key && p->cachefile==cachefile) { if (p->key.b==key.b && p->cachefile==cachefile) {
flush_and_remove(t, p, write_me); flush_and_remove(t, p, write_me);
if ((4 * t->n_in_table < t->table_size) && (t->table_size>4)) if ((4 * t->n_in_table < t->table_size) && (t->table_size>4))
cachetable_rehash(t, t->table_size/2); cachetable_rehash(t, t->table_size/2);
...@@ -1156,7 +1157,7 @@ void toku_cachetable_print_state (CACHETABLE ct) { ...@@ -1156,7 +1157,7 @@ void toku_cachetable_print_state (CACHETABLE ct) {
if (p != 0) { if (p != 0) {
printf("t[%d]=", i); printf("t[%d]=", i);
for (p=ct->table[i]; p; p=p->hash_chain) { 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"); printf("\n");
} }
...@@ -1186,7 +1187,8 @@ int toku_cachetable_get_key_state (CACHETABLE ct, CACHEKEY key, CACHEFILE cf, vo ...@@ -1186,7 +1187,8 @@ int toku_cachetable_get_key_state (CACHETABLE ct, CACHEKEY key, CACHEFILE cf, vo
cachetable_lock(ct); cachetable_lock(ct);
for (p = ct->table[fullhash&(ct->table_size-1)]; p; p = p->hash_chain) { for (p = ct->table[fullhash&(ct->table_size-1)]; p; p = p->hash_chain) {
count++; count++;
if (p->key == key && p->cachefile == cf) { if (p->key.b == key.b && p->cachefile == cf) {
note_hash_count(count);
if (value_ptr) if (value_ptr)
*value_ptr = p->value; *value_ptr = p->value;
if (dirty_ptr) if (dirty_ptr)
......
...@@ -20,7 +20,7 @@ ...@@ -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) * 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 // create a new cachetable
// returns: if success, 0 is returned and result points to the new cachetable // returns: if success, 0 is returned and result points to the new cachetable
......
...@@ -116,6 +116,9 @@ static inline int toku_logsizeof_FILENUM (FILENUM v __attribute__((__unused__))) ...@@ -116,6 +116,9 @@ static inline int toku_logsizeof_FILENUM (FILENUM v __attribute__((__unused__)))
static inline int toku_logsizeof_DISKOFF (DISKOFF v __attribute__((__unused__))) { static inline int toku_logsizeof_DISKOFF (DISKOFF v __attribute__((__unused__))) {
return 8; return 8;
} }
static inline int toku_logsizeof_BLOCKNUM (BLOCKNUM v __attribute__((__unused__))) {
return 8;
}
static inline int toku_logsizeof_TXNID (TXNID txnid __attribute__((__unused__))) { static inline int toku_logsizeof_TXNID (TXNID txnid __attribute__((__unused__))) {
return 8; return 8;
......
...@@ -618,6 +618,10 @@ int toku_fread_DISKOFF (FILE *f, DISKOFF *diskoff, struct x1764 *checksum, u_int ...@@ -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. int r = toku_fread_u_int64_t (f, (u_int64_t*)diskoff, checksum, len); // sign conversion will be OK.
return r; 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) { 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); 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 ...@@ -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->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->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_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_BLOCKNUM (f, &v->free_blocks, 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->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; r = toku_fread_int32_t (f, &v->n_named_roots, checksum, len); if (r!=0) return r;
assert(v->n_named_roots==-1); 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; return 0;
} }
...@@ -740,11 +744,19 @@ int toku_logprint_DISKOFF (FILE *outf, FILE *inf, const char *fieldname, struct ...@@ -740,11 +744,19 @@ int toku_logprint_DISKOFF (FILE *outf, FILE *inf, const char *fieldname, struct
fprintf(outf, " %s=%lld", fieldname, v); fprintf(outf, " %s=%lld", fieldname, v);
return 0; 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__))) { 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; LOGGEDBRTHEADER v;
int r = toku_fread_LOGGEDBRTHEADER(inf, &v, checksum, len); int r = toku_fread_LOGGEDBRTHEADER(inf, &v, checksum, len);
if (r!=0) return r; 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; return 0;
} }
......
...@@ -57,6 +57,7 @@ int toku_fread_u_int32_t (FILE *f, u_int32_t *v, struct x1764 *, u_int32_t *len) ...@@ -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_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_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_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); int toku_fread_TXNID (FILE *f, TXNID *txnid, struct x1764 *, u_int32_t *len);
// fills in the bs with malloced data. // fills in the bs with malloced data.
int toku_fread_BYTESTRING (FILE *f, BYTESTRING *bs, struct x1764 *, u_int32_t *len); 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, ...@@ -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_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_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_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_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_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 *); int toku_logprint_LOGGEDBRTHEADER (FILE *outf, FILE *inf, const char *fieldname, struct x1764 *, u_int32_t *len, const char *);
......
...@@ -83,7 +83,7 @@ const struct logtype logtypes[] = { ...@@ -83,7 +83,7 @@ const struct logtype logtypes[] = {
{"xbegin", 'b', FA{{"TXNID", "parenttxnid", 0},NULLFIELD}}, {"xbegin", 'b', FA{{"TXNID", "parenttxnid", 0},NULLFIELD}},
#if 0 #if 0
{"tl_delete", 'D', FA{{"FILENUM", "filenum", 0}, // tl logentries can be used, by themselves, to rebuild the whole DB from scratch. {"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", "key", 0},
{"BYTESTRING", "data", 0}, {"BYTESTRING", "data", 0},
NULLFIELD}}, NULLFIELD}},
...@@ -97,46 +97,46 @@ const struct logtype logtypes[] = { ...@@ -97,46 +97,46 @@ const struct logtype logtypes[] = {
{"LOGGEDBRTHEADER", "header", 0}, {"LOGGEDBRTHEADER", "header", 0},
NULLFIELD}}, NULLFIELD}},
{"newbrtnode", 'N', FA{{"FILENUM", "filenum", 0}, {"newbrtnode", 'N', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "diskoff", 0}, {"BLOCKNUM", "blocknum", 0},
{"u_int32_t", "height", 0}, {"u_int32_t", "height", 0},
{"u_int32_t", "nodesize", 0}, {"u_int32_t", "nodesize", 0},
{"u_int8_t", "is_dup_sort", 0}, {"u_int8_t", "is_dup_sort", 0},
{"u_int32_t", "rand4fingerprint", "%08x"}, {"u_int32_t", "rand4fingerprint", "%08x"},
NULLFIELD}}, NULLFIELD}},
{"changeunnamedroot", 'u', FA{{"FILENUM", "filenum", 0}, {"changeunnamedroot", 'u', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "oldroot", 0}, {"BLOCKNUM", "oldroot", 0},
{"DISKOFF", "newroot", 0}, {"BLOCKNUM", "newroot", 0},
NULLFIELD}}, NULLFIELD}},
{"changenamedroot", 'n', FA{{"FILENUM", "filenum", 0}, {"changenamedroot", 'n', FA{{"FILENUM", "filenum", 0},
{"BYTESTRING", "name", 0}, {"BYTESTRING", "name", 0},
{"DISKOFF", "oldroot", 0}, {"BLOCKNUM", "oldroot", 0},
{"DISKOFF", "newroot", 0}, {"BLOCKNUM", "newroot", 0},
NULLFIELD}}, NULLFIELD}},
{"changeunusedmemory", 'm', FA{{"FILENUM", "filenum", 0}, {"changeunusedmemory", 'm', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "oldunused", 0}, {"BLOCKNUM", "oldunused", 0},
{"DISKOFF", "newunused", 0}, {"BLOCKNUM", "newunused", 0},
NULLFIELD}}, NULLFIELD}},
{"addchild", 'c', FA{{"FILENUM", "filenum", 0}, {"addchild", 'c', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "diskoff", 0}, {"BLOCKNUM", "blocknum", 0},
{"u_int32_t", "childnum", 0}, // children scoot over {"u_int32_t", "childnum", 0}, // children scoot over
{"DISKOFF", "child", 0}, {"BLOCKNUM", "child", 0},
{"u_int32_t", "childfingerprint", "%08x"}, {"u_int32_t", "childfingerprint", "%08x"},
NULLFIELD}}, NULLFIELD}},
{"delchild", 'r', FA{{"FILENUM", "filenum", 0}, {"delchild", 'r', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "diskoff", 0}, {"BLOCKNUM", "blocknum", 0},
{"u_int32_t", "childnum", 0}, // children scoot over {"u_int32_t", "childnum", 0}, // children scoot over
{"DISKOFF", "child", 0}, {"BLOCKNUM", "child", 0},
{"u_int32_t", "childfingerprint", "%08x"}, {"u_int32_t", "childfingerprint", "%08x"},
{"BYTESTRING", "pivotkey", 0}, {"BYTESTRING", "pivotkey", 0},
NULLFIELD}}, NULLFIELD}},
{"setchild", 'i', FA{{"FILENUM", "filenum", 0}, {"setchild", 'i', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "diskoff", 0}, {"BLOCKNUM", "blocknum", 0},
{"u_int32_t", "childnum", 0}, {"u_int32_t", "childnum", 0},
{"DISKOFF", "oldchild", 0}, {"BLOCKNUM", "oldchild", 0},
{"DISKOFF", "newchild", 0}, {"BLOCKNUM", "newchild", 0},
NULLFIELD}}, NULLFIELD}},
{"setpivot", 'k', FA{{"FILENUM", "filenum", 0}, {"setpivot", 'k', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "diskoff", 0}, {"BLOCKNUM", "blocknum", 0},
{"u_int32_t", "childnum", 0}, {"u_int32_t", "childnum", 0},
{"BYTESTRING", "pivotkey", 0}, {"BYTESTRING", "pivotkey", 0},
NULLFIELD}}, NULLFIELD}},
...@@ -152,11 +152,11 @@ const struct logtype logtypes[] = { ...@@ -152,11 +152,11 @@ const struct logtype logtypes[] = {
NULLFIELD}}, NULLFIELD}},
// Note that brtdeq and brtenq don't name the new size or fingerprint. We can calculate them properly. // Note that brtdeq and brtenq don't name the new size or fingerprint. We can calculate them properly.
{"brtdeq", 'U', FA{{"FILENUM", "filenum", 0}, {"brtdeq", 'U', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "diskoff", 0}, {"BLOCKNUM", "blocknum", 0},
{"u_int32_t", "childnum", 0}, {"u_int32_t", "childnum", 0},
NULLFIELD}}, NULLFIELD}},
{"brtenq", 'Q', FA{{"FILENUM", "filenum", 0}, {"brtenq", 'Q', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "diskoff", 0}, {"BLOCKNUM", "blocknum", 0},
{"u_int32_t", "childnum", 0}, {"u_int32_t", "childnum", 0},
{"TXNID", "xid", 0}, {"TXNID", "xid", 0},
{"u_int32_t", "typ", 0}, {"u_int32_t", "typ", 0},
...@@ -165,13 +165,13 @@ const struct logtype logtypes[] = { ...@@ -165,13 +165,13 @@ const struct logtype logtypes[] = {
NULLFIELD}}, NULLFIELD}},
// {"insertinleaf", 'I', FA{{"TXNID", "txnid", 0}, // {"insertinleaf", 'I', FA{{"TXNID", "txnid", 0},
// {"FILENUM", "filenum", 0}, // {"FILENUM", "filenum", 0},
// {"DISKOFF", "diskoff", 0}, // {"BLOCKNUM", "blocknum", 0},
// {"u_int32_t", "pmaidx", 0}, // {"u_int32_t", "pmaidx", 0},
// {"BYTESTRING", "key", 0}, // {"BYTESTRING", "key", 0},
// {"BYTESTRING", "data", 0}, // {"BYTESTRING", "data", 0},
// NULLFIELD}}, // NULLFIELD}},
// {"replaceleafentry", 'L', FA{{"FILENUM", "filenum", 0}, // {"replaceleafentry", 'L', FA{{"FILENUM", "filenum", 0},
// {"DISKOFF", "diskoff", 0}, // {"BLOCKNUM", "blocknum", 0},
// {"u_int32_t", "pmaidx", 0}, // {"u_int32_t", "pmaidx", 0},
// {"LEAFENTRY", "oldleafentry", 0}, // {"LEAFENTRY", "oldleafentry", 0},
// {"LEAFENTRY", "newleafentry", 0}, // {"LEAFENTRY", "newleafentry", 0},
...@@ -185,17 +185,17 @@ const struct logtype logtypes[] = { ...@@ -185,17 +185,17 @@ const struct logtype logtypes[] = {
{"deqrootentry", 'A', FA{{"FILENUM", "filenum", 0}, {"deqrootentry", 'A', FA{{"FILENUM", "filenum", 0},
NULLFIELD}}, NULLFIELD}},
{"insertleafentry", 'I', FA{{"FILENUM", "filenum", 0}, {"insertleafentry", 'I', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "diskoff", 0}, {"BLOCKNUM", "blocknum", 0},
{"u_int32_t", "idx", 0}, {"u_int32_t", "idx", 0},
{"LEAFENTRY", "newleafentry", 0}, {"LEAFENTRY", "newleafentry", 0},
NULLFIELD}}, NULLFIELD}},
{"deleteleafentry", 'D', FA{{"FILENUM", "filenum", 0}, {"deleteleafentry", 'D', FA{{"FILENUM", "filenum", 0},
{"DISKOFF", "diskoff", 0}, {"BLOCKNUM", "blocknum", 0},
{"u_int32_t", "idx", 0}, {"u_int32_t", "idx", 0},
NULLFIELD}}, NULLFIELD}},
{"leafsplit", 's', FA{{"FILENUM", "filenum", 0}, // log the creation of a new node by splitting stuff out of an old node {"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}, {"BLOCKNUM", "old_blocknum", 0},
{"DISKOFF", "new_diskoff", 0}, {"BLOCKNUM", "new_blocknum", 0},
{"u_int32_t", "old_n", 0}, {"u_int32_t", "old_n", 0},
{"u_int32_t", "split_at", 0}, {"u_int32_t", "split_at", 0},
{"u_int32_t", "new_nodesize", 0}, {"u_int32_t", "new_nodesize", 0},
......
...@@ -56,10 +56,17 @@ static inline unsigned long long rbuf_ulonglong (struct rbuf *r) { ...@@ -56,10 +56,17 @@ static inline unsigned long long rbuf_ulonglong (struct rbuf *r) {
return ((unsigned long long)(i0)<<32) | ((unsigned long long)(i1)); 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) { static inline DISKOFF rbuf_diskoff (struct rbuf *r) {
unsigned i0 = rbuf_int(r); return rbuf_ulonglong(r);
unsigned i1 = rbuf_int(r); }
return ((unsigned long long)(i0)<<32) | ((unsigned long long)(i1));
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) { static inline void rbuf_TXNID (struct rbuf *r, TXNID *txnid) {
......
...@@ -136,8 +136,8 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,L ...@@ -136,8 +136,8 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,L
h->dirty=0; h->dirty=0;
h->flags_array[0] = header.flags; h->flags_array[0] = header.flags;
h->nodesize = header.nodesize; h->nodesize = header.nodesize;
h->freelist = header.freelist; h->free_blocks = header.free_blocks;
h->unused_memory = header.unused_memory; h->unused_blocks = header.unused_blocks;
h->n_named_roots = header.n_named_roots; h->n_named_roots = header.n_named_roots;
r=toku_fifo_create(&h->fifo); r=toku_fifo_create(&h->fifo);
assert(r==0); assert(r==0);
...@@ -149,9 +149,9 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,L ...@@ -149,9 +149,9 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,L
} else { } else {
assert(0); 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; 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) { if (pair->brt) {
toku_free(pair->brt->h); toku_free(pair->brt->h);
} else { } else {
...@@ -172,17 +172,17 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,L ...@@ -172,17 +172,17 @@ static void toku_recover_fheader (LSN UU(lsn), TXNID UU(txnid),FILENUM filenum,L
assert(r==0); 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; int r;
struct cf_pair *pair = NULL; struct cf_pair *pair = NULL;
r = find_cachefile(filenum, &pair); r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
TAGMALLOC(BRTNODE, n); TAGMALLOC(BRTNODE, n);
n->nodesize = nodesize; n->nodesize = nodesize;
n->thisnodename = diskoff; n->thisnodename = blocknum;
n->log_lsn = n->disk_lsn = lsn; n->log_lsn = n->disk_lsn = lsn;
//printf("%s:%d %p->disk_lsn=%"PRId64"\n", __FILE__, __LINE__, n, 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->height = height;
n->rand4fingerprint = rand4fingerprint; n->rand4fingerprint = rand4fingerprint;
n->flags = is_dup_sort ? TOKU_DB_DUPSORT : 0; // Don't have TOKU_DB_DUP ??? 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 ...@@ -207,25 +207,25 @@ void toku_recover_newbrtnode (LSN lsn, FILENUM filenum,DISKOFF diskoff,u_int32_t
MALLOC_N(2,n->u.n.childkeys); MALLOC_N(2,n->u.n.childkeys);
} }
// Now put it in the cachetable // 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; 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); VERIFY_COUNTS(n);
n->log_lsn = lsn; 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); 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
assert(pair->brt); assert(pair->brt);
void *node_v; void *node_v;
u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum);
r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, r = toku_cachetable_get_and_pin(pair->cf, blocknum, fullhash,
&node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt);
assert(r==0); assert(r==0);
BRTNODE node = node_v; BRTNODE node = node_v;
...@@ -239,8 +239,8 @@ static void toku_recover_deqrootentry (LSN lsn __attribute__((__unused__)), FILE ...@@ -239,8 +239,8 @@ static void toku_recover_deqrootentry (LSN lsn __attribute__((__unused__)), FILE
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
void *h_v; void *h_v;
u_int32_t fullhash = toku_cachetable_hash(pair->cf, 0); u_int32_t fullhash = toku_cachetable_hash(pair->cf, header_blocknum);
r = toku_cachetable_get_and_pin(pair->cf, 0, fullhash, r = toku_cachetable_get_and_pin(pair->cf, header_blocknum, fullhash,
&h_v, NULL, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0); &h_v, NULL, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0);
assert(r==0); assert(r==0);
struct brt_header *h=h_v; struct brt_header *h=h_v;
...@@ -252,7 +252,7 @@ static void toku_recover_deqrootentry (LSN lsn __attribute__((__unused__)), FILE ...@@ -252,7 +252,7 @@ static void toku_recover_deqrootentry (LSN lsn __attribute__((__unused__)), FILE
assert(r==0); assert(r==0);
r = toku_fifo_deq(h->fifo); r = toku_fifo_deq(h->fifo);
assert(r==0); 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); assert(r==0);
} }
...@@ -261,23 +261,23 @@ void toku_recover_enqrootentry (LSN lsn __attribute__((__unused__)), FILENUM fil ...@@ -261,23 +261,23 @@ void toku_recover_enqrootentry (LSN lsn __attribute__((__unused__)), FILENUM fil
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
void *h_v; void *h_v;
u_int32_t fullhash = toku_cachetable_hash(pair->cf, 0); u_int32_t fullhash = toku_cachetable_hash(pair->cf, header_blocknum);
r = toku_cachetable_get_and_pin(pair->cf, 0, fullhash, &h_v, NULL, toku_brtheader_flush_callback, toku_brtheader_fetch_callback, 0); 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); assert(r==0);
struct brt_header *h=h_v; struct brt_header *h=h_v;
r = toku_fifo_enq(h->fifo, key.data, key.len, val.data, val.len, typ, xid); r = toku_fifo_enq(h->fifo, key.data, key.len, val.data, val.len, typ, xid);
assert(r==0); 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); assert(r==0);
toku_free(key.data); toku_free(key.data);
toku_free(val.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; CACHEFILE cf;
BRTNODE node; BRTNODE node;
int r; int r;
recover_setup_node(filenum, diskoff, &cf, &node); recover_setup_node(filenum, blocknum, &cf, &node);
assert(node->height>0); assert(node->height>0);
//printf("deq: %lld expected_old_fingerprint=%08x actual=%08x new=%08x\n", diskoff, oldfingerprint, node->local_fingerprint, newfingerprint); //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; 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 ...@@ -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; node->u.n.n_bytes_in_buffers -= sizediff;
BNC_NBYTESINBUF(node, childnum) -= 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_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); 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; CACHEFILE cf;
BRTNODE node; BRTNODE node;
int r; int r;
recover_setup_node(filenum, diskoff, &cf, &node); recover_setup_node(filenum, blocknum, &cf, &node);
assert(node->height>0); 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); r = toku_fifo_enq(BNC_BUFFER(node, childnum), key.data, key.len, data.data, data.len, typ, xid);
assert(r==0); assert(r==0);
node->local_fingerprint += node->rand4fingerprint * toku_calc_fingerprint_cmd(typ, xid, key.data, key.len, data.data, data.len); node->local_fingerprint += node->rand4fingerprint * toku_calc_fingerprint_cmd(typ, xid, key.data, key.len, data.data, data.len);
node->log_lsn = lsn; node->log_lsn = lsn;
u_int32_t sizediff = key.len + data.len + KEY_VALUE_OVERHEAD + BRT_CMD_OVERHEAD; 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); assert(r==0);
node->u.n.n_bytes_in_buffers += sizediff; node->u.n.n_bytes_in_buffers += sizediff;
BNC_NBYTESINBUF(node, childnum) += sizediff; BNC_NBYTESINBUF(node, childnum) += sizediff;
...@@ -317,10 +317,10 @@ void toku_recover_brtenq (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t c ...@@ -317,10 +317,10 @@ void toku_recover_brtenq (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t c
toku_free(data.data); 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; CACHEFILE cf;
BRTNODE node; BRTNODE node;
recover_setup_node(filenum, diskoff, &cf, &node); recover_setup_node(filenum, blocknum, &cf, &node);
assert(node->height>0); assert(node->height>0);
assert(childnum <= (unsigned)node->u.n.n_children); assert(childnum <= (unsigned)node->u.n.n_children);
unsigned int i; unsigned int i;
...@@ -335,25 +335,25 @@ void toku_recover_addchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t ...@@ -335,25 +335,25 @@ void toku_recover_addchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t
if (childnum>0) { if (childnum>0) {
node->u.n.childkeys [childnum-1] = 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_FINGERPRINT(node, childnum) = childfingerprint;
BNC_SUBTREE_LEAFENTRY_ESTIMATE(node, childnum) = 0; BNC_SUBTREE_LEAFENTRY_ESTIMATE(node, childnum) = 0;
int r= toku_fifo_create(&BNC_BUFFER(node, childnum)); assert(r==0); int r= toku_fifo_create(&BNC_BUFFER(node, childnum)); assert(r==0);
BNC_NBYTESINBUF(node, childnum) = 0; BNC_NBYTESINBUF(node, childnum) = 0;
node->u.n.n_children++; node->u.n.n_children++;
node->log_lsn = lsn; 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); 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
void *node_v; void *node_v;
assert(pair->brt); assert(pair->brt);
u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum);
r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); 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); assert(r==0);
BRTNODE node = node_v; BRTNODE node = node_v;
assert(node->height>0); assert(node->height>0);
...@@ -361,7 +361,7 @@ void toku_recover_delchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t ...@@ -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(childnum < (unsigned)node->u.n.n_children);
assert(node->u.n.childinfos[childnum].subtree_fingerprint == childfingerprint); 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(toku_fifo_n_entries(BNC_BUFFER(node,childnum))==0);
assert(BNC_NBYTESINBUF(node,childnum)==0); assert(BNC_NBYTESINBUF(node,childnum)==0);
assert(node->u.n.n_children>2); // Must be at least two children. 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 ...@@ -378,37 +378,37 @@ void toku_recover_delchild (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t
node->u.n.n_children--; node->u.n.n_children--;
node->log_lsn = lsn; 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); assert(r==0);
toku_free(pivotkey.data); 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
void *node_v; void *node_v;
assert(pair->brt); assert(pair->brt);
u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum);
r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); 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); assert(r==0);
BRTNODE node = node_v; BRTNODE node = node_v;
assert(node->fullhash == fullhash); assert(node->fullhash == fullhash);
assert(node->height>0); assert(node->height>0);
assert(childnum < (unsigned)node->u.n.n_children); assert(childnum < (unsigned)node->u.n.n_children);
BNC_DISKOFF(node, childnum) = newchild; BNC_BLOCKNUM(node, childnum) = newchild;
node->log_lsn = lsn; 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); 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
void *node_v; void *node_v;
assert(pair->brt); assert(pair->brt);
u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum);
r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); 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); assert(r==0);
BRTNODE node = node_v; BRTNODE node = node_v;
assert(node->fullhash==fullhash); assert(node->fullhash==fullhash);
...@@ -420,20 +420,20 @@ void toku_recover_setpivot (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_int32_t ...@@ -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->u.n.totalchildkeylens += toku_brt_pivot_key_len(pair->brt, node->u.n.childkeys[childnum]);
node->log_lsn = lsn; 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); assert(r==0);
toku_free(pivotkey.data); 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
void *node_v; void *node_v;
assert(pair->brt); assert(pair->brt);
u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum);
r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); 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); assert(r==0);
BRTNODE node = node_v; BRTNODE node = node_v;
assert(node->fullhash == fullhash); assert(node->fullhash == fullhash);
...@@ -441,7 +441,7 @@ void toku_recover_changechildfingerprint (LSN lsn, FILENUM filenum, DISKOFF disk ...@@ -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. assert((signed)childnum <= node->u.n.n_children); // we allow the childnum to be one too large.
BNC_SUBTREE_FINGERPRINT(node, childnum) = newfingerprint; BNC_SUBTREE_FINGERPRINT(node, childnum) = newfingerprint;
node->log_lsn = lsn; 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); assert(r==0);
} }
...@@ -503,13 +503,13 @@ static int fill_buf (OMTVALUE lev, u_int32_t idx, void *varray) { ...@@ -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. // 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
void *nodeA_v; void *nodeA_v;
assert(pair->brt); assert(pair->brt);
u_int32_t oldn_fullhash = toku_cachetable_hash(pair->cf, old_diskoff); u_int32_t oldn_fullhash = toku_cachetable_hash(pair->cf, old_blocknum);
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); 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); assert(r==0);
BRTNODE oldn = nodeA_v; BRTNODE oldn = nodeA_v;
assert(oldn->fullhash==oldn_fullhash); assert(oldn->fullhash==oldn_fullhash);
...@@ -517,14 +517,14 @@ void toku_recover_leafsplit (LSN lsn, FILENUM filenum, DISKOFF old_diskoff, DISK ...@@ -517,14 +517,14 @@ void toku_recover_leafsplit (LSN lsn, FILENUM filenum, DISKOFF old_diskoff, DISK
TAGMALLOC(BRTNODE, newn); TAGMALLOC(BRTNODE, newn);
assert(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->nodesize = new_node_size;
newn->thisnodename = new_diskoff; newn->thisnodename = new_blocknum;
newn->log_lsn = newn->disk_lsn = lsn; newn->log_lsn = newn->disk_lsn = lsn;
//printf("%s:%d %p->disk_lsn=%"PRId64"\n", __FILE__, __LINE__, n, n->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->height = 0;
newn->rand4fingerprint = new_rand4; newn->rand4fingerprint = new_rand4;
newn->flags = is_dup_sort ? TOKU_DB_DUPSORT : 0; // Don't have TOKU_DB_DUP ??? 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 ...@@ -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(oldn); toku_verify_counts(oldn);
toku_verify_all_in_mempool(newn); toku_verify_counts(newn); 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, toku_serialize_brtnode_size(newn), toku_brtnode_flush_callback, toku_brtnode_fetch_callback, 0);
newn->log_lsn = lsn; 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); assert(r==0);
oldn->log_lsn = lsn; 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); 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
void *node_v; void *node_v;
assert(pair->brt); assert(pair->brt);
u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum);
r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); 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); assert(r==0);
BRTNODE node = node_v; BRTNODE node = node_v;
assert(node->fullhash==fullhash); assert(node->fullhash==fullhash);
...@@ -614,19 +614,19 @@ void toku_recover_insertleafentry (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_ ...@@ -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->u.l.n_bytes_in_buffer += OMT_ITEM_OVERHEAD + leafentry_disksize(newleafentry);
node->local_fingerprint += node->rand4fingerprint * toku_le_crc(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); assert(r==0);
toku_free_LEAFENTRY(newleafentry); 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
void *node_v; void *node_v;
assert(pair->brt); assert(pair->brt);
u_int32_t fullhash = toku_cachetable_hash(pair->cf, diskoff); u_int32_t fullhash = toku_cachetable_hash(pair->cf, blocknum);
r = toku_cachetable_get_and_pin(pair->cf, diskoff, fullhash, &node_v, NULL, toku_brtnode_flush_callback, toku_brtnode_fetch_callback, pair->brt); 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); assert(r==0);
BRTNODE node = node_v; BRTNODE node = node_v;
assert(node->fullhash==fullhash); assert(node->fullhash==fullhash);
...@@ -646,11 +646,11 @@ void toku_recover_deleteleafentry (LSN lsn, FILENUM filenum, DISKOFF diskoff, u_ ...@@ -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); r = toku_omt_delete_at(node->u.l.buffer, idx);
assert(r==0); 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); 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
...@@ -661,16 +661,16 @@ void toku_recover_changeunnamedroot (LSN UU(lsn), FILENUM filenum, DISKOFF UU(ol ...@@ -661,16 +661,16 @@ void toku_recover_changeunnamedroot (LSN UU(lsn), FILENUM filenum, DISKOFF UU(ol
pair->brt->h->root_hashes[0].valid = FALSE; pair->brt->h->root_hashes[0].valid = FALSE;
r = toku_unpin_brt_header(pair->brt); 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; struct cf_pair *pair = NULL;
int r = find_cachefile(filenum, &pair); int r = find_cachefile(filenum, &pair);
assert(r==0); assert(r==0);
assert(pair->brt); assert(pair->brt);
r = toku_read_and_pin_brt_header(pair->cf, &pair->brt->h); r = toku_read_and_pin_brt_header(pair->cf, &pair->brt->h);
assert(r==0); assert(r==0);
pair->brt->h->unused_memory = newunused; pair->brt->h->unused_blocks = newunused;
r = toku_unpin_brt_header(pair->brt); r = toku_unpin_brt_header(pair->brt);
} }
......
...@@ -25,7 +25,7 @@ static void test_serialize(void) { ...@@ -25,7 +25,7 @@ static void test_serialize(void) {
sn.nodesize = nodesize; sn.nodesize = nodesize;
sn.ever_been_written = 0; sn.ever_been_written = 0;
sn.flags = 0x11223344; sn.flags = 0x11223344;
sn.thisnodename = sn.nodesize*20; sn.thisnodename.b = 20;
sn.disk_lsn.lsn = 789; sn.disk_lsn.lsn = 789;
sn.log_lsn.lsn = 123456; sn.log_lsn.lsn = 123456;
sn.layout_version = BRT_LAYOUT_VERSION; sn.layout_version = BRT_LAYOUT_VERSION;
...@@ -38,8 +38,8 @@ static void test_serialize(void) { ...@@ -38,8 +38,8 @@ static void test_serialize(void) {
MALLOC_N(1, sn.u.n.childkeys); MALLOC_N(1, sn.u.n.childkeys);
sn.u.n.childkeys[0] = kv_pair_malloc(hello_string, 6, 0, 0); sn.u.n.childkeys[0] = kv_pair_malloc(hello_string, 6, 0, 0);
sn.u.n.totalchildkeylens = 6; sn.u.n.totalchildkeylens = 6;
BNC_DISKOFF(&sn, 0) = sn.nodesize*30; BNC_BLOCKNUM(&sn, 0).b = 30;
BNC_DISKOFF(&sn, 1) = sn.nodesize*35; BNC_BLOCKNUM(&sn, 1).b = 35;
BNC_SUBTREE_FINGERPRINT(&sn, 0) = random(); BNC_SUBTREE_FINGERPRINT(&sn, 0) = random();
BNC_SUBTREE_FINGERPRINT(&sn, 1) = random(); BNC_SUBTREE_FINGERPRINT(&sn, 1) = random();
BNC_SUBTREE_LEAFENTRY_ESTIMATE(&sn, 0) = random() + (((long long)random())<<32); BNC_SUBTREE_LEAFENTRY_ESTIMATE(&sn, 0) = random() + (((long long)random())<<32);
...@@ -53,12 +53,13 @@ static void test_serialize(void) { ...@@ -53,12 +53,13 @@ static void test_serialize(void) {
BNC_NBYTESINBUF(&sn, 1) = 1*(BRT_CMD_OVERHEAD+KEY_VALUE_OVERHEAD+2+5); 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); 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); toku_serialize_brtnode_to(fd, make_blocknum(20), &sn); assert(r==0);
r = toku_deserialize_brtnode_from(fd, nodesize*(DISKOFF)20, 0/*pass zero for hash*/, &dn); r = toku_deserialize_brtnode_from(fd, make_blocknum(20), 0/*pass zero for hash*/, &dn, nodesize);
assert(r==0); assert(r==0);
assert(dn->thisnodename==nodesize*20); assert(dn->thisnodename.b==20);
assert(dn->disk_lsn.lsn==123456); assert(dn->disk_lsn.lsn==123456);
assert(dn->layout_version ==BRT_LAYOUT_VERSION); assert(dn->layout_version ==BRT_LAYOUT_VERSION);
assert(dn->height == 1); assert(dn->height == 1);
...@@ -67,8 +68,8 @@ static void test_serialize(void) { ...@@ -67,8 +68,8 @@ static void test_serialize(void) {
assert(strcmp(kv_pair_key(dn->u.n.childkeys[0]), "hello")==0); 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(toku_brtnode_pivot_key_len(dn, dn->u.n.childkeys[0])==6);
assert(dn->u.n.totalchildkeylens==6); assert(dn->u.n.totalchildkeylens==6);
assert(BNC_DISKOFF(dn,0)==nodesize*30); assert(BNC_BLOCKNUM(dn,0).b==30);
assert(BNC_DISKOFF(dn,1)==nodesize*35); assert(BNC_BLOCKNUM(dn,1).b==35);
{ {
int i; int i;
for (i=0; i<2; i++) { for (i=0; i<2; i++) {
......
...@@ -25,24 +25,24 @@ void cachetable_count_pinned_test(int n) { ...@@ -25,24 +25,24 @@ void cachetable_count_pinned_test(int n) {
int i; int i;
for (i=1; i<=n; i++) { for (i=1; i<=n; i++) {
u_int32_t hi; u_int32_t hi;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(i));
r = toku_cachetable_put(f1, i, hi, (void *)(long)i, 1, flush, fetch, 0); r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, 1, flush, fetch, 0);
assert(r == 0); assert(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
void *v; 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(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); 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(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
} }
for (i=n; i>0; i--) { for (i=n; i>0; i--) {
u_int32_t hi; u_int32_t hi;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(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(r == 0);
if (i-1) assert(toku_cachetable_assert_all_unpinned(ct)); if (i-1) assert(toku_cachetable_assert_all_unpinned(ct));
assert(toku_cachefile_count_pinned(f1, 0) == i-1); assert(toku_cachefile_count_pinned(f1, 0) == i-1);
......
...@@ -33,19 +33,19 @@ void cachetable_debug_test(int n) { ...@@ -33,19 +33,19 @@ void cachetable_debug_test(int n) {
for (i=1; i<=n; i++) { for (i=1; i<=n; i++) {
const int item_size = 1; const int item_size = 1;
u_int32_t hi; u_int32_t hi;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(i));
r = toku_cachetable_put(f1, i, hi, (void *)(long)i, item_size, flush, fetch, 0); r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, item_size, flush, fetch, 0);
assert(r == 0); assert(r == 0);
void *v; int dirty; long long pinned; long pair_size; 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(r == 0);
assert(v == (void *)(long)i); assert(v == (void *)(long)i);
assert(dirty == CACHETABLE_DIRTY); assert(dirty == CACHETABLE_DIRTY);
assert(pinned == 1); assert(pinned == 1);
assert(pair_size == item_size); 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); assert(r == 0);
toku_cachetable_get_state(ct, &num_entries, &hash_size, &size_current, &size_limit); toku_cachetable_get_state(ct, &num_entries, &hash_size, &size_current, &size_limit);
......
...@@ -31,15 +31,15 @@ void test_cachetable_flush(int n) { ...@@ -31,15 +31,15 @@ void test_cachetable_flush(int n) {
int i; int i;
for (i=0; i<n; i++) { for (i=0; i<n; i++) {
u_int32_t hi; u_int32_t hi;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(i));
r = toku_cachetable_put(f1, i, hi, (void *)(long)i, 1, flush, fetch, 0); r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, 1, flush, fetch, 0);
assert(r == 0); assert(r == 0);
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(r == 0);
hi = toku_cachetable_hash(f2, i); hi = toku_cachetable_hash(f2, make_blocknum(i));
r = toku_cachetable_put(f2, i, hi, (void *)(long)i, 1, flush, fetch, 0); r = toku_cachetable_put(f2, make_blocknum(i), hi, (void *)(long)i, 1, flush, fetch, 0);
assert(r == 0); assert(r == 0);
r = toku_cachetable_unpin(f2, i, hi, CACHETABLE_CLEAN, 1); r = toku_cachetable_unpin(f2, make_blocknum(i), hi, CACHETABLE_CLEAN, 1);
assert(r == 0); assert(r == 0);
} }
toku_cachetable_verify(ct); toku_cachetable_verify(ct);
...@@ -48,15 +48,15 @@ void test_cachetable_flush(int n) { ...@@ -48,15 +48,15 @@ void test_cachetable_flush(int n) {
for (i=0; i<n; i++) { for (i=0; i<n; i++) {
u_int32_t hi; u_int32_t hi;
void *v; void *v;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(i));
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 && v == (void *)(long)i); assert(r == 0 && v == (void *)(long)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(r == 0);
hi = toku_cachetable_hash(f2, i); hi = toku_cachetable_hash(f2, make_blocknum(i));
r = toku_cachetable_maybe_get_and_pin(f2, i, hi, &v); r = toku_cachetable_maybe_get_and_pin(f2, make_blocknum(i), hi, &v);
assert(r == 0 && v == (void *)(long)i); assert(r == 0 && v == (void *)(long)i);
r = toku_cachetable_unpin(f2, i, hi, CACHETABLE_CLEAN, 1); r = toku_cachetable_unpin(f2, make_blocknum(i), hi, CACHETABLE_CLEAN, 1);
assert(r == 0); assert(r == 0);
} }
...@@ -68,13 +68,13 @@ void test_cachetable_flush(int n) { ...@@ -68,13 +68,13 @@ void test_cachetable_flush(int n) {
for (i=0; i<n; i++) { for (i=0; i<n; i++) {
u_int32_t hi; u_int32_t hi;
void *v; void *v;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(i));
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(r != 0);
hi = toku_cachetable_hash(f2, i); hi = toku_cachetable_hash(f2, make_blocknum(i));
r = toku_cachetable_maybe_get_and_pin(f2, i, hi, &v); r = toku_cachetable_maybe_get_and_pin(f2, make_blocknum(i), hi, &v);
assert(r == 0); assert(r == 0);
r = toku_cachetable_unpin(f2, i, hi, CACHETABLE_CLEAN, 1); r = toku_cachetable_unpin(f2, make_blocknum(i), hi, CACHETABLE_CLEAN, 1);
assert(r == 0); assert(r == 0);
} }
......
...@@ -25,41 +25,41 @@ void cachetable_put_test(int n) { ...@@ -25,41 +25,41 @@ void cachetable_put_test(int n) {
int i; int i;
for (i=1; i<=n; i++) { for (i=1; i<=n; i++) {
u_int32_t hi; u_int32_t hi;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(i));
r = toku_cachetable_put(f1, i, hi, (void *)(long)i, 1, flush, fetch, 0); r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, 1, flush, fetch, 0);
assert(r == 0); assert(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
r = toku_cachetable_put(f1, i, hi, (void *)(long)i, 1, flush, fetch, 0); r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, 1, flush, fetch, 0);
assert(r == -1); assert(r == -1);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
// the second put returns an error put increments the pin count, so we have // the second put returns an error put increments the pin count, so we have
// to unpin it here // to unpin it here
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(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
void *v; 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(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); 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(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
} }
for (i=n; i>0; i--) { for (i=n; i>0; i--) {
u_int32_t hi; u_int32_t hi;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(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(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i-1); assert(toku_cachefile_count_pinned(f1, 0) == i-1);
} }
assert(toku_cachefile_count_pinned(f1, 1) == 0); assert(toku_cachefile_count_pinned(f1, 1) == 0);
toku_cachetable_verify(ct); 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); r = toku_cachetable_unpin(f1, k, toku_cachetable_hash(f1, k), CACHETABLE_CLEAN, 1);
assert(r != 0); assert(r != 0);
......
...@@ -55,10 +55,10 @@ static void r_flush (CACHEFILE f __attribute__((__unused__)), ...@@ -55,10 +55,10 @@ static void r_flush (CACHEFILE f __attribute__((__unused__)),
test_mutex_lock(); test_mutex_lock();
for (i=0; i<n_keys; i++) { for (i=0; i<n_keys; i++) {
if (keys[i]==k) { if (keys[i].b==k.b) {
assert(vals[i]==value); assert(vals[i]==value);
if (!keep_me) { if (!keep_me) {
if (verbose) printf("%s: %d/%d %llx\n", __FUNCTION__, i, n_keys, k); if (verbose) printf("%s: %d/%d %" PRIx64 "\n", __FUNCTION__, i, n_keys, k.b);
keys[i]=keys[n_keys-1]; keys[i]=keys[n_keys-1];
vals[i]=vals[n_keys-1]; vals[i]=vals[n_keys-1];
n_keys--; n_keys--;
...@@ -98,9 +98,9 @@ static void test_rename (void) { ...@@ -98,9 +98,9 @@ static void test_rename (void) {
int ra = random()%3; int ra = random()%3;
if (ra<=1) { if (ra<=1) {
// Insert something // Insert something
CACHEKEY nkey = random(); CACHEKEY nkey = make_blocknum(random());
long nval = random(); long nval = random();
if (verbose) printf("n_keys=%d Insert %08llx\n", n_keys, nkey); if (verbose) printf("n_keys=%d Insert %08" PRIx64 "\n", n_keys, nkey.b);
u_int32_t hnkey = toku_cachetable_hash(f, nkey); u_int32_t hnkey = toku_cachetable_hash(f, nkey);
r = toku_cachetable_put(f, nkey, hnkey, r = toku_cachetable_put(f, nkey, hnkey,
(void*)nval, 1, (void*)nval, 1,
...@@ -122,13 +122,13 @@ static void test_rename (void) { ...@@ -122,13 +122,13 @@ static void test_rename (void) {
} else if (ra==2 && n_keys>0) { } else if (ra==2 && n_keys>0) {
// Rename something // Rename something
int objnum = random()%n_keys; int objnum = random()%n_keys;
CACHEKEY nkey = random(); CACHEKEY nkey = make_blocknum(random());
test_mutex_lock(); test_mutex_lock();
CACHEKEY okey = keys[objnum]; CACHEKEY okey = keys[objnum];
test_mutex_unlock(); test_mutex_unlock();
void *current_value; void *current_value;
long current_size; 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), &current_value, &current_size, r_flush, r_fetch, 0); r = toku_cachetable_get_and_pin(f, okey, toku_cachetable_hash(f, okey), &current_value, &current_size, r_flush, r_fetch, 0);
if (r == -42) continue; if (r == -42) continue;
assert(r==0); assert(r==0);
...@@ -139,7 +139,7 @@ static void test_rename (void) { ...@@ -139,7 +139,7 @@ static void test_rename (void) {
// get_and_pin may reorganize the keys[], so we need to find it again // get_and_pin may reorganize the keys[], so we need to find it again
int j; int j;
for (j=0; j < n_keys; j++) for (j=0; j < n_keys; j++)
if (keys[j] == okey) if (keys[j].b == okey.b)
break; break;
assert(j < n_keys); assert(j < n_keys);
keys[j]=nkey; keys[j]=nkey;
...@@ -151,7 +151,7 @@ static void test_rename (void) { ...@@ -151,7 +151,7 @@ static void test_rename (void) {
// test rename fails if old key does not exist in the cachetable // test rename fails if old key does not exist in the cachetable
CACHEKEY okey, nkey; CACHEKEY okey, nkey;
while (1) { while (1) {
okey = random(); okey = make_blocknum(random());
void *v; void *v;
r = toku_cachetable_maybe_get_and_pin(f, okey, toku_cachetable_hash(f, okey), &v); r = toku_cachetable_maybe_get_and_pin(f, okey, toku_cachetable_hash(f, okey), &v);
if (r != 0) if (r != 0)
...@@ -159,7 +159,7 @@ static void test_rename (void) { ...@@ -159,7 +159,7 @@ static void test_rename (void) {
r = toku_cachetable_unpin(f, okey, toku_cachetable_hash(f, okey), CACHETABLE_CLEAN, 1); r = toku_cachetable_unpin(f, okey, toku_cachetable_hash(f, okey), CACHETABLE_CLEAN, 1);
assert(r == 0); assert(r == 0);
} }
nkey = random(); nkey = make_blocknum(random());
r = toku_cachetable_rename(f, okey, nkey); r = toku_cachetable_rename(f, okey, nkey);
assert(r != 0); assert(r != 0);
......
...@@ -26,7 +26,7 @@ static void f_flush (CACHEFILE f, ...@@ -26,7 +26,7 @@ static void f_flush (CACHEFILE f,
BOOL rename_p __attribute__((__unused__))) { BOOL rename_p __attribute__((__unused__))) {
assert(size==BLOCKSIZE); assert(size==BLOCKSIZE);
if (write_me) { 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); assert(r==BLOCKSIZE);
} }
if (!keep_me) { if (!keep_me) {
...@@ -42,7 +42,7 @@ static int f_fetch (CACHEFILE f, ...@@ -42,7 +42,7 @@ static int f_fetch (CACHEFILE f,
void*extraargs __attribute__((__unused__)), void*extraargs __attribute__((__unused__)),
LSN *modified_lsn __attribute__((__unused__))) { LSN *modified_lsn __attribute__((__unused__))) {
void *buf = malloc(BLOCKSIZE); 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); assert(r==BLOCKSIZE);
*value = buf; *value = buf;
*sizep = BLOCKSIZE; *sizep = BLOCKSIZE;
...@@ -66,7 +66,7 @@ static void writeit (void) { ...@@ -66,7 +66,7 @@ static void writeit (void) {
int i, r; int i, r;
for (i=0; i<N; i++) { for (i=0; i<N; i++) {
void *buf = malloc(BLOCKSIZE); void *buf = malloc(BLOCKSIZE);
CACHEKEY key = i*BLOCKSIZE; CACHEKEY key = make_blocknum(i*BLOCKSIZE);
u_int32_t fullhash = toku_cachetable_hash(f, key); u_int32_t fullhash = toku_cachetable_hash(f, key);
int j; int j;
for (j=0; j<BLOCKSIZE; j++) ((char*)buf)[j]=(i+j)%256; for (j=0; j<BLOCKSIZE; j++) ((char*)buf)[j]=(i+j)%256;
...@@ -86,9 +86,8 @@ static void readit (void) { ...@@ -86,9 +86,8 @@ static void readit (void) {
int i, r; int i, r;
void *block; void *block;
long current_size; long current_size;
CACHEKEY key;
for (i=0; i<N; i++) { for (i=0; i<N; i++) {
key = i*BLOCKSIZE; CACHEKEY key = make_blocknum(i*BLOCKSIZE);
u_int32_t fullhash = toku_cachetable_hash(f, key); u_int32_t fullhash = toku_cachetable_hash(f, key);
r=toku_cachetable_get_and_pin(f, key, fullhash, &block, &current_size, f_flush, f_fetch, 0); assert(r==0); r=toku_cachetable_get_and_pin(f, key, fullhash, &block, &current_size, f_flush, f_fetch, 0); assert(r==0);
r=toku_cachetable_unpin(f, key, fullhash, 0, BLOCKSIZE); assert(r==0); r=toku_cachetable_unpin(f, key, fullhash, 0, BLOCKSIZE); assert(r==0);
......
/* -*- mode: C; c-basic-offset: 4 -*- */ /* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include <inttypes.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
...@@ -81,14 +82,14 @@ struct item { ...@@ -81,14 +82,14 @@ struct item {
static volatile int expect_n_flushes=0; static volatile int expect_n_flushes=0;
static volatile CACHEKEY flushes[100]; static volatile CACHEKEY flushes[100];
static void expect1(CACHEKEY key) { static void expect1(int64_t blocknum_n) {
expect_n_flushes=1; expect_n_flushes=1;
flushes[0]=key; flushes[0].b=blocknum_n;
if (verbose) printf("%s:%d %lld\n", __FUNCTION__, 0, key); //if (verbose) printf("%s:%d %lld\n", __FUNCTION__, 0, key.b);
} }
static void expectN(CACHEKEY key) { static void expectN(int64_t blocknum_n) {
if (verbose) printf("%s:%d %lld\n", __FUNCTION__, expect_n_flushes, key); //if (verbose) printf("%s:%d %lld\n", __FUNCTION__, expect_n_flushes, key);
flushes[expect_n_flushes++]=key; flushes[expect_n_flushes++].b=blocknum_n;
} }
static CACHEFILE expect_f; static CACHEFILE expect_f;
...@@ -99,39 +100,39 @@ static void flush (CACHEFILE f, CACHEKEY key, void*value, long size __attribute_ ...@@ -99,39 +100,39 @@ static void flush (CACHEFILE f, CACHEKEY key, void*value, long size __attribute_
if (keep_me) return; 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(expect_f==f);
assert(strcmp(it->something,"something")==0); assert(strcmp(it->something,"something")==0);
assert(it->key==key); assert(it->key.b==key.b);
/* Verify that we expected the flush. */ /* Verify that we expected the flush. */
for (i=0; i<expect_n_flushes; i++) { for (i=0; i<expect_n_flushes; i++) {
if (key==flushes[i]) { if (key.b==flushes[i].b) {
flushes[i] = flushes[expect_n_flushes-1]; flushes[i] = flushes[expect_n_flushes-1];
expect_n_flushes--; expect_n_flushes--;
goto found_flush; goto found_flush;
} }
} }
fprintf(stderr, "%lld was flushed, but I didn't expect it\n", key); fprintf(stderr, "%" PRId64 " was flushed, but I didn't expect it\n", key.b);
abort(); abort();
found_flush: found_flush:
toku_free(value); toku_free(value);
} }
static struct item *make_item (CACHEKEY key) { static struct item *make_item (u_int64_t key) {
struct item *MALLOC(it); struct item *MALLOC(it);
it->key=key; it->key.b=key;
it->something="something"; it->something="something";
return it; 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) { 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 (expect_f==f);
assert((long)extraargs==23); assert((long)extraargs==23);
*value = make_item(key); *value = make_item(key.b);
did_fetch=key; did_fetch=key;
written_lsn->lsn = 0; written_lsn->lsn = 0;
return 0; return 0;
...@@ -158,89 +159,89 @@ static void test0 (void) { ...@@ -158,89 +159,89 @@ static void test0 (void) {
expect_f = f; expect_f = f;
expect_n_flushes=0; expect_n_flushes=0;
u_int32_t h1 = toku_cachetable_hash(f, 1); u_int32_t h1 = toku_cachetable_hash(f, make_blocknum(1));
u_int32_t h2 = toku_cachetable_hash(f, 2); u_int32_t h2 = toku_cachetable_hash(f, make_blocknum(2));
u_int32_t h3 = toku_cachetable_hash(f, 3); u_int32_t h3 = toku_cachetable_hash(f, make_blocknum(3));
u_int32_t h4 = toku_cachetable_hash(f, 4); u_int32_t h4 = toku_cachetable_hash(f, make_blocknum(4));
u_int32_t h5 = toku_cachetable_hash(f, 5); u_int32_t h5 = toku_cachetable_hash(f, make_blocknum(5));
u_int32_t h6 = toku_cachetable_hash(f, 6); u_int32_t h6 = toku_cachetable_hash(f, make_blocknum(6));
u_int32_t h7 = toku_cachetable_hash(f, 7); u_int32_t h7 = toku_cachetable_hash(f, make_blocknum(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. */ 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(r==0);
assert(expect_n_flushes==0); assert(expect_n_flushes==0);
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); 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); assert(expect_n_flushes==0);
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(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) */ 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; 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(r==0);
assert(expect_n_flushes==0); /* 4P 3P 2U 1P */ assert(expect_n_flushes==0); /* 4P 3P 2U 1P */
expect_n_flushes=0; 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); 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); 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(r==0);
assert(expect_n_flushes==0); /* 5U 4P 3U 2U 1P */ assert(expect_n_flushes==0); /* 5U 4P 3U 2U 1P */
expect1(2); /* 2 is the oldest unpinned item. */ 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); assert(r==0);
while (expect_n_flushes != 0) pthread_yield(); while (expect_n_flushes != 0) pthread_yield();
assert(expect_n_flushes==0); assert(expect_n_flushes==0);
expect1(3); 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); assert(r==0);
while (expect_n_flushes != 0) pthread_yield(); while (expect_n_flushes != 0) pthread_yield();
assert(expect_n_flushes==0); 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); assert(r==0);
{ {
void *item_v=0; void *item_v=0;
expect_n_flushes=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(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(strcmp(((struct item *)item_v)->something,"something")==0);
assert(expect_n_flushes==0); assert(expect_n_flushes==0);
} }
{ {
void *item_v=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); assert(r==0);
expect1(4); expect1(4);
did_fetch=-1; did_fetch=make_blocknum(-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 */ 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(r==0);
assert(did_fetch==2); /* Expect that 2 is fetched in. */ assert(did_fetch.b==2); /* Expect that 2 is fetched in. */
assert(((struct item *)item_v)->key==2); assert(((struct item *)item_v)->key.b==2);
assert(strcmp(((struct item *)item_v)->something,"something")==0); assert(strcmp(((struct item *)item_v)->something,"something")==0);
while (expect_n_flushes != 0) pthread_yield(); while (expect_n_flushes != 0) pthread_yield();
assert(expect_n_flushes==0); 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); 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); 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); 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); assert(r==0);
r=toku_cachetable_assert_all_unpinned(t); r=toku_cachetable_assert_all_unpinned(t);
assert(r==0); assert(r==0);
...@@ -293,26 +294,26 @@ static void test_nested_pin (void) { ...@@ -293,26 +294,26 @@ static void test_nested_pin (void) {
expect_f = f; expect_f = f;
i0=0; i1=0; i0=0; i1=0;
u_int32_t f1hash = toku_cachetable_hash(f, 1); u_int32_t f1hash = toku_cachetable_hash(f, make_blocknum(1));
r = toku_cachetable_put(f, 1, f1hash, &i0, 1, flush_n, fetch_n, f2); r = toku_cachetable_put(f, make_blocknum(1), f1hash, &i0, 1, flush_n, fetch_n, f2);
assert(r==0); 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(r==0);
assert(vv==&i0); assert(vv==&i0);
assert(i0==0); 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); 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(r==0);
assert(vv2==vv); 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); assert(r==0);
u_int32_t f2hash = toku_cachetable_hash(f, 2); u_int32_t f2hash = toku_cachetable_hash(f, make_blocknum(2));
r = toku_cachetable_put(f, 2, f2hash, &i1, test_object_size, flush_n, fetch_n, f2); 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 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); 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); assert(r==0);
// sleep(1); // sleep(1);
r = toku_cachefile_close(&f, 0); assert(r==0); r = toku_cachefile_close(&f, 0); assert(r==0);
...@@ -333,7 +334,7 @@ static void null_flush (CACHEFILE cf __attribute__((__unused__)), ...@@ -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) { 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(fullhash==toku_cachetable_hash(cf,key));
assert((long)extraargs==123); assert((long)extraargs==123);
*value = (void*)((unsigned long)key+123L); *value = (void*)((unsigned long)key.b+123L);
written_lsn->lsn = 0; written_lsn->lsn = 0;
return 0; return 0;
} }
...@@ -341,7 +342,7 @@ static int add123_fetch (CACHEFILE cf, CACHEKEY key, u_int32_t fullhash, void ** ...@@ -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) { 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(fullhash==toku_cachetable_hash(cf,key));
assert((long)extraargs==222); assert((long)extraargs==222);
*value = (void*)((unsigned long)key+222L); *value = (void*)((unsigned long)key.b+222L);
written_lsn->lsn = 0; written_lsn->lsn = 0;
return 0; return 0;
} }
...@@ -366,39 +367,39 @@ static void test_multi_filehandles (void) { ...@@ -366,39 +367,39 @@ static void test_multi_filehandles (void) {
assert(f1==f2); assert(f1==f2);
assert(f1!=f3); 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_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, 1, toku_cachetable_hash(f2, 1), &v, NULL, 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); 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); 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); 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); 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, make_blocknum(1), toku_cachetable_hash(f1, make_blocknum(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(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_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, make_blocknum(1), toku_cachetable_hash(f2, make_blocknum(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(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_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_cachefile_close(&f3, 0); assert(r==0);
r = toku_cachetable_close(&t); 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__))) { 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) { 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; *value_ptr = arg;
written_lsn->lsn = 0; written_lsn->lsn = 0;
assert(fullhash==toku_cachetable_hash(f,key)); 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; return 0;
} }
...@@ -419,7 +420,7 @@ static void test_dirty() { ...@@ -419,7 +420,7 @@ static void test_dirty() {
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, 0777); r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, 0777);
assert(r == 0); assert(r == 0);
key = 1; value = (void*)1; key = make_blocknum(1); value = (void*)1;
u_int32_t hkey = toku_cachetable_hash(f, key); 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); r = toku_cachetable_put(f, key, hkey, value, test_object_size, test_dirty_flush, 0, 0);
assert(r == 0); assert(r == 0);
...@@ -456,7 +457,7 @@ static void test_dirty() { ...@@ -456,7 +457,7 @@ static void test_dirty() {
assert(dirty == 1); assert(dirty == 1);
assert(pinned == 0); assert(pinned == 0);
key = 2; key = make_blocknum(2);
hkey = toku_cachetable_hash(f, key); hkey = toku_cachetable_hash(f, key);
r = toku_cachetable_get_and_pin(f, key, hkey, r = toku_cachetable_get_and_pin(f, key, hkey,
&value, NULL, test_dirty_flush, &value, NULL, test_dirty_flush,
...@@ -508,7 +509,7 @@ static int test_size_debug; ...@@ -508,7 +509,7 @@ static int test_size_debug;
static CACHEKEY test_size_flush_key; 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__))) { 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) { if (keep) {
assert(do_write != 0); assert(do_write != 0);
test_size_flush_key = key; test_size_flush_key = key;
...@@ -533,7 +534,7 @@ static void test_size_resize() { ...@@ -533,7 +534,7 @@ static void test_size_resize() {
r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, 0777); r = toku_cachetable_openf(&f, t, fname, O_RDWR|O_CREAT, 0777);
assert(r == 0); assert(r == 0);
CACHEKEY key = 42; CACHEKEY key = make_blocknum(42);
void *value = (void *) -42; void *value = (void *) -42;
u_int32_t hkey = toku_cachetable_hash(f, key); u_int32_t hkey = toku_cachetable_hash(f, key);
...@@ -587,12 +588,12 @@ static void test_size_flush() { ...@@ -587,12 +588,12 @@ static void test_size_flush() {
assert(r == 0); assert(r == 0);
/* put 2*n keys into the table, ensure flushes occur in key order */ /* 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; int i;
CACHEKEY expect_flush_key = 0; CACHEKEY expect_flush_key = make_blocknum(0);
for (i=0; i<2*n; i++) { for (i=0; i<2*n; i++) {
CACHEKEY key = i; CACHEKEY key = make_blocknum(i);
void *value = (void *)(long)-i; void *value = (void *)(long)-i;
// printf("test_size put %lld %p %lld\n", key, value, size); // printf("test_size put %lld %p %lld\n", key, value, size);
u_int32_t hkey = toku_cachetable_hash(f, key); u_int32_t hkey = toku_cachetable_hash(f, key);
...@@ -616,10 +617,10 @@ static void test_size_flush() { ...@@ -616,10 +617,10 @@ static void test_size_flush() {
assert(entry_value == value); assert(entry_value == value);
assert(entry_size == size); assert(entry_size == size);
if (test_size_flush_key != -1) { if (test_size_flush_key.b != -1) {
assert(test_size_flush_key == expect_flush_key); assert(test_size_flush_key.b == expect_flush_key.b);
assert(expect_flush_key == i-n); assert(expect_flush_key.b == i-n);
expect_flush_key += 1; expect_flush_key.b += 1;
} }
r = toku_cachetable_unpin(f, key, hkey, CACHETABLE_CLEAN, size); r = toku_cachetable_unpin(f, key, hkey, CACHETABLE_CLEAN, size);
......
/* -*- mode: C; c-basic-offset: 4 -*- */ /* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved." #ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
#include "memory.h" #include <inttypes.h>
#include "cachetable.h"
#include "toku_assert.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include "memory.h"
#include "cachetable.h"
#include "toku_assert.h"
#include "test.h" #include "test.h"
// this mutex is used by some of the tests to serialize access to some // this mutex is used by some of the tests to serialize access to some
...@@ -51,7 +52,7 @@ static void print_ints(void) { ...@@ -51,7 +52,7 @@ static void print_ints(void) {
int i; int i;
for (i=0; i<n_present; i++) { for (i=0; i<n_present; i++) {
if (i==0) printf("{"); else printf(","); if (i==0) printf("{"); else printf(",");
printf("{%lld,%p}", present_items[i].key, present_items[i].cf); printf("{%" PRId64 ",%p}", present_items[i].key.b, present_items[i].cf);
} }
printf("}\n"); printf("}\n");
} }
...@@ -72,7 +73,7 @@ static void item_becomes_not_present(CACHEFILE cf, CACHEKEY key) { ...@@ -72,7 +73,7 @@ static void item_becomes_not_present(CACHEFILE cf, CACHEKEY key) {
test_mutex_lock(); test_mutex_lock();
assert(n_present<=N_PRESENT_LIMIT); assert(n_present<=N_PRESENT_LIMIT);
for (i=0; i<n_present; i++) { for (i=0; i<n_present; i++) {
if (present_items[i].cf==cf && present_items[i].key==key) { if (present_items[i].cf==cf && present_items[i].key.b==key.b) {
present_items[i]=present_items[n_present-1]; present_items[i]=present_items[n_present-1];
n_present--; n_present--;
test_mutex_unlock(); test_mutex_unlock();
...@@ -80,7 +81,7 @@ static void item_becomes_not_present(CACHEFILE cf, CACHEKEY key) { ...@@ -80,7 +81,7 @@ static void item_becomes_not_present(CACHEFILE cf, CACHEKEY key) {
return; return;
} }
} }
printf("Whoops, %p,%lld was already not present\n", cf ,key); printf("Whoops, %p,%" PRId64 " was already not present\n", cf ,key.b);
abort(); abort();
test_mutex_unlock(); test_mutex_unlock();
} }
...@@ -107,15 +108,15 @@ static void flush_forchain (CACHEFILE f __attribute__((__unused__)), ...@@ -107,15 +108,15 @@ static void flush_forchain (CACHEFILE f __attribute__((__unused__)),
int *v = value; int *v = value;
//toku_cachetable_print_state(ct); //toku_cachetable_print_state(ct);
//printf("Flush %lld %d\n", key, (int)value); //printf("Flush %lld %d\n", key, (int)value);
assert((long)v==(long)key); assert((long)v==(long)key.b);
item_becomes_not_present(f, key); item_becomes_not_present(f, key);
//print_ints(); //print_ints();
} }
static int fetch_forchain (CACHEFILE f, CACHEKEY key, u_int32_t fullhash, void**value, long *sizep __attribute__((__unused__)), void*extraargs, LSN *written_lsn) { static int fetch_forchain (CACHEFILE f, CACHEKEY key, u_int32_t fullhash, void**value, long *sizep __attribute__((__unused__)), void*extraargs, LSN *written_lsn) {
assert(toku_cachetable_hash(f, key)==fullhash); assert(toku_cachetable_hash(f, key)==fullhash);
assert((long)extraargs==(long)key); assert((long)extraargs==(long)key.b);
*value = (void*)(long)key; *value = (void*)(long)key.b;
written_lsn->lsn = 0; written_lsn->lsn = 0;
return 0; return 0;
} }
...@@ -162,12 +163,12 @@ static void test_chaining (void) { ...@@ -162,12 +163,12 @@ static void test_chaining (void) {
for (i=0; i<N_PRESENT_LIMIT; i++) { for (i=0; i<N_PRESENT_LIMIT; i++) {
int fnum = i%N_FILES; int fnum = i%N_FILES;
//printf("%s:%d Add %d\n", __FILE__, __LINE__, i); //printf("%s:%d Add %d\n", __FILE__, __LINE__, i);
u_int32_t fhash = toku_cachetable_hash(f[fnum], i); u_int32_t fhash = toku_cachetable_hash(f[fnum], make_blocknum(i));
r = toku_cachetable_put(f[fnum], i, fhash, (void*)i, test_object_size, flush_forchain, fetch_forchain, (void*)i); r = toku_cachetable_put(f[fnum], make_blocknum(i), fhash, (void*)i, test_object_size, flush_forchain, fetch_forchain, (void*)i);
assert(r==0); assert(r==0);
item_becomes_present(f[fnum], i); item_becomes_present(f[fnum], make_blocknum(i));
r = toku_cachetable_unpin(f[fnum], i, fhash, CACHETABLE_CLEAN, test_object_size); r = toku_cachetable_unpin(f[fnum], make_blocknum(i), fhash, CACHETABLE_CLEAN, test_object_size);
assert(r==0); assert(r==0);
//print_ints(); //print_ints();
} }
test_mutex_init(); test_mutex_init();
...@@ -189,7 +190,7 @@ static void test_chaining (void) { ...@@ -189,7 +190,7 @@ static void test_chaining (void) {
NULL, NULL,
flush_forchain, flush_forchain,
fetch_forchain, fetch_forchain,
(void*)(long)whichkey (void*)(long)whichkey.b
); );
assert(r==0); assert(r==0);
r = toku_cachetable_unpin(whichcf, r = toku_cachetable_unpin(whichcf,
...@@ -204,18 +205,19 @@ static void test_chaining (void) { ...@@ -204,18 +205,19 @@ static void test_chaining (void) {
// i is always incrementing, so we need not worry about inserting a duplicate // i is always incrementing, so we need not worry about inserting a duplicate
// if i is a duplicate, cachetable_put will return -1 // if i is a duplicate, cachetable_put will return -1
// printf("%s:%d Add {%ld,%p}\n", __FILE__, __LINE__, i, f[fnum]); // printf("%s:%d Add {%ld,%p}\n", __FILE__, __LINE__, i, f[fnum]);
u_int32_t fhash = toku_cachetable_hash(f[fnum], i); u_int32_t fhash = toku_cachetable_hash(f[fnum], make_blocknum(i));
r = toku_cachetable_put(f[fnum], i, fhash, (void*)i, test_object_size, flush_forchain, fetch_forchain, (void*)i); r = toku_cachetable_put(f[fnum], make_blocknum(i), fhash, (void*)i, test_object_size, flush_forchain, fetch_forchain, (void*)i);
assert(r==0 || r==-1); assert(r==0 || r==-1);
if (r==0) { if (r==0) {
item_becomes_present(f[fnum], i); item_becomes_present(f[fnum], make_blocknum(i));
//print_ints(); //print_ints();
//cachetable_print_state(ct); //cachetable_print_state(ct);
} }
r = toku_cachetable_unpin(f[fnum], i, fhash, CACHETABLE_CLEAN, test_object_size); r = toku_cachetable_unpin(f[fnum], make_blocknum(i), fhash, CACHETABLE_CLEAN, test_object_size);
assert(r==0); assert(r==0);
long long pinned; long long pinned;
r = toku_cachetable_get_key_state(ct, i, f[fnum], 0, 0, &pinned, 0); r = toku_cachetable_get_key_state(ct, make_blocknum(i), f[fnum], 0, 0, &pinned, 0);
assert(r==0); assert(r==0);
assert(pinned == 0); assert(pinned == 0);
verify_cachetable_against_present(); verify_cachetable_against_present();
......
...@@ -25,31 +25,31 @@ void cachetable_unpin_test(int n) { ...@@ -25,31 +25,31 @@ void cachetable_unpin_test(int n) {
int i; int i;
for (i=1; i<=n; i++) { for (i=1; i<=n; i++) {
u_int32_t hi; u_int32_t hi;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(i));
r = toku_cachetable_put(f1, i, hi, (void *)(long)i, 1, flush, fetch, 0); r = toku_cachetable_put(f1, make_blocknum(i), hi, (void *)(long)i, 1, flush, fetch, 0);
assert(r == 0); assert(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
void *v; 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(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); 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(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i); assert(toku_cachefile_count_pinned(f1, 0) == i);
} }
for (i=n; i>0; i--) { for (i=n; i>0; i--) {
u_int32_t hi; u_int32_t hi;
hi = toku_cachetable_hash(f1, i); hi = toku_cachetable_hash(f1, make_blocknum(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(r == 0);
assert(toku_cachefile_count_pinned(f1, 0) == i-1); assert(toku_cachefile_count_pinned(f1, 0) == i-1);
} }
assert(toku_cachefile_count_pinned(f1, 1) == 0); assert(toku_cachefile_count_pinned(f1, 1) == 0);
toku_cachetable_verify(ct); 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); r = toku_cachetable_unpin(f1, k, toku_cachetable_hash(f1, k), CACHETABLE_CLEAN, 1);
assert(r != 0); assert(r != 0);
......
...@@ -22,7 +22,7 @@ int fnamelen; ...@@ -22,7 +22,7 @@ int fnamelen;
char *fname; char *fname;
void doit (void) { void doit (void) {
DISKOFF nodea,nodeb; BLOCKNUM nodea,nodeb;
u_int32_t fingerprinta=0; u_int32_t fingerprinta=0;
int r; int r;
......
...@@ -48,7 +48,7 @@ int fnamelen; ...@@ -48,7 +48,7 @@ int fnamelen;
char *fname; char *fname;
void doit (int ksize __attribute__((__unused__))) { void doit (int ksize __attribute__((__unused__))) {
DISKOFF cnodes[BRT_FANOUT], bnode, anode; BLOCKNUM cnodes[BRT_FANOUT], bnode, anode;
u_int32_t fingerprints[BRT_FANOUT]; u_int32_t fingerprints[BRT_FANOUT];
char *keys[BRT_FANOUT-1]; char *keys[BRT_FANOUT-1];
......
...@@ -98,6 +98,11 @@ static inline void wbuf_u_int32_t (struct wbuf *w, u_int32_t v) { ...@@ -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) { static inline void wbuf_DISKOFF (struct wbuf *w, DISKOFF off) {
wbuf_ulonglong(w, (u_int64_t)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) { static inline void wbuf_TXNID (struct wbuf *w, TXNID tid) {
wbuf_ulonglong(w, tid); wbuf_ulonglong(w, tid);
...@@ -115,15 +120,15 @@ static inline void wbuf_LOGGEDBRTHEADER (struct wbuf *w, LOGGEDBRTHEADER h) { ...@@ -115,15 +120,15 @@ static inline void wbuf_LOGGEDBRTHEADER (struct wbuf *w, LOGGEDBRTHEADER h) {
wbuf_uint(w, h.size); wbuf_uint(w, h.size);
wbuf_uint(w, h.flags); wbuf_uint(w, h.flags);
wbuf_uint(w, h.nodesize); wbuf_uint(w, h.nodesize);
wbuf_DISKOFF(w, h.freelist); wbuf_BLOCKNUM(w, h.free_blocks);
wbuf_DISKOFF(w, h.unused_memory); wbuf_BLOCKNUM(w, h.unused_blocks);
wbuf_int(w, h.n_named_roots); wbuf_int(w, h.n_named_roots);
if ((signed)h.n_named_roots==-1) { if ((signed)h.n_named_roots==-1) {
wbuf_DISKOFF(w, h.u.one.root); wbuf_BLOCKNUM(w, h.u.one.root);
} else { } else {
int i; int i;
for (i=0; i<h.n_named_roots; i++) { for (i=0; i<h.n_named_roots; i++) {
wbuf_DISKOFF(w, h.u.many.roots[i]); wbuf_BLOCKNUM(w, h.u.many.roots[i]);
wbuf_bytes (w, h.u.many.names[i], (u_int32_t)(1+strlen(h.u.many.names[i]))); wbuf_bytes (w, h.u.many.names[i], (u_int32_t)(1+strlen(h.u.many.names[i])));
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment