diff options
Diffstat (limited to 'src/third_party/wiredtiger/dist/log.py')
-rw-r--r-- | src/third_party/wiredtiger/dist/log.py | 315 |
1 files changed, 185 insertions, 130 deletions
diff --git a/src/third_party/wiredtiger/dist/log.py b/src/third_party/wiredtiger/dist/log.py index 2f8fbea5294..e9c0fd7850c 100644 --- a/src/third_party/wiredtiger/dist/log.py +++ b/src/third_party/wiredtiger/dist/log.py @@ -8,76 +8,93 @@ import log_data tmp_file = '__tmp' # Map log record types to: -# (C type, pack type, printf format, printf arg(s)) +# (C type, pack type, printf format, printf arg(s), printf setup) field_types = { - 'string' : ('const char *', 'S', '%s', 'arg'), - 'item' : ('WT_ITEM *', 'u', '%.*s', - '(int)arg.size, (const char *)arg.data'), - 'recno' : ('uint64_t', 'r', '%" PRIu64 "', 'arg'), - 'uint32' : ('uint32_t', 'I', '%" PRIu32 "', 'arg'), - 'uint64' : ('uint64_t', 'Q', '%" PRIu64 "', 'arg'), + 'string' : ('const char *', 'S', '%s', 'arg', ''), + 'item' : ('WT_ITEM *', 'u', '%s', 'escaped', + 'WT_RET(__logrec_jsonify_str(session, &escaped, &arg));'), + 'recno' : ('uint64_t', 'r', '%" PRIu64 "', 'arg', ''), + 'uint32' : ('uint32_t', 'I', '%" PRIu32 "', 'arg', ''), + 'uint64' : ('uint64_t', 'Q', '%" PRIu64 "', 'arg', ''), } def cintype(f): - return field_types[f[0]][0] + return field_types[f[0]][0] def couttype(f): - type = cintype(f) - # We already have a pointer to a WT_ITEM - if f[0] == 'item': - return type - if type[-1] != '*': - type += ' ' - return type + '*' + type = cintype(f) + # We already have a pointer to a WT_ITEM + if f[0] == 'item': + return type + if type[-1] != '*': + type += ' ' + return type + '*' def clocaltype(f): - type = cintype(f) - # Allocate a WT_ITEM struct on the stack - if f[0] == 'item': - return type[:-2] - return type + type = cintype(f) + # Allocate a WT_ITEM struct on the stack + if f[0] == 'item': + return type[:-2] + return type + +def escape_decl(fields): + for f in fields: + if 'escaped' in field_types[f[0]][4]: + return '\n\tchar *escaped;' + return '' + +def has_escape(fields): + for f in fields: + if 'escaped' in field_types[f[0]][4]: + return True + return False def pack_fmt(fields): - return ''.join(field_types[f[0]][1] for f in fields) + return ''.join(field_types[f[0]][1] for f in fields) def op_pack_fmt(r): - return 'II' + pack_fmt(r.fields) + return 'II' + pack_fmt(r.fields) def rec_pack_fmt(r): - return 'I' + pack_fmt(r.fields) + return 'I' + pack_fmt(r.fields) def printf_fmt(f): - return field_types[f[0]][2] + return field_types[f[0]][2] def printf_arg(f): - arg = field_types[f[0]][3].replace('arg', f[1]) - return '\n\t ' + arg if f[0] == 'item' else ' ' + arg + arg = field_types[f[0]][3].replace('arg', f[1]) + return ' ' + arg + +def printf_setup(f): + stmt = field_types[f[0]][4].replace('arg', f[1]) + return '' if stmt == '' else stmt + '\n\t' + ##################################################################### # Update log.h with #defines for types ##################################################################### log_defines = ( - ''.join('/*! %s */\n#define\t%s\t%d\n' % (r.desc, r.macro_name(), i) - for i, r in enumerate(log_data.rectypes)) + - ''.join('/*! %s */\n#define\t%s\t%d\n' % (r.desc, r.macro_name(), i) - for i, r in enumerate(log_data.optypes,start=1)) + ''.join('/*! %s */\n#define\t%s\t%d\n' % (r.desc, r.macro_name(), i) + for i, r in enumerate(log_data.rectypes)) + + ''.join('/*! %s */\n#define\t%s\t%d\n' % (r.desc, r.macro_name(), i) + for i, r in enumerate(log_data.optypes,start=1)) ) tfile = open(tmp_file, 'w') skip = 0 for line in open('../src/include/wiredtiger.in', 'r'): - if skip: - if 'Log record declarations: END' in line: - tfile.write('/*\n' + line) - skip = 0 - else: - tfile.write(line) - if 'Log record declarations: BEGIN' in line: - skip = 1 - tfile.write(' */\n') - tfile.write('/*! invalid operation */\n') - tfile.write('#define\tWT_LOGOP_INVALID\t0\n') - tfile.write(log_defines) + if skip: + if 'Log record declarations: END' in line: + tfile.write('/*\n' + line) + skip = 0 + else: + tfile.write(line) + if 'Log record declarations: BEGIN' in line: + skip = 1 + tfile.write(' */\n') + tfile.write('/*! invalid operation */\n') + tfile.write('#define\tWT_LOGOP_INVALID\t0\n') + tfile.write(log_defines) tfile.close() compare_srcfile(tmp_file, '../src/include/wiredtiger.in') @@ -95,33 +112,33 @@ tfile.write(''' int __wt_logrec_alloc(WT_SESSION_IMPL *session, size_t size, WT_ITEM **logrecp) { - WT_ITEM *logrec; +\tWT_ITEM *logrec; - WT_RET(__wt_scr_alloc(session, WT_ALIGN(size + 1, LOG_ALIGN), &logrec)); - WT_CLEAR(*(WT_LOG_RECORD *)logrec->data); - logrec->size = offsetof(WT_LOG_RECORD, record); +\tWT_RET(__wt_scr_alloc(session, WT_ALIGN(size + 1, LOG_ALIGN), &logrec)); +\tWT_CLEAR(*(WT_LOG_RECORD *)logrec->data); +\tlogrec->size = offsetof(WT_LOG_RECORD, record); - *logrecp = logrec; - return (0); +\t*logrecp = logrec; +\treturn (0); } void __wt_logrec_free(WT_SESSION_IMPL *session, WT_ITEM **logrecp) { - WT_UNUSED(session); - __wt_scr_free(logrecp); +\tWT_UNUSED(session); +\t__wt_scr_free(logrecp); } int __wt_logrec_read(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *rectypep) { - uint64_t rectype; +\tuint64_t rectype; - WT_UNUSED(session); - WT_RET(__wt_vunpack_uint(pp, WT_PTRDIFF(end, *pp), &rectype)); - *rectypep = (uint32_t)rectype; - return (0); +\tWT_UNUSED(session); +\tWT_RET(__wt_vunpack_uint(pp, WT_PTRDIFF(end, *pp), &rectype)); +\t*rectypep = (uint32_t)rectype; +\treturn (0); } int @@ -129,99 +146,137 @@ __wt_logop_read(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *optypep, uint32_t *opsizep) { - return (__wt_struct_unpack( - session, *pp, WT_PTRDIFF(end, *pp), "II", optypep, opsizep)); +\treturn (__wt_struct_unpack( +\t session, *pp, WT_PTRDIFF(end, *pp), "II", optypep, opsizep)); +} + +static size_t +__logrec_json_unpack_str(char *dest, size_t destlen, const char *src, + size_t srclen) +{ +\tsize_t total; +\tsize_t n; + +\ttotal = 0; +\twhile (srclen > 0) { +\t\tn = __wt_json_unpack_char(*src++, (u_char *)dest, destlen, 0); +\t\tsrclen--; +\t\tif (n > destlen) +\t\t\tdestlen = 0; +\t\telse { +\t\t\tdestlen -= n; +\t\t\tdest += n; +\t\t} +\t\ttotal += n; +\t} +\tif (destlen > 0) +\t\t*dest = '\\0'; +\treturn (total + 1); +} + +static int +__logrec_jsonify_str(WT_SESSION_IMPL *session, char **destp, WT_ITEM *item) +{ +\tsize_t needed; + +\tneeded = __logrec_json_unpack_str(NULL, 0, item->data, item->size); +\tWT_RET(__wt_realloc(session, NULL, needed, destp)); +\t(void)__logrec_json_unpack_str(*destp, needed, item->data, item->size); +\treturn (0); } ''') # Emit code to read, write and print log operations (within a log record) for optype in log_data.optypes: - if not optype.fields: - continue + if not optype.fields: + continue - tfile.write(''' + tfile.write(''' int __wt_logop_%(name)s_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, %(arg_decls)s) { - const char *fmt = WT_UNCHECKED_STRING(%(fmt)s); - size_t size; - uint32_t optype, recsize; - - optype = %(macro)s; - WT_RET(__wt_struct_size(session, &size, fmt, - optype, 0%(arg_names)s)); - - __wt_struct_size_adjust(session, &size); - WT_RET(__wt_buf_extend(session, logrec, logrec->size + size)); - recsize = (uint32_t)size; - WT_RET(__wt_struct_pack(session, - (uint8_t *)logrec->data + logrec->size, size, fmt, - optype, recsize%(arg_names)s)); - - logrec->size += (uint32_t)size; - return (0); +\tconst char *fmt = WT_UNCHECKED_STRING(%(fmt)s); +\tsize_t size; +\tuint32_t optype, recsize; + +\toptype = %(macro)s; +\tWT_RET(__wt_struct_size(session, &size, fmt, +\t optype, 0%(arg_names)s)); + +\t__wt_struct_size_adjust(session, &size); +\tWT_RET(__wt_buf_extend(session, logrec, logrec->size + size)); +\trecsize = (uint32_t)size; +\tWT_RET(__wt_struct_pack(session, +\t (uint8_t *)logrec->data + logrec->size, size, fmt, +\t optype, recsize%(arg_names)s)); + +\tlogrec->size += (uint32_t)size; +\treturn (0); } ''' % { - 'name' : optype.name, - 'macro' : optype.macro_name(), - 'arg_decls' : ', '.join( - '%s%s%s' % (cintype(f), '' if cintype(f)[-1] == '*' else ' ', f[1]) - for f in optype.fields), - 'arg_names' : ''.join(', %s' % f[1] for f in optype.fields), - 'fmt' : op_pack_fmt(optype) + 'name' : optype.name, + 'macro' : optype.macro_name(), + 'arg_decls' : ', '.join( + '%s%s%s' % (cintype(f), '' if cintype(f)[-1] == '*' else ' ', f[1]) + for f in optype.fields), + 'arg_names' : ''.join(', %s' % f[1] for f in optype.fields), + 'fmt' : op_pack_fmt(optype) }) - tfile.write(''' + tfile.write(''' int __wt_logop_%(name)s_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, %(arg_decls)s) { - const char *fmt = WT_UNCHECKED_STRING(%(fmt)s); - uint32_t optype, size; +\tconst char *fmt = WT_UNCHECKED_STRING(%(fmt)s); +\tuint32_t optype, size; - WT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, - &optype, &size%(arg_names)s)); - WT_ASSERT(session, optype == %(macro)s); +\tWT_RET(__wt_struct_unpack(session, *pp, WT_PTRDIFF(end, *pp), fmt, +\t &optype, &size%(arg_names)s)); +\tWT_ASSERT(session, optype == %(macro)s); - *pp += size; - return (0); +\t*pp += size; +\treturn (0); } ''' % { - 'name' : optype.name, - 'macro' : optype.macro_name(), - 'arg_decls' : ', '.join( - '%s%sp' % (couttype(f), f[1]) for f in optype.fields), - 'arg_names' : ''.join(', %sp' % f[1] for f in optype.fields), - 'fmt' : op_pack_fmt(optype) + 'name' : optype.name, + 'macro' : optype.macro_name(), + 'arg_decls' : ', '.join( + '%s%sp' % (couttype(f), f[1]) for f in optype.fields), + 'arg_names' : ''.join(', %sp' % f[1] for f in optype.fields), + 'fmt' : op_pack_fmt(optype) }) - tfile.write(''' + tfile.write(''' int __wt_logop_%(name)s_print( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, FILE *out) { - %(arg_decls)s +\t%(arg_decls)s - WT_RET(__wt_logop_%(name)s_unpack( - session, pp, end%(arg_addrs)s)); +\t%(arg_init)sWT_RET(__wt_logop_%(name)s_unpack( +\t session, pp, end%(arg_addrs)s)); - fprintf(out, " \\"optype\\": \\"%(name)s\\",\\n"); - %(print_args)s - return (0); +\tfprintf(out, " \\"optype\\": \\"%(name)s\\",\\n"); +\t%(print_args)s +\t%(arg_fini)sreturn (0); } ''' % { - 'name' : optype.name, - 'arg_decls' : '\n\t'.join('%s%s%s;' % - (clocaltype(f), '' if clocaltype(f)[-1] == '*' else ' ', f[1]) - for f in optype.fields), - 'arg_addrs' : ''.join(', &%s' % f[1] for f in optype.fields), - 'print_args' : '\n\t'.join( - 'fprintf(out, " \\"%s\\": \\"%s\\",\\n",%s);' % - (f[1], printf_fmt(f), printf_arg(f)) - for f in optype.fields), + 'name' : optype.name, + 'arg_decls' : ('\n\t'.join('%s%s%s;' % + (clocaltype(f), '' if clocaltype(f)[-1] == '*' else ' ', f[1]) + for f in optype.fields)) + escape_decl(optype.fields), + 'arg_init' : ('escaped = NULL;\n\t' if has_escape(optype.fields) else ''), + 'arg_fini' : ('__wt_free(session, escaped);\n\t' + if has_escape(optype.fields) else ''), + 'arg_addrs' : ''.join(', &%s' % f[1] for f in optype.fields), + 'print_args' : '\n\t'.join( + '%sfprintf(out, " \\"%s\\": \\"%s\\",\\n",%s);' % + (printf_setup(f), f[1], printf_fmt(f), printf_arg(f)) + for f in optype.fields), }) # Emit the printlog entry point @@ -230,32 +285,32 @@ int __wt_txn_op_printlog( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, FILE *out) { - uint32_t optype, opsize; +\tuint32_t optype, opsize; - /* Peek at the size and the type. */ - WT_RET(__wt_logop_read(session, pp, end, &optype, &opsize)); - end = *pp + opsize; +\t/* Peek at the size and the type. */ +\tWT_RET(__wt_logop_read(session, pp, end, &optype, &opsize)); +\tend = *pp + opsize; - switch (optype) {''') +\tswitch (optype) {''') for optype in log_data.optypes: - if not optype.fields: - continue + if not optype.fields: + continue - tfile.write(''' - case %(macro)s: - WT_RET(%(print_func)s(session, pp, end, out)); - break; + tfile.write(''' +\tcase %(macro)s: +\t\tWT_RET(%(print_func)s(session, pp, end, out)); +\t\tbreak; ''' % { - 'macro' : optype.macro_name(), - 'print_func' : '__wt_logop_' + optype.name + '_print', + 'macro' : optype.macro_name(), + 'print_func' : '__wt_logop_' + optype.name + '_print', }) tfile.write(''' - WT_ILLEGAL_VALUE(session); - } +\tWT_ILLEGAL_VALUE(session); +\t} - return (0); +\treturn (0); } ''') |