2007-11-23 17:41:02 +00:00
# ifndef BRT_INTERNAL_H
# define BRT_INTERNAL_H
2007-11-29 14:27:42 +00:00
2008-01-24 15:10:32 +00:00
# ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
2007-11-29 14:18:54 +00:00
2007-07-13 19:37:47 +00:00
# include "cachetable.h"
2008-01-11 14:03:33 +00:00
# include "fifo.h"
2007-07-13 19:37:47 +00:00
# include "pma.h"
# include "brt.h"
2007-11-14 17:58:38 +00:00
# include "crc.h"
2008-01-25 15:43:37 +00:00
# include "list.h"
2007-07-13 19:37:47 +00:00
2007-08-25 21:58:25 +00:00
# ifndef BRT_FANOUT
# define BRT_FANOUT 16
# endif
2007-11-14 17:58:38 +00:00
enum { TREE_FANOUT = BRT_FANOUT } ;
2007-07-13 19:37:47 +00:00
enum { KEY_VALUE_OVERHEAD = 8 } ; /* Must store the two lengths. */
2007-12-04 22:18:21 +00:00
enum { PMA_ITEM_OVERHEAD = 4 } ;
2007-09-06 21:36:45 +00:00
enum { BRT_CMD_OVERHEAD = 1 } ;
2007-11-14 17:58:38 +00:00
enum { BRT_DEFAULT_NODE_SIZE = 1 < < 20 } ;
2007-09-06 21:36:45 +00:00
2007-07-13 19:37:47 +00:00
struct nodeheader_in_file {
int n_in_buffer ;
} ;
enum { BUFFER_HEADER_SIZE = ( 4 // height//
+ 4 // n_children
+ TREE_FANOUT * 8 // children
) } ;
2007-12-06 12:00:24 +00:00
struct brtnode_nonleaf_pivotinfo {
struct kv_pair * pivotkey ; /* For DUPSORT keys, the keys are whole key-value pairs.
* For nonduplicate and DUPSORT keys we have
* Child 0 ' s keys < = pivotkey [ 0 ] < Child 1 ' s keys < = pivotkey [ 1 ] < . . . pivotkey [ N - 1 ] < child N ' s keys < = pivotkey [ N ] . . .
*/
} ;
struct brtnode_nonleaf_childinfo {
u_int32_t subtree_fingerprint ;
2007-12-06 19:16:18 +00:00
#if 0
2007-12-06 12:00:24 +00:00
DISKOFF diskoff ;
2008-01-11 14:03:33 +00:00
FIFO htable ;
unsigned int n_bytes_in_buffer ; /* How many bytes are in each buffer (including overheads for the disk-representation) */
2007-12-06 19:16:18 +00:00
# endif
2007-12-06 12:00:24 +00:00
} ;
2007-07-13 19:37:47 +00:00
typedef struct brtnode * BRTNODE ;
/* Internal nodes. */
struct brtnode {
enum typ_tag tag ;
unsigned int nodesize ;
2007-11-27 15:22:56 +00:00
unsigned int flags ;
2007-11-14 17:58:38 +00:00
DISKOFF thisnodename ; // The size of the node allocated on disk. Not all is necessarily in use.
2008-01-23 18:06:23 +00:00
// These two LSNs are used to decide when to make a copy of a node instead of overwriting it.
// In the TOKULOGGER is a field called checkpoint_lsn which is the lsn of the most recent checkpoint
LSN disk_lsn ; // The LSN as of the most recent version on disk. (Updated by brt-serialize) This lsn is saved in the node.
LSN log_lsn ; // The LSN of the youngest log entry that affects the current in-memory state. The log write may not have actually made it to disk. This lsn is not saved in disk (since the two lsns are the same for any node not in main memory.)
// The checkpointing works as follows:
// When we unpin a node: if it is dirty and disk_lsn<checkpoint_lsn then we need to make a new copy.
// When we checkpoint: Create a checkpoint record, and cause every dirty node to be written to disk. The new checkpoint record is *not* incorporated into the disk_lsn of the written nodes.
// While we are checkpointing, someone may modify a dirty node that has not yet been written. In that case, when we unpin the node, we make the new copy (because the disk_lsn<checkpoint_lsn), just as we would usually.
//
2007-11-14 17:58:38 +00:00
int layout_version ; // What version of the data structure?
2007-07-13 19:37:47 +00:00
int height ; /* height is always >= 0. 0 for leaf, >0 for nonleaf. */
2007-11-14 17:58:38 +00:00
u_int32_t rand4fingerprint ;
2008-01-11 14:03:33 +00:00
u_int32_t local_fingerprint ; /* For leaves this is everything in the buffer. For nonleaves, this is everything in the buffers, but does not include child subtree fingerprints. */
2007-11-14 17:58:38 +00:00
int dirty ;
2007-07-13 19:37:47 +00:00
union node {
struct nonleaf {
2007-11-14 17:58:38 +00:00
// Don't actually store the subree fingerprint in the in-memory data structure.
2007-07-13 19:37:47 +00:00
int n_children ; /* if n_children==TREE_FANOUT+1 then the tree needs to be rebalanced. */
2007-12-06 12:00:24 +00:00
unsigned int totalchildkeylens ;
2008-01-11 14:03:33 +00:00
unsigned int n_bytes_in_buffers ;
2007-12-06 12:00:24 +00:00
2007-12-06 19:16:18 +00:00
struct brtnode_nonleaf_childinfo childinfos [ TREE_FANOUT + 1 ] ; /* One extra so we can grow */
#if 0
u_int32_t child_subtree_fingerprints [ TREE_FANOUT + 1 ] ;
# define BRTNODE_CHILD_SUBTREE_FINGERPRINTS(node,i) ((node)->u.n.child_subtree_fingerprints[i])
# else
# define BRTNODE_CHILD_SUBTREE_FINGERPRINTS(node,i) ((node)->u.n.childinfos[i].subtree_fingerprint)
# endif
2007-12-06 12:00:24 +00:00
//#define CHSTRUCT
# ifdef CHSTRUCT
struct brtnode_nonleaf_pivotinfo pivots [ TREE_FANOUT ] ; /* One extra one so we can grow. */
# else
2007-11-27 18:16:45 +00:00
struct kv_pair * childkeys [ TREE_FANOUT ] ; /* Pivot keys. Child 0's keys are <= childkeys[0]. Child 1's keys are <= childkeys[1].
2007-07-13 19:37:47 +00:00
Note : It is possible that Child 1 ' s keys are = = to child 0 ' s key ' s , so it is
not necessarily true that child 1 ' s keys are > childkeys [ 0 ] .
However , in the absense of duplicate keys , child 1 ' s keys * are * > childkeys [ 0 ] . */
2007-11-14 17:58:38 +00:00
DISKOFF children [ TREE_FANOUT + 1 ] ; /* unused if height==0 */ /* Note: The last element of these arrays is used only temporarily while splitting a node. */
2007-12-06 20:58:45 +00:00
# define BRTNODE_CHILD_DISKOFF(node,i) ((node)->u.n.children[i])
2008-01-11 14:03:33 +00:00
FIFO buffers [ TREE_FANOUT + 1 ] ;
unsigned int n_bytes_in_buffer [ TREE_FANOUT + 1 ] ; /* how many bytes are in each buffer (including overheads) */
2007-12-06 12:00:24 +00:00
# endif
2007-08-23 18:07:18 +00:00
} n ;
2007-07-13 19:37:47 +00:00
struct leaf {
PMA buffer ;
2007-12-04 22:18:21 +00:00
unsigned int n_bytes_in_buffer ; /* How many bytes to represent the PMA (including the per-key overheads, but not including the overheads for the node. */
2007-07-13 19:37:47 +00:00
} l ;
} u ;
} ;
2007-11-19 20:22:56 +00:00
/* pivot flags (must fit in 8 bits) */
2007-11-15 14:44:05 +00:00
enum {
BRT_PIVOT_TRUNC = 4 ,
BRT_PIVOT_FRONT_COMPRESS = 8 ,
} ;
2007-07-13 19:37:47 +00:00
struct brt_header {
int dirty ;
unsigned int nodesize ;
2007-11-14 17:58:38 +00:00
DISKOFF freelist ;
DISKOFF unused_memory ;
DISKOFF unnamed_root ;
2007-07-13 19:37:47 +00:00
int n_named_roots ; /* -1 if the only one is unnamed */
char * * names ;
2007-11-14 17:58:38 +00:00
DISKOFF * roots ;
unsigned int flags ;
2007-07-13 19:37:47 +00:00
} ;
2007-11-22 01:05:00 +00:00
enum brt_header_flags {
TOKU_DB_DUP = 1 ,
TOKU_DB_DUPSORT = 2 ,
} ;
2007-07-13 19:37:47 +00:00
struct brt {
CACHEFILE cf ;
char * database_name ;
// The header is shared. It is also ephemeral.
struct brt_header * h ;
2008-01-25 15:43:37 +00:00
struct list cursors ;
2007-07-24 01:32:03 +00:00
2007-11-14 17:58:38 +00:00
unsigned int nodesize ;
unsigned int flags ;
2007-07-24 14:34:05 +00:00
int ( * compare_fun ) ( DB * , const DBT * , const DBT * ) ;
2007-11-14 17:58:38 +00:00
int ( * dup_compare ) ( DB * , const DBT * , const DBT * ) ;
2007-11-26 21:51:36 +00:00
DB * db ; // To pass to the compare fun
2007-07-24 01:32:03 +00:00
void * skey , * sval ; /* Used for DBT return values. */
2007-07-13 19:37:47 +00:00
} ;
/* serialization code */
2007-11-21 13:07:49 +00:00
void toku_serialize_brtnode_to ( int fd , DISKOFF off , DISKOFF size , BRTNODE node ) ;
2007-11-26 21:51:36 +00:00
int toku_deserialize_brtnode_from ( int fd , DISKOFF off , BRTNODE * brtnode , int flags , int nodesize , int ( * bt_compare ) ( DB * , const DBT * , const DBT * ) , int ( * dup_compare ) ( DB * , const DBT * , const DBT * ) , DB * db , FILENUM filenum ) ;
2007-11-19 23:54:17 +00:00
unsigned int toku_serialize_brtnode_size ( BRTNODE node ) ; /* How much space will it take? */
2007-11-20 00:02:51 +00:00
int toku_keycompare ( bytevec key1 , ITEMLEN key1len , bytevec key2 , ITEMLEN key2len ) ;
2007-07-13 19:37:47 +00:00
2007-11-19 23:54:17 +00:00
void toku_verify_counts ( BRTNODE ) ;
2007-07-13 19:37:47 +00:00
2007-11-21 13:07:49 +00:00
int toku_serialize_brt_header_size ( struct brt_header * h ) ;
2007-11-19 23:54:17 +00:00
int toku_serialize_brt_header_to ( int fd , struct brt_header * h ) ;
2007-11-21 13:07:49 +00:00
int toku_serialize_brt_header_to_wbuf ( struct wbuf * , struct brt_header * h ) ;
2007-11-19 23:54:17 +00:00
int toku_deserialize_brtheader_from ( int fd , DISKOFF off , struct brt_header * * brth ) ;
2007-07-13 19:37:47 +00:00
2007-11-29 15:09:14 +00:00
void toku_brtnode_free ( BRTNODE * node ) ;
2007-08-01 02:37:21 +00:00
2007-07-13 19:37:47 +00:00
# if 1
# define DEADBEEF ((void*)0xDEADBEEF)
# else
# define DEADBEEF ((void*)0xDEADBEEFDEADBEEF)
# endif
2008-01-25 15:43:37 +00:00
/* tree command types */
2007-09-06 21:36:45 +00:00
enum brt_cmd_type {
BRT_NONE = 0 ,
BRT_INSERT = 1 ,
BRT_DELETE = 2 ,
2008-01-02 20:33:51 +00:00
BRT_DELETE_BOTH = 3 ,
2007-09-06 21:36:45 +00:00
} ;
2008-01-25 15:43:37 +00:00
/* tree commands */
2007-09-06 21:36:45 +00:00
struct brt_cmd {
enum brt_cmd_type type ;
union {
/* insert or delete */
struct brt_cmd_insert_delete {
DBT * key ;
DBT * val ;
} id ;
} u ;
} ;
typedef struct brt_cmd BRT_CMD ;
2007-11-14 17:58:38 +00:00
struct brtenv {
CACHETABLE ct ;
TOKULOGGER logger ;
long long checksum_number ;
// SPINLOCK checkpointing;
} ;
2007-11-29 15:09:14 +00:00
extern cachetable_flush_func_t toku_brtnode_flush_callback , toku_brtheader_flush_callback ;
extern cachetable_fetch_func_t toku_brtnode_fetch_callback , toku_brtheader_fetch_callback ;
2007-11-14 17:58:38 +00:00
extern int toku_read_and_pin_brt_header ( CACHEFILE cf , struct brt_header * * header ) ;
extern int toku_unpin_brt_header ( BRT brt ) ;
extern CACHEKEY * toku_calculate_root_offset_pointer ( BRT brt ) ;
static const BRTNODE null_brtnode = 0 ;
extern u_int32_t toku_calccrc32_kvpair ( const void * key , int keylen , const void * val , int vallen ) ;
extern u_int32_t toku_calccrc32_cmd ( int type , const void * key , int keylen , const void * val , int vallen ) ;
extern u_int32_t toku_calccrc32_cmdstruct ( BRT_CMD * cmd ) ;
2007-11-26 21:51:36 +00:00
2007-12-06 13:52:52 +00:00
// How long is the pivot key?
2007-12-06 14:20:47 +00:00
unsigned int toku_brt_pivot_key_len ( BRT , struct kv_pair * ) ; // Given the tree
unsigned int toku_brtnode_pivot_key_len ( BRTNODE , struct kv_pair * ) ; // Given the node
2007-12-06 13:52:52 +00:00
2008-01-25 15:43:37 +00:00
/* a brt cursor is represented as a kv pair in a tree */
struct brt_cursor {
struct list cursors_link ;
BRT brt ;
DBT key ;
DBT val ;
} ;
2007-11-23 17:41:02 +00:00
# endif