2007-11-29 14:18:54 +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."
2007-11-29 14:18:54 +00:00
2007-11-22 05:09:29 +00:00
/* This file defines the logformat in an executable fashion.
* This code is used to generate
* The code that writes into the log .
* The code that reads the log and prints it to stdout ( the log_print utility )
* The code that reads the log for recovery .
* The struct definitions .
* The Latex documentation .
*/
2013-04-16 23:57:21 -04:00
# include "portability.h"
2013-04-16 23:57:21 -04:00
# include <assert.h>
2007-11-27 10:48:31 +00:00
# include <ctype.h>
2007-11-22 06:13:26 +00:00
# include <stdarg.h>
2007-11-22 07:13:08 +00:00
# include <stdio.h>
2008-01-18 21:28:27 +00:00
# include <stdlib.h>
2007-11-27 10:48:31 +00:00
# include <string.h>
2007-11-22 07:13:08 +00:00
# include <sys/stat.h>
# include <sys/types.h>
2013-04-16 23:57:21 -04:00
# if !defined(TOKU_WINDOWS)
2007-11-22 07:13:08 +00:00
# include <unistd.h>
2013-04-16 23:57:21 -04:00
# endif
2007-11-22 05:09:29 +00:00
typedef struct field {
char * type ;
char * name ;
2007-11-27 10:48:31 +00:00
char * format ; // optional format string
2007-11-22 05:09:29 +00:00
} F ;
2007-11-27 10:48:31 +00:00
# define NULLFIELD {0,0,0}
2007-11-22 05:09:29 +00:00
# define FA (F[])
struct logtype {
char * name ;
2008-02-14 19:23:25 +00:00
unsigned int command_and_flags ;
2007-11-22 05:09:29 +00:00
struct field * fields ;
} ;
// In the fields, don't mention the command, the LSN, the CRC or the trailing LEN.
2007-11-23 02:51:45 +00:00
int logformat_version_number = 0 ;
2008-02-26 15:51:15 +00:00
const struct logtype rollbacks [ ] = {
2008-04-07 01:30:25 +00:00
{ " fcreate " , ' F ' , FA { { " TXNID " , " xid " , 0 } ,
{ " BYTESTRING " , " fname " , 0 } ,
2008-02-26 15:51:15 +00:00
NULLFIELD } } ,
2008-04-07 01:30:25 +00:00
{ " cmdinsert " , ' i ' , FA { { " TXNID " , " xid " , 0 } ,
{ " FILENUM " , " filenum " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
NULLFIELD } } ,
{ " cmddeleteboth " , ' D ' , FA { { " TXNID " , " xid " , 0 } ,
{ " FILENUM " , " filenum " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
NULLFIELD } } ,
{ " cmddelete " , ' d ' , FA { { " TXNID " , " xid " , 0 } ,
{ " FILENUM " , " filenum " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
NULLFIELD } } ,
2008-04-22 17:09:24 +00:00
{ " rollinclude " , ' I ' , FA { { " BYTESTRING " , " fname " , 0 } ,
NULLFIELD } } ,
2008-04-02 23:40:36 +00:00
// {"fclose", 'c', FA{{"FILENUM", "filenum", 0},
// {"BYTESTRING", "fname", 0},
// NULLFIELD}},
2008-04-07 01:30:25 +00:00
// {"deleteatleaf", 'd', FA{{"FILENUM", "filenum", 0}, // Note a delete for rollback. The delete takes place in a leaf.
// {"BYTESTRING", "key", 0},
// {"BYTESTRING", "data", 0},
// NULLFIELD}},
// {"insertatleaf", 'i', FA{{"FILENUM", "filenum", 0}, // Note an insert for rollback. The insert takes place in a leaf.
// {"BYTESTRING", "key", 0},
// {"BYTESTRING", "data", 0},
// NULLFIELD}},
// {"xactiontouchednonleaf", 'n', FA{{"FILENUM", "filenum", 0},
// {"DISKOFFARRAY", "parents", 0},
// {"DISKOFF", "diskoff", 0},
// NULLFIELD}},
2008-02-27 07:14:03 +00:00
{ 0 , 0 , FA { NULLFIELD } }
2008-02-26 15:51:15 +00:00
} ;
2007-11-22 05:09:29 +00:00
const struct logtype logtypes [ ] = {
2008-03-21 19:40:32 +00:00
{ " checkpoint " , ' x ' , FA { NULLFIELD } } ,
2007-11-27 10:48:31 +00:00
{ " commit " , ' C ' , FA { { " TXNID " , " txnid " , 0 } , NULLFIELD } } ,
2008-04-21 04:22:45 +00:00
{ " xabort " , ' q ' , FA { { " TXNID " , " txnid " , 0 } , NULLFIELD } } ,
2008-03-21 21:02:30 +00:00
{ " xbegin " , ' b ' , FA { { " TXNID " , " parenttxnid " , 0 } , NULLFIELD } } ,
2008-02-29 20:47:11 +00:00
#if 0
{ " tl_delete " , ' D ' , FA { { " FILENUM " , " filenum " , 0 } , // tl logentries can be used, by themselves, to rebuild the whole DB from scratch.
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2007-11-27 10:48:31 +00:00
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
2007-11-22 05:09:29 +00:00
NULLFIELD } } ,
2008-02-29 20:47:11 +00:00
# endif
2008-02-26 15:51:15 +00:00
{ " fcreate " , ' F ' , FA { { " TXNID " , " txnid " , 0 } ,
{ " BYTESTRING " , " fname " , 0 } ,
{ " u_int32_t " , " mode " , " 0%o " } ,
NULLFIELD } } ,
2008-02-14 19:23:25 +00:00
{ " fheader " , ' H ' , FA { { " TXNID " , " txnid " , 0 } ,
{ " FILENUM " , " filenum " , 0 } ,
{ " LOGGEDBRTHEADER " , " header " , 0 } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " newbrtnode " , ' N ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2007-11-27 10:48:31 +00:00
{ " u_int32_t " , " height " , 0 } ,
{ " u_int32_t " , " nodesize " , 0 } ,
{ " u_int8_t " , " is_dup_sort " , 0 } ,
2008-01-23 18:06:23 +00:00
{ " u_int32_t " , " rand4fingerprint " , " %08x " } ,
2007-11-23 17:16:26 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " changeunnamedroot " , ' u ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " oldroot " , 0 } ,
{ " BLOCKNUM " , " newroot " , 0 } ,
2008-02-08 19:54:00 +00:00
NULLFIELD } } ,
{ " changenamedroot " , ' n ' , FA { { " FILENUM " , " filenum " , 0 } ,
2008-01-18 21:28:27 +00:00
{ " BYTESTRING " , " name " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " oldroot " , 0 } ,
{ " BLOCKNUM " , " newroot " , 0 } ,
2008-01-18 21:28:27 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " changeunusedmemory " , ' m ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " oldunused " , 0 } ,
{ " BLOCKNUM " , " newunused " , 0 } ,
2008-01-18 21:28:27 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " addchild " , ' c ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2008-01-17 19:03:37 +00:00
{ " u_int32_t " , " childnum " , 0 } , // children scoot over
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " child " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " u_int32_t " , " childfingerprint " , " %08x " } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " delchild " , ' r ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " u_int32_t " , " childnum " , 0 } , // children scoot over
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " child " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " u_int32_t " , " childfingerprint " , " %08x " } ,
{ " BYTESTRING " , " pivotkey " , 0 } ,
2008-01-17 19:03:37 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " setchild " , ' i ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2008-01-17 19:03:37 +00:00
{ " u_int32_t " , " childnum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " oldchild " , 0 } ,
{ " BLOCKNUM " , " newchild " , 0 } ,
2008-01-17 19:03:37 +00:00
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " setpivot " , ' k ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2008-01-17 19:03:37 +00:00
{ " u_int32_t " , " childnum " , 0 } ,
{ " BYTESTRING " , " pivotkey " , 0 } ,
NULLFIELD } } ,
2007-11-27 10:48:31 +00:00
{ " fopen " , ' O ' , FA { { " TXNID " , " txnid " , 0 } ,
{ " BYTESTRING " , " fname " , 0 } ,
{ " FILENUM " , " filenum " , 0 } ,
2007-11-22 21:11:21 +00:00
NULLFIELD } } ,
2008-04-17 03:11:55 +00:00
{ " brtclose " , ' e ' , FA { { " BYTESTRING " , " fname " , 0 } , // brtclose is logged when a particular brt is closed
{ " FILENUM " , " filenum " , 0 } ,
NULLFIELD } } ,
{ " cfclose " , ' o ' , FA { { " BYTESTRING " , " fname " , 0 } , // cfclose is logged when a cachefile actually closes ("cfclose" means cache file close)
{ " FILENUM " , " filenum " , 0 } ,
NULLFIELD } } ,
2008-05-02 14:38:35 +00:00
// Note that brtdeq and brtenq don't name the new size or fingerprint. We can calculate them properly.
2008-02-08 19:54:00 +00:00
{ " brtdeq " , ' U ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " u_int32_t " , " childnum " , 0 } ,
NULLFIELD } } ,
2008-02-08 19:54:00 +00:00
{ " brtenq " , ' Q ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " u_int32_t " , " childnum " , 0 } ,
2008-02-08 19:54:00 +00:00
{ " TXNID " , " xid " , 0 } ,
2008-01-29 21:43:08 +00:00
{ " u_int32_t " , " typ " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
NULLFIELD } } ,
2008-04-07 01:30:25 +00:00
// {"insertinleaf", 'I', FA{{"TXNID", "txnid", 0},
// {"FILENUM", "filenum", 0},
2013-04-16 23:57:18 -04:00
// {"BLOCKNUM", "blocknum", 0},
2008-04-07 01:30:25 +00:00
// {"u_int32_t", "pmaidx", 0},
// {"BYTESTRING", "key", 0},
// {"BYTESTRING", "data", 0},
// NULLFIELD}},
// {"replaceleafentry", 'L', FA{{"FILENUM", "filenum", 0},
2013-04-16 23:57:18 -04:00
// {"BLOCKNUM", "blocknum", 0},
2008-04-07 01:30:25 +00:00
// {"u_int32_t", "pmaidx", 0},
// {"LEAFENTRY", "oldleafentry", 0},
// {"LEAFENTRY", "newleafentry", 0},
// NULLFIELD}},
2008-04-09 02:45:27 +00:00
{ " enqrootentry " , ' a ' , FA { { " FILENUM " , " filenum " , 0 } ,
{ " TXNID " , " xid " , 0 } ,
{ " u_int32_t " , " typ " , 0 } ,
{ " BYTESTRING " , " key " , 0 } ,
{ " BYTESTRING " , " data " , 0 } ,
NULLFIELD } } ,
{ " deqrootentry " , ' A ' , FA { { " FILENUM " , " filenum " , 0 } ,
NULLFIELD } } ,
2008-04-07 01:30:25 +00:00
{ " insertleafentry " , ' I ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2008-04-22 20:39:50 +00:00
{ " u_int32_t " , " idx " , 0 } ,
2008-04-07 01:30:25 +00:00
{ " LEAFENTRY " , " newleafentry " , 0 } ,
NULLFIELD } } ,
{ " deleteleafentry " , ' D ' , FA { { " FILENUM " , " filenum " , 0 } ,
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " blocknum " , 0 } ,
2008-04-22 20:39:50 +00:00
{ " u_int32_t " , " idx " , 0 } ,
2008-04-07 01:30:25 +00:00
NULLFIELD } } ,
2008-04-22 20:39:50 +00:00
{ " leafsplit " , ' s ' , FA { { " FILENUM " , " filenum " , 0 } , // log the creation of a new node by splitting stuff out of an old node
2013-04-16 23:57:18 -04:00
{ " BLOCKNUM " , " old_blocknum " , 0 } ,
{ " BLOCKNUM " , " new_blocknum " , 0 } ,
2008-04-22 20:39:50 +00:00
{ " u_int32_t " , " old_n " , 0 } ,
{ " u_int32_t " , " split_at " , 0 } ,
{ " u_int32_t " , " new_nodesize " , 0 } ,
{ " u_int32_t " , " new_rand4 " , " %08x " } ,
{ " u_int8_t " , " is_dupsort " , 0 } ,
NULLFIELD } } ,
2007-11-22 05:09:29 +00:00
{ 0 , 0 , FA { NULLFIELD } }
} ;
2008-02-26 15:51:15 +00:00
2013-04-16 23:57:21 -04:00
# define DO_STRUCTS(lt, array, body) do { \
2007-11-22 05:09:29 +00:00
const struct logtype * lt ; \
2008-02-26 15:51:15 +00:00
for ( lt = & array [ 0 ] ; lt - > name ; lt + + ) { \
2007-11-22 05:09:29 +00:00
body ; \
2013-04-16 23:57:21 -04:00
} } while ( 0 )
2007-11-22 05:09:29 +00:00
2008-02-26 15:51:15 +00:00
# define DO_ROLLBACKS(lt, body) DO_STRUCTS(lt, rollbacks, body)
# define DO_LOGTYPES(lt, body) DO_STRUCTS(lt, logtypes, body)
# define DO_LOGTYPES_AND_ROLLBACKS(lt, body) (DO_ROLLBACKS(lt,body), DO_LOGTYPES(lt, body))
2013-04-16 23:57:21 -04:00
# define DO_FIELDS(fld, lt, body) do { \
2007-11-22 05:09:29 +00:00
struct field * fld ; \
for ( fld = lt - > fields ; fld - > type ; fld + + ) { \
body ; \
2013-04-16 23:57:21 -04:00
} } while ( 0 )
2007-11-22 05:09:29 +00:00
2008-02-26 15:51:15 +00:00
2008-04-02 23:40:36 +00:00
static void __attribute__ ( ( format ( printf , 3 , 4 ) ) ) fprintf2 ( FILE * f1 , FILE * f2 , const char * format , . . . ) {
2007-11-22 06:13:26 +00:00
va_list ap ;
int r ;
va_start ( ap , format ) ;
r = vfprintf ( f1 , format , ap ) ; assert ( r > = 0 ) ;
2007-11-25 14:32:52 +00:00
va_end ( ap ) ;
va_start ( ap , format ) ;
2007-11-22 06:13:26 +00:00
r = vfprintf ( f2 , format , ap ) ; assert ( r > = 0 ) ;
va_end ( ap ) ;
}
FILE * hf = 0 , * cf = 0 ;
2013-04-16 23:57:20 -04:00
static void
generate_enum_internal ( char * enum_name , char * enum_prefix , const struct logtype * lts ) {
2008-01-18 21:28:27 +00:00
char used_cmds [ 256 ] ;
2007-11-22 06:13:26 +00:00
int count = 0 ;
2008-01-18 21:28:27 +00:00
memset ( used_cmds , 0 , 256 ) ;
2008-02-26 15:51:15 +00:00
fprintf ( hf , " enum %s { " , enum_name ) ;
DO_STRUCTS ( lt , lts ,
2013-04-16 23:57:21 -04:00
{
2013-04-16 23:57:20 -04:00
unsigned char cmd = ( unsigned char ) ( lt - > command_and_flags & 0xff ) ;
2007-11-22 06:13:26 +00:00
if ( count ! = 0 ) fprintf ( hf , " , " ) ;
count + + ;
fprintf ( hf , " \n " ) ;
2008-02-26 15:51:15 +00:00
fprintf ( hf , " %s_%-16s = '%c' " , enum_prefix , lt - > name , cmd ) ;
2008-04-17 03:11:55 +00:00
if ( used_cmds [ cmd ] ! = 0 ) { fprintf ( stderr , " %s:%d: error: Command %d (%c) was used twice (second time for %s) \n " , __FILE__ , __LINE__ , cmd , cmd , lt - > name ) ; abort ( ) ; }
2008-02-14 19:23:25 +00:00
used_cmds [ cmd ] = 1 ;
2013-04-16 23:57:21 -04:00
} ) ;
2007-11-22 06:13:26 +00:00
fprintf ( hf , " \n }; \n \n " ) ;
2008-02-26 15:51:15 +00:00
}
2013-04-16 23:57:20 -04:00
static void
generate_enum ( void ) {
2008-02-26 15:51:15 +00:00
generate_enum_internal ( " lt_cmd " , " LT " , logtypes ) ;
generate_enum_internal ( " rt_cmd " , " RT " , rollbacks ) ;
2007-11-22 06:13:26 +00:00
}
2013-04-16 23:57:20 -04:00
static void
generate_log_struct ( void ) {
2007-11-22 05:09:29 +00:00
DO_LOGTYPES ( lt ,
2013-04-16 23:57:21 -04:00
{ fprintf ( hf , " struct logtype_%s { \n " , lt - > name ) ;
2007-11-22 06:13:26 +00:00
fprintf ( hf , " %-16s lsn; \n " , " LSN " ) ;
2007-11-22 05:09:29 +00:00
DO_FIELDS ( ft , lt ,
2007-11-22 06:13:26 +00:00
fprintf ( hf , " %-16s %s; \n " , ft - > type , ft - > name ) ) ;
2007-11-22 07:13:08 +00:00
fprintf ( hf , " %-16s crc; \n " , " u_int32_t " ) ;
fprintf ( hf , " %-16s len; \n " , " u_int32_t " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( hf , " }; \n " ) ;
2008-03-14 19:14:31 +00:00
//fprintf(hf, "void toku_recover_%s (LSN lsn", lt->name);
//DO_FIELDS(ft, lt, fprintf(hf, ", %s %s", ft->type, ft->name));
//fprintf(hf, ");\n");
2013-04-16 23:57:21 -04:00
} ) ;
2008-02-26 15:51:15 +00:00
DO_ROLLBACKS ( lt ,
2013-04-16 23:57:21 -04:00
{ fprintf ( hf , " struct rolltype_%s { \n " , lt - > name ) ;
2008-02-26 15:51:15 +00:00
DO_FIELDS ( ft , lt ,
fprintf ( hf , " %-16s %s; \n " , ft - > type , ft - > name ) ) ;
fprintf ( hf , " }; \n " ) ;
fprintf ( hf , " int toku_rollback_%s ( " , lt - > name ) ;
DO_FIELDS ( ft , lt , fprintf ( hf , " %s %s, " , ft - > type , ft - > name ) ) ;
fprintf ( hf , " TOKUTXN txn); \n " ) ;
2008-04-07 01:30:25 +00:00
fprintf ( hf , " int toku_commit_%s ( " , lt - > name ) ;
DO_FIELDS ( ft , lt , fprintf ( hf , " %s %s, " , ft - > type , ft - > name ) ) ;
fprintf ( hf , " TOKUTXN txn); \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2007-11-23 18:27:50 +00:00
fprintf ( hf , " struct log_entry { \n " ) ;
fprintf ( hf , " enum lt_cmd cmd; \n " ) ;
fprintf ( hf , " union { \n " ) ;
DO_LOGTYPES ( lt , fprintf ( hf , " struct logtype_%s %s; \n " , lt - > name , lt - > name ) ) ;
fprintf ( hf , " } u; \n " ) ;
fprintf ( hf , " }; \n " ) ;
2008-02-26 15:51:15 +00:00
fprintf ( hf , " struct roll_entry { \n " ) ;
fprintf ( hf , " enum rt_cmd cmd; \n " ) ;
fprintf ( hf , " union { \n " ) ;
DO_ROLLBACKS ( lt , fprintf ( hf , " struct rolltype_%s %s; \n " , lt - > name , lt - > name ) ) ;
fprintf ( hf , " } u; \n " ) ;
fprintf ( hf , " struct roll_entry *prev; /* for in-memory list of log entries. Threads from newest to oldest. */ \n " ) ;
2008-04-21 04:22:45 +00:00
fprintf ( hf , " struct roll_entry *next; /* Points to a newer logentry. Needed for flushing to disk, since we want to write the oldest one first. */ \n " ) ;
2008-02-26 15:51:15 +00:00
fprintf ( hf , " }; \n " ) ;
2007-11-22 05:09:29 +00:00
}
2013-04-16 23:57:20 -04:00
static void
generate_dispatch ( void ) {
2008-02-26 15:51:15 +00:00
fprintf ( hf , " #define rolltype_dispatch(s, funprefix) ({ switch((s)->cmd) { \\ \n " ) ;
DO_ROLLBACKS ( lt , fprintf ( hf , " case RT_%s: funprefix ## %s (&(s)->u.%s); break; \\ \n " , lt - > name , lt - > name , lt - > name ) ) ;
2007-11-23 20:36:03 +00:00
fprintf ( hf , " }}) \n " ) ;
2008-01-10 13:41:58 +00:00
2013-04-16 23:57:21 -04:00
fprintf ( hf , " #define logtype_dispatch_assign(s, funprefix, var, ...) do { switch((s)->cmd) { \\ \n " ) ;
DO_LOGTYPES ( lt , fprintf ( hf , " case LT_%s: var = funprefix ## %s (&(s)->u.%s, __VA_ARGS__); break; \\ \n " , lt - > name , lt - > name , lt - > name ) ) ;
2013-04-16 23:57:21 -04:00
fprintf ( hf , " }} while (0) \n " ) ;
2008-01-10 13:41:58 +00:00
2013-04-16 23:57:21 -04:00
fprintf ( hf , " #define rolltype_dispatch_assign(s, funprefix, var, ...) do { \\ \n " ) ;
2008-02-14 19:23:25 +00:00
fprintf ( hf , " switch((s)->cmd) { \\ \n " ) ;
2013-04-16 23:57:21 -04:00
DO_ROLLBACKS ( lt , {
2008-02-26 15:51:15 +00:00
fprintf ( hf , " case RT_%s: var = funprefix ## %s ( " , lt - > name , lt - > name ) ;
2008-02-14 19:23:25 +00:00
int fieldcount = 0 ;
2013-04-16 23:57:21 -04:00
DO_FIELDS ( ft , lt , {
2008-02-14 19:23:25 +00:00
if ( fieldcount > 0 ) fprintf ( hf , " , " ) ;
fprintf ( hf , " (s)->u.%s.%s " , lt - > name , ft - > name ) ;
fieldcount + + ;
2013-04-16 23:57:21 -04:00
} ) ;
2013-04-16 23:57:21 -04:00
fprintf ( hf , " , __VA_ARGS__); break; \\ \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
fprintf ( hf , " default: assert(0);} } while (0) \n " ) ;
2008-02-14 19:23:25 +00:00
2013-04-16 23:57:21 -04:00
fprintf ( hf , " #define logtype_dispatch_args(s, funprefix) do { switch((s)->cmd) { \\ \n " ) ;
2008-02-08 22:16:02 +00:00
DO_LOGTYPES ( lt ,
2013-04-16 23:57:21 -04:00
{
2008-02-08 22:16:02 +00:00
fprintf ( hf , " case LT_%s: funprefix ## %s ((s)->u.%s.lsn " , lt - > name , lt - > name , lt - > name ) ;
DO_FIELDS ( ft , lt , fprintf ( hf , " ,(s)->u.%s.%s " , lt - > name , ft - > name ) ) ;
fprintf ( hf , " ); break; \\ \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
fprintf ( hf , " }} while (0) \n " ) ;
2007-11-23 20:36:03 +00:00
}
2013-04-16 23:57:20 -04:00
static void
generate_log_writer ( void ) {
2013-04-16 23:57:21 -04:00
DO_LOGTYPES ( lt , {
2008-03-21 21:02:30 +00:00
fprintf2 ( cf , hf , " int toku_log_%s (TOKULOGGER logger, LSN *lsnp, int do_fsync " , lt - > name ) ;
2008-02-14 19:23:25 +00:00
DO_FIELDS ( ft , lt , fprintf2 ( cf , hf , " , %s %s " , ft - > type , ft - > name ) ) ;
2007-11-22 06:13:26 +00:00
fprintf ( hf , " ); \n " ) ;
fprintf ( cf , " ) { \n " ) ;
2008-02-08 19:54:00 +00:00
fprintf ( cf , " if (logger==0) return 0; \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " const unsigned int buflen= (+4 // len at the beginning \n " ) ;
fprintf ( cf , " +1 // log command \n " ) ;
2007-11-22 18:45:22 +00:00
fprintf ( cf , " +8 // lsn \n " ) ;
2007-11-22 05:09:29 +00:00
DO_FIELDS ( ft , lt ,
2007-11-22 18:45:22 +00:00
fprintf ( cf , " +toku_logsizeof_%s(%s) \n " , ft - > type , ft - > name ) ) ;
fprintf ( cf , " +8 // crc + len \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " ); \n " ) ;
fprintf ( cf , " struct wbuf wbuf; \n " ) ;
2008-03-12 17:55:11 +00:00
fprintf ( cf , " struct logbytes *lbytes = MALLOC_LOGBYTES(buflen); \n " ) ;
fprintf ( cf , " if (lbytes==0) return errno; \n " ) ;
fprintf ( cf , " wbuf_init(&wbuf, &lbytes->bytes[0], buflen); \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " wbuf_int(&wbuf, buflen); \n " ) ;
2013-04-16 23:57:20 -04:00
fprintf ( cf , " wbuf_char(&wbuf, '%c'); \n " , ( char ) ( 0xff & lt - > command_and_flags ) ) ;
2008-03-12 17:55:11 +00:00
fprintf ( cf , " ml_lock(&logger->input_lock); \n " ) ;
2008-04-17 03:11:55 +00:00
fprintf ( cf , " logger->lsn.lsn++; \n " ) ;
2008-03-12 17:55:11 +00:00
fprintf ( cf , " LSN lsn = logger->lsn; \n " ) ;
fprintf ( cf , " wbuf_LSN(&wbuf, lsn); \n " ) ;
fprintf ( cf , " lbytes->lsn = lsn; \n " ) ;
2008-03-21 21:02:30 +00:00
fprintf ( cf , " if (lsnp) *lsnp=logger->lsn; \n " ) ;
2007-11-22 05:09:29 +00:00
DO_FIELDS ( ft , lt ,
2007-11-22 06:13:26 +00:00
fprintf ( cf , " wbuf_%s(&wbuf, %s); \n " , ft - > type , ft - > name ) ) ;
2008-03-12 17:55:11 +00:00
fprintf ( cf , " int r= toku_logger_finish(logger, lbytes, &wbuf, do_fsync); \n " ) ;
2007-11-22 07:13:08 +00:00
fprintf ( cf , " assert(wbuf.ndone==buflen); \n " ) ;
2008-02-08 19:54:00 +00:00
fprintf ( cf , " return r; \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " } \n \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2007-11-22 05:09:29 +00:00
}
2013-04-16 23:57:20 -04:00
static void
generate_log_reader ( void ) {
2013-04-16 23:57:21 -04:00
DO_LOGTYPES ( lt , {
2008-07-27 22:16:49 +00:00
fprintf ( cf , " static int toku_log_fread_%s (FILE *infile, struct logtype_%s *data, struct x1764 *checksum) " , lt - > name , lt - > name ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " { \n " ) ;
2007-11-22 18:45:22 +00:00
fprintf ( cf , " int r=0; \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " u_int32_t actual_len=5; // 1 for the command, 4 for the first len. \n " ) ;
2008-07-27 22:16:49 +00:00
fprintf ( cf , " r=toku_fread_%-16s(infile, &data->%-16s, checksum, &actual_len); if (r!=0) return r; \n " , " LSN " , " lsn " ) ;
2007-11-22 06:13:26 +00:00
DO_FIELDS ( ft , lt ,
2008-07-27 22:16:49 +00:00
fprintf ( cf , " r=toku_fread_%-16s(infile, &data->%-16s, checksum, &actual_len); if (r!=0) return r; \n " , ft - > type , ft - > name ) ) ;
fprintf ( cf , " u_int32_t checksum_in_file, len_in_file; \n " ) ;
fprintf ( cf , " r=toku_fread_u_int32_t_nocrclen(infile, &checksum_in_file); actual_len+=4; if (r!=0) return r; \n " ) ;
fprintf ( cf , " r=toku_fread_u_int32_t_nocrclen(infile, &len_in_file); actual_len+=4; if (r!=0) return r; \n " ) ;
fprintf ( cf , " if (checksum_in_file!=x1764_finish(checksum) || len_in_file!=actual_len) return DB_BADFORMAT; \n " ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " return 0; \n " ) ;
fprintf ( cf , " } \n \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2007-11-29 18:14:40 +00:00
fprintf2 ( cf , hf , " int toku_log_fread (FILE *infile, struct log_entry *le) " ) ;
2007-11-23 18:27:50 +00:00
fprintf ( hf , " ; \n " ) ;
fprintf ( cf , " { \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " u_int32_t len1; int r; \n " ) ;
2008-07-27 22:16:49 +00:00
fprintf ( cf , " u_int32_t ignorelen=0; \n " ) ;
fprintf ( cf , " struct x1764 checksum; \n " ) ;
fprintf ( cf , " x1764_init(&checksum); \n " ) ;
fprintf ( cf , " r = toku_fread_u_int32_t(infile, &len1, &checksum, &ignorelen); if (r!=0) return r; \n " ) ;
2007-11-23 18:27:50 +00:00
fprintf ( cf , " int cmd=fgetc(infile); \n " ) ;
fprintf ( cf , " if (cmd==EOF) return EOF; \n " ) ;
2013-04-16 23:57:20 -04:00
fprintf ( cf , " char cmdchar = (char)cmd; \n " ) ;
2008-07-27 22:16:49 +00:00
fprintf ( cf , " x1764_add(&checksum, &cmdchar, 1); \n " ) ;
2013-04-16 23:57:20 -04:00
fprintf ( cf , " le->cmd=(enum lt_cmd)cmd; \n " ) ;
2007-11-23 18:27:50 +00:00
fprintf ( cf , " switch ((enum lt_cmd)cmd) { \n " ) ;
2013-04-16 23:57:21 -04:00
DO_LOGTYPES ( lt , {
2007-11-23 18:27:50 +00:00
fprintf ( cf , " case LT_%s: \n " , lt - > name ) ;
2008-07-27 22:16:49 +00:00
fprintf ( cf , " return toku_log_fread_%s (infile, &le->u.%s, &checksum); \n " , lt - > name , lt - > name ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2007-11-23 18:27:50 +00:00
fprintf ( cf , " }; \n " ) ;
fprintf ( cf , " return DB_BADFORMAT; \n " ) ; // Should read past the record using the len field.
fprintf ( cf , " } \n \n " ) ;
2007-11-22 06:13:26 +00:00
}
2013-04-16 23:57:20 -04:00
static void
generate_logprint ( void ) {
2007-11-27 10:48:31 +00:00
unsigned maxnamelen = 0 ;
2007-11-22 20:35:21 +00:00
fprintf2 ( cf , hf , " int toku_logprint_one_record(FILE *outf, FILE *f) " ) ;
fprintf ( hf , " ; \n " ) ;
fprintf ( cf , " { \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( cf , " int cmd, r; \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " u_int32_t len1, crc_in_file; \n " ) ;
2008-07-27 22:16:49 +00:00
fprintf ( cf , " u_int32_t ignorelen=0; \n " ) ;
fprintf ( cf , " struct x1764 checksum; \n " ) ;
fprintf ( cf , " x1764_init(&checksum); \n " ) ;
fprintf ( cf , " r=toku_fread_u_int32_t(f, &len1, &checksum, &ignorelen); \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " if (r==EOF) return EOF; \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( cf , " cmd=fgetc(f); \n " ) ;
2007-11-24 23:21:02 +00:00
fprintf ( cf , " if (cmd==EOF) return DB_BADFORMAT; \n " ) ;
fprintf ( cf , " u_int32_t len_in_file, len=1+4; // cmd + len1 \n " ) ;
2013-04-16 23:57:20 -04:00
fprintf ( cf , " char charcmd = (char)cmd; \n " ) ;
2008-07-27 22:16:49 +00:00
fprintf ( cf , " x1764_add(&checksum, &charcmd, 1); \n " ) ;
2007-11-22 07:13:08 +00:00
fprintf ( cf , " switch ((enum lt_cmd)cmd) { \n " ) ;
2013-04-16 23:57:21 -04:00
DO_LOGTYPES ( lt , { if ( strlen ( lt - > name ) > maxnamelen ) maxnamelen = strlen ( lt - > name ) ; } ) ;
DO_LOGTYPES ( lt , {
2013-04-16 23:57:20 -04:00
unsigned char cmd = ( unsigned char ) ( 0xff & lt - > command_and_flags ) ;
2008-02-14 19:23:25 +00:00
fprintf ( cf , " case LT_%s: \n " , lt - > name ) ;
// We aren't using the log reader here because we want better diagnostics as soon as things go wrong.
2013-04-16 23:57:20 -04:00
fprintf ( cf , " fprintf(outf, \" %%-%us \" , \" %s \" ); \n " , maxnamelen , lt - > name ) ;
2008-02-14 19:23:25 +00:00
if ( isprint ( cmd ) ) fprintf ( cf , " fprintf(outf, \" '%c': \" ); \n " , cmd ) ;
else fprintf ( cf , " fprintf(outf, \" 0%03o: \" ) ; \ n " , cmd);
2008-07-27 22:16:49 +00:00
fprintf ( cf , " r = toku_logprint_%-16s(outf, f, \" lsn \" , &checksum, &len, 0); if (r!=0) return r; \n " , " LSN " ) ;
2013-04-16 23:57:21 -04:00
DO_FIELDS ( ft , lt , {
2008-07-27 22:16:49 +00:00
fprintf ( cf , " r = toku_logprint_%-16s(outf, f, \" %s \" , &checksum, &len, " , ft - > type , ft - > name ) ;
2008-02-14 19:23:25 +00:00
if ( ft - > format ) fprintf ( cf , " \" %s \" " , ft - > format ) ;
else fprintf ( cf , " 0 " ) ;
fprintf ( cf , " ); if (r!=0) return r; \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2008-07-27 22:16:49 +00:00
fprintf ( cf , " { \n " ) ;
fprintf ( cf , " u_int32_t actual_murmur = x1764_finish(&checksum); \n " ) ;
fprintf ( cf , " r = toku_fread_u_int32_t_nocrclen (f, &crc_in_file); len+=4; if (r!=0) return r; \n " ) ;
fprintf ( cf , " fprintf(outf, \" crc=%%08x \" , crc_in_file); \n " ) ;
fprintf ( cf , " if (crc_in_file!=actual_murmur) fprintf(outf, \" actual_fingerprint=%%08x \" , actual_murmur); \n " ) ;
fprintf ( cf , " r = toku_fread_u_int32_t_nocrclen (f, &len_in_file); len+=4; if (r!=0) return r; \n " ) ;
2013-04-16 23:57:20 -04:00
fprintf ( cf , " fprintf(outf, \" len=%%u \" , len_in_file); \n " ) ;
fprintf ( cf , " if (len_in_file!=len) fprintf(outf, \" actual_len=%%u \" , len); \n " ) ;
2008-07-27 22:16:49 +00:00
fprintf ( cf , " if (len_in_file!=len || crc_in_file!=actual_murmur) return DB_BADFORMAT; \n " ) ;
fprintf ( cf , " }; \n " ) ;
2008-02-14 19:23:25 +00:00
fprintf ( cf , " fprintf(outf, \" \\ n \" ); \n " ) ;
fprintf ( cf , " return 0;; \n \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2007-11-22 06:13:26 +00:00
fprintf ( cf , " } \n " ) ;
fprintf ( cf , " fprintf(outf, \" Unknown command %%d ('%%c') \" , cmd, cmd); \n " ) ;
fprintf ( cf , " return DB_BADFORMAT; \n " ) ;
fprintf ( cf , " } \n \n " ) ;
}
2007-11-22 05:09:29 +00:00
2013-04-16 23:57:20 -04:00
static void
generate_rollbacks ( void ) {
2013-04-16 23:57:21 -04:00
DO_ROLLBACKS ( lt , {
2008-02-14 19:23:25 +00:00
fprintf2 ( cf , hf , " int toku_logger_save_rollback_%s (TOKUTXN txn " , lt - > name ) ;
DO_FIELDS ( ft , lt , fprintf2 ( cf , hf , " , %s %s " , ft - > type , ft - > name ) ) ;
fprintf ( hf , " ); \n " ) ;
fprintf ( cf , " ) { \n " ) ;
2008-04-21 04:22:45 +00:00
{
int count = 0 ;
fprintf ( cf , " u_int32_t rollback_fsize = toku_logger_rollback_fsize_%s( " , lt - > name ) ;
DO_FIELDS ( ft , lt , fprintf ( cf , " %s%s " , ( count + + > 0 ) ? " , " : " " , ft - > name ) ) ;
fprintf ( cf , " ); \n " ) ;
}
2008-07-11 22:00:06 +00:00
fprintf ( cf , " struct roll_entry *v = toku_malloc_in_rollback(txn, sizeof(*v)); \n " ) ;
2008-02-14 19:23:25 +00:00
fprintf ( cf , " if (v==0) return errno; \n " ) ;
2013-04-16 23:57:20 -04:00
fprintf ( cf , " v->cmd = (enum rt_cmd)%u; \n " , lt - > command_and_flags & 0xff ) ;
2008-02-14 19:23:25 +00:00
DO_FIELDS ( ft , lt , fprintf ( cf , " v->u.%s.%s = %s; \n " , lt - > name , ft - > name , ft - > name ) ) ;
fprintf ( cf , " v->prev = txn->newest_logentry; \n " ) ;
2008-04-21 04:22:45 +00:00
fprintf ( cf , " v->next = 0; \n " ) ;
2008-02-14 19:23:25 +00:00
fprintf ( cf , " if (txn->oldest_logentry==0) txn->oldest_logentry=v; \n " ) ;
2008-04-21 04:22:45 +00:00
fprintf ( cf , " else txn->newest_logentry->next = v; \n " ) ;
2008-02-14 19:23:25 +00:00
fprintf ( cf , " txn->newest_logentry = v; \n " ) ;
2008-04-21 04:22:45 +00:00
fprintf ( cf , " txn->rollentry_resident_bytecount += rollback_fsize; \n " ) ;
fprintf ( cf , " return toku_maybe_spill_rollbacks(txn); \n } \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2008-04-21 04:22:45 +00:00
2013-04-16 23:57:21 -04:00
DO_ROLLBACKS ( lt , {
2008-04-21 04:22:45 +00:00
fprintf2 ( cf , hf , " void toku_logger_rollback_wbufwrite_%s (struct wbuf *wbuf " , lt - > name ) ;
DO_FIELDS ( ft , lt , fprintf2 ( cf , hf , " , %s %s " , ft - > type , ft - > name ) ) ;
fprintf2 ( cf , hf , " ) " ) ;
fprintf ( hf , " ; \n " ) ;
fprintf ( cf , " { \n " ) ;
fprintf ( cf , " u_int32_t ndone_at_start = wbuf->ndone; \n " ) ;
2013-04-16 23:57:20 -04:00
fprintf ( cf , " wbuf_char(wbuf, '%c'); \n " , ( char ) ( 0xff & lt - > command_and_flags ) ) ;
2008-04-21 04:22:45 +00:00
DO_FIELDS ( ft , lt , fprintf ( cf , " wbuf_%s(wbuf, %s); \n " , ft - > type , ft - > name ) ) ;
fprintf ( cf , " wbuf_int(wbuf, 4+wbuf->ndone - ndone_at_start); \n " ) ;
fprintf ( cf , " } \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2008-04-21 04:22:45 +00:00
fprintf2 ( cf , hf , " void toku_logger_rollback_wbufwrite (struct wbuf *wbuf, struct roll_entry *r) " ) ;
fprintf ( hf , " ; \n " ) ;
fprintf ( cf , " { \n switch (r->cmd) { \n " ) ;
2013-04-16 23:57:21 -04:00
DO_ROLLBACKS ( lt , {
2008-04-21 04:22:45 +00:00
fprintf ( cf , " case RT_%s: toku_logger_rollback_wbufwrite_%s(wbuf " , lt - > name , lt - > name ) ;
DO_FIELDS ( ft , lt , fprintf ( cf , " , r->u.%s.%s " , lt - > name , ft - > name ) ) ;
fprintf ( cf , " ); return; \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2008-04-21 04:22:45 +00:00
fprintf ( cf , " } \n assert(0); \n " ) ;
fprintf ( cf , " } \n " ) ;
2013-04-16 23:57:21 -04:00
DO_ROLLBACKS ( lt , {
2008-04-21 04:22:45 +00:00
fprintf2 ( cf , hf , " u_int32_t toku_logger_rollback_fsize_%s ( " , lt - > name ) ;
2008-04-17 10:46:19 +00:00
int count = 0 ;
DO_FIELDS ( ft , lt , fprintf2 ( cf , hf , " %s%s %s " , ( count + + > 0 ) ? " , " : " " , ft - > type , ft - > name ) ) ;
fprintf ( hf , " ); \n " ) ;
fprintf ( cf , " ) { \n " ) ;
2008-04-21 04:22:45 +00:00
fprintf ( cf , " return 1 /* the cmd*/ \n " ) ;
fprintf ( cf , " + 4 /* the int at the end saying the size */ " ) ;
2008-04-17 10:46:19 +00:00
DO_FIELDS ( ft , lt ,
fprintf ( cf , " \n + toku_logsizeof_%s(%s) " , ft - > type , ft - > name ) ) ;
fprintf ( cf , " ; \n } \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2008-04-21 04:22:45 +00:00
fprintf2 ( cf , hf , " u_int32_t toku_logger_rollback_fsize(struct roll_entry *item) " ) ;
fprintf ( hf , " ; \n " ) ;
fprintf ( cf , " { \n switch(item->cmd) { \n " ) ;
2013-04-16 23:57:21 -04:00
DO_ROLLBACKS ( lt , {
2008-04-21 04:22:45 +00:00
fprintf ( cf , " case RT_%s: return toku_logger_rollback_fsize_%s( " , lt - > name , lt - > name ) ;
int count = 0 ;
DO_FIELDS ( ft , lt , fprintf ( cf , " %sitem->u.%s.%s " , ( count + + > 0 ) ? " , " : " " , lt - > name , ft - > name ) ) ;
fprintf ( cf , " ); \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2008-04-21 04:22:45 +00:00
fprintf ( cf , " } \n assert(0); \n return 0; \n " ) ;
fprintf ( cf , " } \n " ) ;
2008-07-11 22:00:06 +00:00
fprintf2 ( cf , hf , " int toku_parse_rollback(unsigned char *buf, u_int32_t n_bytes, struct roll_entry **itemp, MEMARENA ma) " ) ;
2008-04-21 04:22:45 +00:00
fprintf ( hf , " ; \n " ) ;
2013-04-16 23:57:20 -04:00
fprintf ( cf , " { \n assert(n_bytes>0); \n struct roll_entry *item = malloc_in_memarena(ma, sizeof(*item)); \n item->cmd=(enum rt_cmd)(buf[0]); \n " ) ;
2008-04-21 04:22:45 +00:00
fprintf ( cf , " struct rbuf rc = {buf, n_bytes, 1}; \n " ) ;
fprintf ( cf , " switch(item->cmd) { \n " ) ;
2013-04-16 23:57:21 -04:00
DO_ROLLBACKS ( lt , {
2008-04-21 04:22:45 +00:00
fprintf ( cf , " case RT_%s: \n " , lt - > name ) ;
2008-07-11 22:00:06 +00:00
DO_FIELDS ( ft , lt , fprintf ( cf , " rbuf_ma_%s(&rc, ma, &item->u.%s.%s); \n " , ft - > type , lt - > name , ft - > name ) ) ;
2008-04-21 04:22:45 +00:00
fprintf ( cf , " *itemp = item; \n " ) ;
fprintf ( cf , " return 0; \n " ) ;
2013-04-16 23:57:21 -04:00
} ) ;
2008-04-21 04:22:45 +00:00
fprintf ( cf , " } \n return EINVAL; \n } \n " ) ;
2008-02-14 19:23:25 +00:00
}
2007-11-22 07:13:08 +00:00
const char * codepath = " log_code.c " ;
const char * headerpath = " log_header.h " ;
2007-11-22 05:09:29 +00:00
int main ( int argc __attribute__ ( ( __unused__ ) ) , char * argv [ ] __attribute__ ( ( __unused__ ) ) ) {
2007-11-22 07:13:08 +00:00
unlink ( codepath ) ;
unlink ( headerpath ) ;
cf = fopen ( codepath , " w " ) ; assert ( cf ! = 0 ) ;
hf = fopen ( headerpath , " w " ) ; assert ( hf ! = 0 ) ;
2013-04-16 23:57:20 -04:00
fprintf ( hf , " #ifndef LOG_HEADER_H \n " ) ;
fprintf ( hf , " #define LOG_HEADER_H \n " ) ;
2008-01-24 15:10:32 +00:00
fprintf2 ( cf , hf , " /* Do not edit this file. This code generated by logformat.c. Copyright 2007, 2008 Tokutek. */ \n " ) ;
fprintf2 ( cf , hf , " #ident \" Copyright (c) 2007, 2008 Tokutek Inc. All rights reserved. \" \n " ) ;
2013-04-16 23:57:20 -04:00
fprintf ( cf , " #include \" includes.h \" \n " ) ;
2007-11-22 06:46:00 +00:00
fprintf ( hf , " #include \" brt-internal.h \" \n " ) ;
2008-07-11 22:00:06 +00:00
fprintf ( hf , " #include \" memarena.h \" \n " ) ;
2008-02-26 15:51:15 +00:00
generate_enum ( ) ;
2007-11-22 05:09:29 +00:00
generate_log_struct ( ) ;
2007-11-23 20:36:03 +00:00
generate_dispatch ( ) ;
2007-11-22 05:09:29 +00:00
generate_log_writer ( ) ;
2007-11-22 06:13:26 +00:00
generate_log_reader ( ) ;
generate_logprint ( ) ;
2008-02-14 19:23:25 +00:00
generate_rollbacks ( ) ;
2013-04-16 23:57:20 -04:00
fprintf ( hf , " #endif \n " ) ;
2007-11-22 06:13:26 +00:00
{
int r = fclose ( hf ) ;
assert ( r = = 0 ) ;
r = fclose ( cf ) ;
assert ( r = = 0 ) ;
2007-11-22 07:13:08 +00:00
// Make it tougher to modify by mistake
chmod ( codepath , S_IRUSR | S_IRGRP | S_IROTH ) ;
chmod ( headerpath , S_IRUSR | S_IRGRP | S_IROTH ) ;
2007-11-22 06:13:26 +00:00
}
2007-11-22 05:09:29 +00:00
return 0 ;
}