2008-01-11 03:09:14 +00:00
/* -*- mode: C; c-basic-offset: 4 -*- */
2008-01-24 15:10:32 +00:00
# ident "Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved."
2008-01-11 03:09:14 +00:00
/* rollback and rollforward routines. */
# include <stdlib.h>
# include <inttypes.h>
2008-01-18 18:18:11 +00:00
# include <unistd.h>
2008-01-11 03:09:14 +00:00
# include "log_header.h"
# include "log-internal.h"
# include "cachetable.h"
# include "key.h"
//#define DO_VERIFY_COUNTS
# ifdef DO_VERIFY_COUNTS
# define VERIFY_COUNTS(n) toku_verify_counts(n)
# else
# define VERIFY_COUNTS(n) ((void)0)
# endif
2008-02-08 22:16:02 +00:00
# define UU(x) x __attribute__((__unused__))
2008-01-11 03:09:14 +00:00
static DB * const null_db = 0 ;
// These data structures really should be part of a recovery data structure. Recovery could be multithreaded (on different environments...) But this is OK since recovery can only happen in one
static CACHETABLE ct ;
static struct cf_pair {
FILENUM filenum ;
CACHEFILE cf ;
BRT brt ; // set to zero on an fopen, but filled in when an fheader is seen.
} * cf_pairs ;
static int n_cf_pairs = 0 , max_cf_pairs = 0 ; ;
int toku_recover_init ( void ) {
int r = toku_create_cachetable ( & ct , 1 < < 25 , ( LSN ) { 0 } , 0 ) ;
return r ;
}
void toku_recover_cleanup ( void ) {
int i ;
for ( i = 0 ; i < n_cf_pairs ; i + + ) {
if ( cf_pairs [ i ] . brt ) {
int r = toku_close_brt ( cf_pairs [ i ] . brt ) ;
//r = toku_cachefile_close(&cf_pairs[i].cf);
assert ( r = = 0 ) ;
}
}
toku_free ( cf_pairs ) ;
{
int r = toku_cachetable_close ( & ct ) ;
assert ( r = = 0 ) ;
}
}
2008-02-27 07:14:03 +00:00
int toku_recover_note_cachefile ( FILENUM fnum , CACHEFILE cf , BRT brt ) {
2008-01-11 03:09:14 +00:00
if ( max_cf_pairs = = 0 ) {
n_cf_pairs = 1 ;
max_cf_pairs = 2 ;
MALLOC_N ( max_cf_pairs , cf_pairs ) ;
if ( cf_pairs = = 0 ) return errno ;
} else {
if ( n_cf_pairs > = max_cf_pairs ) {
max_cf_pairs * = 2 ;
cf_pairs = toku_realloc ( cf_pairs , max_cf_pairs * sizeof ( * cf_pairs ) ) ;
}
n_cf_pairs + + ;
}
cf_pairs [ n_cf_pairs - 1 ] . filenum = fnum ;
cf_pairs [ n_cf_pairs - 1 ] . cf = cf ;
2008-02-27 07:14:03 +00:00
cf_pairs [ n_cf_pairs - 1 ] . brt = brt ;
2008-01-11 03:09:14 +00:00
return 0 ;
}
static int find_cachefile ( FILENUM fnum , struct cf_pair * * cf_pair ) {
int i ;
for ( i = 0 ; i < n_cf_pairs ; i + + ) {
if ( fnum . fileid = = cf_pairs [ i ] . filenum . fileid ) {
* cf_pair = cf_pairs + i ;
return 0 ;
}
}
return 1 ;
}
static char * fixup_fname ( BYTESTRING * f ) {
assert ( f - > len > 0 ) ;
char * fname = toku_malloc ( f - > len + 1 ) ;
memcpy ( fname , f - > data , f - > len ) ;
fname [ f - > len ] = 0 ;
return fname ;
}
2008-02-08 22:16:02 +00:00
void toku_recover_commit ( LSN UU ( lsn ) , TXNID UU ( txnid ) ) {
2008-01-11 03:09:14 +00:00
}
2008-01-11 03:44:21 +00:00
# define ABORTIT { le=le; txn=txn; fprintf(stderr, "%s:%d (%s) not ready to go\n", __FILE__, __LINE__, __func__); abort(); }
2008-02-26 15:51:15 +00:00
2008-02-08 22:16:02 +00:00
void toku_recover_delete ( LSN UU ( lsn ) , FILENUM UU ( filenum ) , DISKOFF UU ( diskoff ) , BYTESTRING UU ( key ) , BYTESTRING UU ( data ) ) { assert ( 0 ) ; }
2008-01-11 03:09:14 +00:00
2008-02-08 22:16:02 +00:00
void toku_recover_fcreate ( LSN UU ( lsn ) , TXNID UU ( txnid ) , BYTESTRING fname , u_int32_t mode ) {
char * fixed_fname = fixup_fname ( & fname ) ;
int fd = creat ( fixed_fname , mode ) ;
2008-01-11 03:09:14 +00:00
assert ( fd > = 0 ) ;
2008-02-08 22:16:02 +00:00
toku_free ( fixed_fname ) ;
toku_free_BYTESTRING ( fname ) ;
2008-01-11 03:09:14 +00:00
}
2008-02-26 15:51:15 +00:00
int toku_rollback_fcreate ( BYTESTRING bs_fname ,
2008-02-14 19:23:25 +00:00
TOKUTXN txn __attribute__ ( ( __unused__ ) ) ) {
char * fname = fixup_fname ( & bs_fname ) ;
2008-01-12 12:21:07 +00:00
char * directory = txn - > logger - > directory ;
int full_len = strlen ( fname ) + strlen ( directory ) + 2 ;
char full_fname [ full_len ] ;
int l = snprintf ( full_fname , full_len , " %s/%s " , directory , fname ) ;
assert ( l < = full_len ) ;
int r = unlink ( full_fname ) ;
assert ( r = = 0 ) ;
2008-02-14 19:23:25 +00:00
free ( fname ) ;
2008-01-12 12:21:07 +00:00
return 0 ;
}
2008-02-08 22:16:02 +00:00
void toku_recover_fheader ( LSN UU ( lsn ) , TXNID UU ( txnid ) , FILENUM filenum , LOGGEDBRTHEADER header ) {
2008-01-11 03:09:14 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
struct brt_header * MALLOC ( h ) ;
assert ( h ) ;
h - > dirty = 0 ;
2008-02-08 22:16:02 +00:00
h - > flags = header . flags ;
h - > nodesize = header . nodesize ;
h - > freelist = header . freelist ;
h - > unused_memory = header . unused_memory ;
h - > n_named_roots = header . n_named_roots ;
if ( ( signed ) header . n_named_roots = = - 1 ) {
h - > unnamed_root = header . u . one . root ;
2008-01-11 03:09:14 +00:00
} else {
assert ( 0 ) ;
}
toku_cachetable_put ( pair - > cf , 0 , h , 0 , toku_brtheader_flush_callback , toku_brtheader_fetch_callback , 0 ) ;
if ( pair - > brt ) {
free ( pair - > brt - > h ) ;
} else {
MALLOC ( pair - > brt ) ;
pair - > brt - > cf = pair - > cf ;
pair - > brt - > database_name = 0 ; // Special case, we don't know or care what the database name is for recovery.
2008-01-25 15:44:49 +00:00
list_init ( & pair - > brt - > cursors ) ;
2008-01-11 03:09:14 +00:00
pair - > brt - > compare_fun = 0 ;
pair - > brt - > dup_compare = 0 ;
pair - > brt - > db = 0 ;
pair - > brt - > skey = pair - > brt - > sval = 0 ;
}
pair - > brt - > h = h ;
pair - > brt - > nodesize = h - > nodesize ;
pair - > brt - > flags = h - > nodesize ;
r = toku_unpin_brt_header ( pair - > brt ) ;
assert ( r = = 0 ) ;
}
2008-02-08 22:16:02 +00:00
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 ) {
2008-01-11 03:09:14 +00:00
int r ;
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
r = find_cachefile ( filenum , & pair ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
TAGMALLOC ( BRTNODE , n ) ;
2008-02-08 22:16:02 +00:00
n - > nodesize = nodesize ;
n - > thisnodename = diskoff ;
n - > log_lsn = n - > disk_lsn = lsn ;
2008-01-23 18:06:23 +00:00
//printf("%s:%d %p->disk_lsn=%"PRId64"\n", __FILE__, __LINE__, n, n->disk_lsn.lsn);
2008-02-05 18:25:23 +00:00
n - > layout_version = 2 ;
2008-02-08 22:16:02 +00:00
n - > height = height ;
n - > rand4fingerprint = rand4fingerprint ;
n - > flags = is_dup_sort ? TOKU_DB_DUPSORT : 0 ; // Don't have TOKU_DB_DUP ???
2008-01-11 03:09:14 +00:00
n - > local_fingerprint = 0 ; // nothing there yet
n - > dirty = 1 ;
2008-02-08 22:16:02 +00:00
if ( height = = 0 ) {
r = toku_pma_create ( & n - > u . l . buffer , toku_dont_call_this_compare_fun , null_db , filenum , nodesize ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
n - > u . l . n_bytes_in_buffer = 0 ;
} else {
2008-01-17 15:41:42 +00:00
n - > u . n . n_children = 0 ;
n - > u . n . totalchildkeylens = 0 ;
n - > u . n . n_bytes_in_buffers = 0 ;
2008-01-18 16:01:25 +00:00
int i ;
for ( i = 0 ; i < TREE_FANOUT + 1 ; i + + )
2008-02-01 01:38:11 +00:00
BNC_NBYTESINBUF ( n , i ) = 0 ;
2008-01-11 03:09:14 +00:00
}
// Now put it in the cachetable
2008-02-08 22:16:02 +00:00
toku_cachetable_put ( pair - > cf , diskoff , n , toku_serialize_brtnode_size ( n ) , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , 0 ) ;
2008-01-11 03:09:14 +00:00
VERIFY_COUNTS ( n ) ;
2008-02-08 22:16:02 +00:00
n - > log_lsn = lsn ;
r = toku_cachetable_unpin ( pair - > cf , diskoff , 1 , toku_serialize_brtnode_size ( n ) ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
}
2008-02-26 15:51:15 +00:00
//int toku_rollback_newbrtnode (struct logtype_newbrtnode *le, TOKUTXN txn) {
// // All that must be done is to put the node on the freelist.
// // Since we don't have a freelist right now, we don't have anything to do.
// // We'll fix this later (See #264)
// le=le;
// txn=txn;
// return 0;
//}
2008-01-12 12:21:07 +00:00
2008-01-18 21:28:27 +00:00
static void recover_setup_node ( FILENUM filenum , DISKOFF diskoff , CACHEFILE * cf , BRTNODE * resultnode ) {
2008-01-17 19:36:44 +00:00
struct cf_pair * pair ;
2008-01-18 21:28:27 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-17 19:36:44 +00:00
assert ( r = = 0 ) ;
assert ( pair - > brt ) ;
2008-01-18 21:28:27 +00:00
void * node_v ;
r = toku_cachetable_get_and_pin ( pair - > cf , diskoff , & node_v , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-17 19:36:44 +00:00
assert ( r = = 0 ) ;
BRTNODE node = node_v ;
2008-01-18 21:28:27 +00:00
* resultnode = node ;
* cf = pair - > cf ;
}
2008-02-08 22:16:02 +00:00
void toku_recover_brtdeq ( LSN UU ( lsn ) , FILENUM UU ( filenum ) , DISKOFF UU ( diskoff ) , u_int32_t UU ( childnum ) , TXNID UU ( xid ) , u_int32_t UU ( typ ) , BYTESTRING UU ( key ) , BYTESTRING UU ( data ) , u_int32_t UU ( oldfingerprint ) , u_int32_t UU ( newfingerprint ) ) { assert ( 0 ) ; }
2008-01-29 21:43:08 +00:00
2008-02-08 22:16:02 +00:00
void toku_recover_brtenq ( LSN UU ( lsn ) , FILENUM UU ( filenum ) , DISKOFF UU ( diskoff ) , u_int32_t UU ( childnum ) , TXNID UU ( xid ) , u_int32_t UU ( typ ) , BYTESTRING UU ( key ) , BYTESTRING UU ( data ) , u_int32_t UU ( oldfingerprint ) , u_int32_t UU ( newfingerprint ) ) { assert ( 0 ) ; }
2008-01-29 21:43:08 +00:00
2008-02-08 22:16:02 +00:00
void toku_recover_addchild ( LSN lsn , FILENUM filenum , DISKOFF diskoff , u_int32_t childnum , DISKOFF child , u_int32_t childfingerprint ) {
2008-01-18 21:28:27 +00:00
CACHEFILE cf ;
BRTNODE node ;
2008-02-08 22:16:02 +00:00
recover_setup_node ( filenum , diskoff , & cf , & node ) ;
2008-01-17 19:36:44 +00:00
assert ( node - > height > 0 ) ;
2008-02-08 22:16:02 +00:00
assert ( childnum < = ( unsigned ) node - > u . n . n_children ) ;
2008-01-17 19:36:44 +00:00
unsigned int i ;
2008-02-08 22:16:02 +00:00
for ( i = node - > u . n . n_children ; i > childnum ; i - - ) {
2008-01-17 19:36:44 +00:00
node - > u . n . childinfos [ i ] = node - > u . n . childinfos [ i - 1 ] ;
2008-02-01 01:38:11 +00:00
BNC_NBYTESINBUF ( node , i ) = BNC_NBYTESINBUF ( node , i - 1 ) ;
2008-01-30 21:23:01 +00:00
assert ( i > = 2 ) ;
node - > u . n . childkeys [ i - 1 ] = node - > u . n . childkeys [ i - 2 ] ;
2008-01-17 19:36:44 +00:00
}
2008-02-08 22:16:02 +00:00
if ( childnum > 0 ) {
node - > u . n . childkeys [ childnum - 1 ] = 0 ;
2008-02-08 04:34:12 +00:00
}
2008-02-08 22:16:02 +00:00
BNC_DISKOFF ( node , childnum ) = child ;
BNC_SUBTREE_FINGERPRINT ( node , childnum ) = childfingerprint ;
int r = toku_fifo_create ( & BNC_BUFFER ( node , childnum ) ) ; assert ( r = = 0 ) ;
BNC_NBYTESINBUF ( node , childnum ) = 0 ;
2008-01-17 19:36:44 +00:00
node - > u . n . n_children + + ;
2008-02-08 22:16:02 +00:00
node - > log_lsn = lsn ;
r = toku_cachetable_unpin ( cf , diskoff , 1 , toku_serialize_brtnode_size ( node ) ) ;
2008-01-17 19:36:44 +00:00
assert ( r = = 0 ) ;
}
2008-01-17 19:03:37 +00:00
2008-02-08 22:16:02 +00:00
void toku_recover_delchild ( LSN lsn , FILENUM filenum , DISKOFF diskoff , u_int32_t childnum , DISKOFF child , u_int32_t childfingerprint , BYTESTRING pivotkey ) {
2008-01-30 21:23:01 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-30 21:23:01 +00:00
assert ( r = = 0 ) ;
void * node_v ;
assert ( pair - > brt ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_get_and_pin ( pair - > cf , diskoff , & node_v , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-30 21:23:01 +00:00
assert ( r = = 0 ) ;
BRTNODE node = node_v ;
assert ( node - > height > 0 ) ;
assert ( childnum < ( unsigned ) node - > u . n . n_children ) ;
2008-02-08 22:16:02 +00:00
assert ( node - > u . n . childinfos [ childnum ] . subtree_fingerprint = = childfingerprint ) ;
assert ( BNC_DISKOFF ( node , childnum ) = = child ) ;
2008-01-31 22:05:43 +00:00
assert ( toku_fifo_n_entries ( BNC_BUFFER ( node , childnum ) ) = = 0 ) ;
2008-02-01 01:38:11 +00:00
assert ( BNC_NBYTESINBUF ( node , childnum ) = = 0 ) ;
2008-01-30 21:23:01 +00:00
assert ( node - > u . n . n_children > 2 ) ; // Must be at least two children.
u_int32_t i ;
assert ( childnum > 0 ) ;
node - > u . n . totalchildkeylens - = toku_brt_pivot_key_len ( pair - > brt , node - > u . n . childkeys [ childnum - 1 ] ) ;
toku_free ( ( void * ) node - > u . n . childkeys [ childnum - 1 ] ) ;
2008-01-31 22:05:43 +00:00
toku_fifo_free ( & BNC_BUFFER ( node , childnum ) ) ;
2008-01-30 21:23:01 +00:00
for ( i = childnum + 1 ; i < ( unsigned ) node - > u . n . n_children ; i + + ) {
node - > u . n . childinfos [ i - 1 ] = node - > u . n . childinfos [ i ] ;
2008-02-01 01:38:11 +00:00
BNC_NBYTESINBUF ( node , i - 1 ) = BNC_NBYTESINBUF ( node , i ) ;
2008-01-30 21:23:01 +00:00
node - > u . n . childkeys [ i - 2 ] = node - > u . n . childkeys [ i - 1 ] ;
}
node - > u . n . n_children - - ;
2008-02-08 22:16:02 +00:00
node - > log_lsn = lsn ;
r = toku_cachetable_unpin ( pair - > cf , diskoff , 1 , toku_serialize_brtnode_size ( node ) ) ;
2008-01-30 21:23:01 +00:00
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
toku_free ( pivotkey . data ) ;
2008-01-30 21:23:01 +00:00
}
2008-01-29 21:43:08 +00:00
2008-02-08 22:16:02 +00:00
void toku_recover_setchild ( LSN lsn , FILENUM filenum , DISKOFF diskoff , u_int32_t childnum , DISKOFF UU ( oldchild ) , DISKOFF newchild ) {
2008-01-17 19:03:37 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-17 19:03:37 +00:00
assert ( r = = 0 ) ;
void * node_v ;
assert ( pair - > brt ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_get_and_pin ( pair - > cf , diskoff , & node_v , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-17 19:03:37 +00:00
assert ( r = = 0 ) ;
BRTNODE node = node_v ;
assert ( node - > height > 0 ) ;
2008-02-08 22:16:02 +00:00
assert ( childnum < ( unsigned ) node - > u . n . n_children ) ;
BNC_DISKOFF ( node , childnum ) = newchild ;
node - > log_lsn = lsn ;
r = toku_cachetable_unpin ( pair - > cf , diskoff , 1 , toku_serialize_brtnode_size ( node ) ) ;
2008-01-17 19:03:37 +00:00
assert ( r = = 0 ) ;
}
2008-02-08 22:16:02 +00:00
void toku_recover_setpivot ( LSN lsn , FILENUM filenum , DISKOFF diskoff , u_int32_t childnum , BYTESTRING pivotkey ) {
2008-01-17 19:36:44 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-17 19:36:44 +00:00
assert ( r = = 0 ) ;
void * node_v ;
assert ( pair - > brt ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_get_and_pin ( pair - > cf , diskoff , & node_v , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-17 19:36:44 +00:00
assert ( r = = 0 ) ;
BRTNODE node = node_v ;
assert ( node - > height > 0 ) ;
2008-01-30 21:23:01 +00:00
2008-02-08 22:16:02 +00:00
struct kv_pair * new_pivot = kv_pair_malloc ( pivotkey . data , pivotkey . len , 0 , 0 ) ;
2008-01-30 21:23:01 +00:00
2008-02-08 22:16:02 +00:00
node - > u . n . childkeys [ childnum ] = new_pivot ;
node - > u . n . totalchildkeylens + = toku_brt_pivot_key_len ( pair - > brt , node - > u . n . childkeys [ childnum ] ) ;
2008-01-17 19:36:44 +00:00
2008-02-08 22:16:02 +00:00
node - > log_lsn = lsn ;
r = toku_cachetable_unpin ( pair - > cf , diskoff , 1 , toku_serialize_brtnode_size ( node ) ) ;
2008-01-17 19:36:44 +00:00
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
toku_free ( pivotkey . data ) ;
2008-01-17 19:36:44 +00:00
}
2008-01-17 15:41:42 +00:00
2008-02-08 22:16:02 +00:00
void toku_recover_changechildfingerprint ( LSN lsn , FILENUM filenum , DISKOFF diskoff , u_int32_t childnum , u_int32_t UU ( oldfingerprint ) , u_int32_t newfingerprint ) {
2008-01-23 18:06:23 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-23 18:06:23 +00:00
assert ( r = = 0 ) ;
void * node_v ;
assert ( pair - > brt ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_get_and_pin ( pair - > cf , diskoff , & node_v , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-23 18:06:23 +00:00
assert ( r = = 0 ) ;
BRTNODE node = node_v ;
assert ( node - > height > 0 ) ;
2008-02-08 22:16:02 +00:00
assert ( ( signed ) childnum < node - > u . n . n_children ) ;
BNC_SUBTREE_FINGERPRINT ( node , childnum ) = newfingerprint ;
node - > log_lsn = lsn ;
r = toku_cachetable_unpin ( pair - > cf , diskoff , 1 , toku_serialize_brtnode_size ( node ) ) ;
2008-01-23 18:06:23 +00:00
assert ( r = = 0 ) ;
}
2008-02-08 22:16:02 +00:00
void toku_recover_fopen ( LSN UU ( lsn ) , TXNID UU ( txnid ) , BYTESTRING fname , FILENUM filenum ) {
char * fixedfname = fixup_fname ( & fname ) ;
2008-01-11 03:09:14 +00:00
CACHEFILE cf ;
2008-02-08 22:16:02 +00:00
int fd = open ( fixedfname , O_RDWR , 0 ) ;
2008-01-11 03:09:14 +00:00
assert ( fd > = 0 ) ;
2008-02-26 17:47:40 +00:00
BRT MALLOC ( brt ) ;
assert ( errno = = 0 & & brt ! = 0 ) ;
brt - > database_name = fixedfname ;
brt - > h = 0 ;
list_init ( & brt - > cursors ) ;
brt - > compare_fun = 0 ;
brt - > dup_compare = 0 ;
brt - > db = 0 ;
int r = toku_cachetable_openfd ( & cf , ct , fd , brt ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
2008-02-26 17:47:40 +00:00
brt - > skey = brt - > sval = 0 ;
brt - > cf = cf ;
2008-02-27 07:14:03 +00:00
toku_recover_note_cachefile ( filenum , cf , brt ) ;
2008-02-08 22:16:02 +00:00
toku_free_BYTESTRING ( fname ) ;
2008-01-11 03:09:14 +00:00
}
2008-02-08 22:16:02 +00:00
void toku_recover_insertinleaf ( LSN lsn , TXNID UU ( txnid ) , FILENUM filenum , DISKOFF diskoff , u_int32_t pmaidx , BYTESTRING keybs , BYTESTRING databs ) {
2008-01-11 03:09:14 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
void * node_v ;
assert ( pair - > brt ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_get_and_pin ( pair - > cf , diskoff , & node_v , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
BRTNODE node = node_v ;
assert ( node - > height = = 0 ) ;
VERIFY_COUNTS ( node ) ;
DBT key , data ;
2008-02-08 22:16:02 +00:00
r = toku_pma_set_at_index ( node - > u . l . buffer , pmaidx , toku_fill_dbt ( & key , keybs . data , keybs . len ) , toku_fill_dbt ( & data , databs . data , databs . len ) ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
node - > local_fingerprint + = node - > rand4fingerprint * toku_calccrc32_kvpair ( keybs . data , keybs . len , databs . data , databs . len ) ;
node - > u . l . n_bytes_in_buffer + = PMA_ITEM_OVERHEAD + KEY_VALUE_OVERHEAD + keybs . len + databs . len ;
2008-01-11 03:09:14 +00:00
VERIFY_COUNTS ( node ) ;
2008-02-08 22:16:02 +00:00
node - > log_lsn = lsn ;
r = toku_cachetable_unpin ( pair - > cf , diskoff , 1 , toku_serialize_brtnode_size ( node ) ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
toku_free_BYTESTRING ( keybs ) ;
toku_free_BYTESTRING ( databs ) ;
2008-01-11 03:09:14 +00:00
}
2008-02-08 22:16:02 +00:00
void toku_recover_deleteinleaf ( LSN lsn , TXNID UU ( txnid ) , FILENUM filenum , DISKOFF diskoff , u_int32_t pmaidx , BYTESTRING keybs , BYTESTRING databs ) {
2008-01-25 21:50:07 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-25 21:50:07 +00:00
assert ( r = = 0 ) ;
void * node_v ;
assert ( pair - > brt ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_get_and_pin ( pair - > cf , diskoff , & node_v , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-25 21:50:07 +00:00
assert ( r = = 0 ) ;
BRTNODE node = node_v ;
assert ( node - > height = = 0 ) ;
VERIFY_COUNTS ( node ) ;
2008-02-08 22:16:02 +00:00
r = toku_pma_clear_at_index ( node - > u . l . buffer , pmaidx ) ;
2008-01-29 21:43:08 +00:00
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
node - > local_fingerprint - = node - > rand4fingerprint * toku_calccrc32_kvpair ( keybs . data , keybs . len , databs . data , databs . len ) ;
node - > u . l . n_bytes_in_buffer - = PMA_ITEM_OVERHEAD + KEY_VALUE_OVERHEAD + keybs . len + databs . len ;
2008-01-25 21:50:07 +00:00
VERIFY_COUNTS ( node ) ;
2008-02-08 22:16:02 +00:00
node - > log_lsn = lsn ;
r = toku_cachetable_unpin ( pair - > cf , diskoff , 1 , toku_serialize_brtnode_size ( node ) ) ;
2008-01-25 21:50:07 +00:00
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
toku_free_BYTESTRING ( keybs ) ;
toku_free_BYTESTRING ( databs ) ;
2008-01-25 21:50:07 +00:00
}
2008-02-27 07:14:03 +00:00
int toku_rollback_deleteboth ( FILENUM filenum ,
BYTESTRING key , BYTESTRING data , TOKUTXN txn ) {
CACHEFILE cf ;
BRT brt ;
int r = toku_cachefile_of_filenum ( txn - > logger - > ct , filenum , & cf , & brt ) ;
assert ( r = = 0 ) ;
DBT key_dbt , data_dbt ;
r = toku_brt_insert ( brt ,
toku_fill_dbt ( & key_dbt , key . data , key . len ) ,
toku_fill_dbt ( & data_dbt , data . data , data . len ) ,
txn ) ;
return r ;
}
2008-02-26 15:51:15 +00:00
int toku_rollback_delete ( FILENUM filenum ,
2008-02-27 07:14:03 +00:00
BYTESTRING key , BYTESTRING data , TOKUTXN txn ) {
2008-01-25 21:50:07 +00:00
CACHEFILE cf ;
BRT brt ;
2008-02-25 22:46:48 +00:00
int r = toku_cachefile_of_filenum ( txn - > logger - > ct , filenum , & cf , & brt ) ;
2008-01-25 21:50:07 +00:00
assert ( r = = 0 ) ;
2008-02-25 22:46:48 +00:00
DBT key_dbt , data_dbt ;
r = toku_brt_insert ( brt ,
toku_fill_dbt ( & key_dbt , key . data , key . len ) ,
toku_fill_dbt ( & data_dbt , data . data , data . len ) ,
txn ) ;
2008-01-25 21:50:07 +00:00
return r ;
}
2008-02-26 17:47:40 +00:00
int toku_rollback_insert ( FILENUM filenum ,
BYTESTRING key , BYTESTRING data , TOKUTXN txn ) {
CACHEFILE cf ;
BRT brt ;
int r = toku_cachefile_of_filenum ( txn - > logger - > ct , filenum , & cf , & brt ) ;
assert ( r = = 0 ) ;
DBT key_dbt , data_dbt ;
r = toku_brt_delete_both ( brt ,
toku_fill_dbt ( & key_dbt , key . data , key . len ) ,
toku_fill_dbt ( & data_dbt , data . data , data . len ) ,
2008-02-27 07:14:03 +00:00
0 ) ;
2008-02-26 17:47:40 +00:00
return r ;
}
2008-01-11 03:09:14 +00:00
// a newbrtnode should have been done before this
2008-02-08 22:16:02 +00:00
void toku_recover_resizepma ( LSN lsn , FILENUM filenum , DISKOFF diskoff , u_int32_t oldsize , u_int32_t newsize ) {
2008-01-11 03:09:14 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
void * node_v ;
assert ( pair - > brt ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_get_and_pin ( pair - > cf , diskoff , & node_v , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
BRTNODE node = node_v ;
assert ( node - > height = = 0 ) ;
2008-02-08 22:16:02 +00:00
r = toku_resize_pma_exactly ( node - > u . l . buffer , oldsize , newsize ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
VERIFY_COUNTS ( node ) ;
2008-02-08 22:16:02 +00:00
node - > log_lsn = lsn ;
r = toku_cachetable_unpin ( pair - > cf , diskoff , 1 , toku_serialize_brtnode_size ( node ) ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
}
2008-02-08 22:16:02 +00:00
void toku_recover_pmadistribute ( LSN lsn , FILENUM filenum , DISKOFF old_diskoff , DISKOFF new_diskoff , INTPAIRARRAY fromto ) {
2008-01-11 03:09:14 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
2008-01-16 13:50:23 +00:00
void * node_va , * node_vb ;
2008-01-11 03:09:14 +00:00
assert ( pair - > brt ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_get_and_pin ( pair - > cf , old_diskoff , & node_va , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_get_and_pin ( pair - > cf , new_diskoff , & node_vb , NULL , toku_brtnode_flush_callback , toku_brtnode_fetch_callback , pair - > brt ) ;
2008-01-16 13:50:23 +00:00
assert ( r = = 0 ) ;
BRTNODE nodea = node_va ; assert ( nodea - > height = = 0 ) ;
BRTNODE nodeb = node_vb ; assert ( nodeb - > height = = 0 ) ;
{
2008-01-11 03:09:14 +00:00
unsigned int i ;
2008-02-08 22:16:02 +00:00
for ( i = 0 ; i < fromto . size ; i + + ) {
assert ( fromto . array [ i ] . a < toku_pma_index_limit ( nodea - > u . l . buffer ) ) ;
assert ( fromto . array [ i ] . b < toku_pma_index_limit ( nodeb - > u . l . buffer ) ) ;
2008-01-11 03:09:14 +00:00
}
}
2008-02-08 22:16:02 +00:00
r = toku_pma_move_indices ( nodea - > u . l . buffer , nodeb - > u . l . buffer , fromto ,
2008-01-16 15:41:12 +00:00
nodea - > rand4fingerprint , & nodea - > local_fingerprint ,
nodeb - > rand4fingerprint , & nodeb - > local_fingerprint ,
& nodea - > u . l . n_bytes_in_buffer , & nodeb - > u . l . n_bytes_in_buffer
) ;
// The bytes in buffer and fingerprint shouldn't change
2008-01-11 03:09:14 +00:00
2008-01-16 13:50:23 +00:00
VERIFY_COUNTS ( nodea ) ;
VERIFY_COUNTS ( nodeb ) ;
2008-01-11 03:09:14 +00:00
2008-02-08 22:16:02 +00:00
nodea - > log_lsn = lsn ;
nodeb - > log_lsn = lsn ;
r = toku_cachetable_unpin ( pair - > cf , old_diskoff , 1 , toku_serialize_brtnode_size ( nodea ) ) ;
2008-01-11 03:09:14 +00:00
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
r = toku_cachetable_unpin ( pair - > cf , new_diskoff , 1 , toku_serialize_brtnode_size ( nodeb ) ) ;
2008-01-16 13:50:23 +00:00
assert ( r = = 0 ) ;
2008-01-11 03:09:14 +00:00
2008-02-08 22:16:02 +00:00
toku_free_INTPAIRARRAY ( fromto ) ;
2008-01-11 03:09:14 +00:00
}
2008-02-08 22:16:02 +00:00
void toku_recover_changeunnamedroot ( LSN UU ( lsn ) , FILENUM filenum , DISKOFF UU ( oldroot ) , DISKOFF newroot ) {
2008-01-18 21:28:27 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-18 21:28:27 +00:00
assert ( r = = 0 ) ;
assert ( pair - > brt ) ;
r = toku_read_and_pin_brt_header ( pair - > cf , & pair - > brt - > h ) ;
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
pair - > brt - > h - > unnamed_root = newroot ;
2008-01-18 21:28:27 +00:00
r = toku_unpin_brt_header ( pair - > brt ) ;
}
2008-02-08 22:16:02 +00:00
void toku_recover_changenamedroot ( LSN UU ( lsn ) , FILENUM UU ( filenum ) , BYTESTRING UU ( name ) , DISKOFF UU ( oldroot ) , DISKOFF UU ( newroot ) ) { assert ( 0 ) ; }
2008-01-18 21:28:27 +00:00
2008-02-08 22:16:02 +00:00
void toku_recover_changeunusedmemory ( LSN UU ( lsn ) , FILENUM filenum , DISKOFF UU ( oldunused ) , DISKOFF newunused ) {
2008-01-18 21:28:27 +00:00
struct cf_pair * pair ;
2008-02-08 22:16:02 +00:00
int r = find_cachefile ( filenum , & pair ) ;
2008-01-18 21:28:27 +00:00
assert ( r = = 0 ) ;
assert ( pair - > brt ) ;
r = toku_read_and_pin_brt_header ( pair - > cf , & pair - > brt - > h ) ;
assert ( r = = 0 ) ;
2008-02-08 22:16:02 +00:00
pair - > brt - > h - > unused_memory = newunused ;
2008-01-18 21:28:27 +00:00
r = toku_unpin_brt_header ( pair - > brt ) ;
}
2008-01-23 18:06:23 +00:00