diff --git a/dist/stat.py b/dist/stat.py index bb9048395..798a106b9 100644 --- a/dist/stat.py +++ b/dist/stat.py @@ -5,7 +5,7 @@ import re, string, sys, textwrap from dist import compare_srcfile # Read the source files. -from stat_data import groups, dsrc_stats, connection_stats, join_stats +from stat_data import groups, dsrc_stats, connection_stats, join_stats, operation_stats def print_struct(title, name, base, stats): '''Print the structures for the stat.h file.''' @@ -36,6 +36,7 @@ for line in open('../src/include/stat.h', 'r'): 'connections', 'connection', 1000, connection_stats) print_struct('data sources', 'dsrc', 2000, dsrc_stats) print_struct('join cursors', 'join', 3000, join_stats) + print_struct('operations', 'operation', 4000, operation_stats) f.close() compare_srcfile(tmp_file, '../src/include/stat.h') @@ -90,6 +91,15 @@ def print_defines(): */ ''') print_defines_one('JOIN', 3000, join_stats) + f.write(''' +/*! + * @} + * @name Statistics for operations + * @anchor statistics_operation + * @{ + */ +''') + print_defines_one('OPERATION', 4000, operation_stats) f.write('/*! @} */\n') # Update the #defines in the wiredtiger.in file. @@ -240,5 +250,6 @@ f.write('#include "wt_internal.h"\n') print_func('dsrc', 'WT_DATA_HANDLE', dsrc_stats) print_func('connection', 'WT_CONNECTION_IMPL', connection_stats) print_func('join', None, join_stats) +print_func('operation', None, operation_stats) f.close() compare_srcfile(tmp_file, '../src/support/stat.c') diff --git a/dist/stat_data.py b/dist/stat_data.py index 95d05e17e..7bcf46a83 100644 --- a/dist/stat_data.py +++ b/dist/stat_data.py @@ -84,6 +84,10 @@ class LSMStat(Stat): prefix = 'LSM' def __init__(self, name, desc, flags=''): Stat.__init__(self, name, LSMStat.prefix, desc, flags) +class OperationStat(Stat): + prefix = 'operation' + def __init__(self, name, desc, flags=''): + Stat.__init__(self, name, OperationStat.prefix, desc, flags) class PerfHistStat(Stat): prefix = 'perf' def __init__(self, name, desc, flags=''): @@ -770,3 +774,14 @@ join_stats = [ ] join_stats = sorted(join_stats, key=attrgetter('desc')) + +########################################## +# Operation statistics +########################################## +operation_stats = [ + OperationStat('property_one', 'op prop 1'), + OperationStat('property_two', 'op prop 2', 'no_clear'), + OperationStat('property_three', 'op prop 3'), +] + +operation_stats = sorted(operation_stats, key=attrgetter('desc')) diff --git a/src/cursor/cur_stat.c b/src/cursor/cur_stat.c index 25d4b588d..716517f87 100644 --- a/src/cursor/cur_stat.c +++ b/src/cursor/cur_stat.c @@ -484,6 +484,36 @@ __curstat_join_desc(WT_CURSOR_STAT *cst, int slot, const char **resultp) return (0); } +/* + * __curstat_session_init -- + * Initialize the statistics for a session cursor. + */ +static int +__curstat_session_init(WT_SESSION_IMPL *session, + const char *uri, const char *cfg[], WT_CURSOR_STAT *cst) +{ + // Look at __curstat_conn_init(): + // Copy from SESSION struct to u.session_stats + // clear is needed: + // if (F_ISSET(cst, WT_STAT_CLEAR)) + // __wt_stat_operation_init_single(SESSION stat struct) + memcpy(&cst->u.session_stats, + session->op_stats, sizeof(WT_OPERATION_STATS)); + if (F_ISSET(cst, WT_STAT_CLEAR)) + __wt_stat_operation_init_single(session->op_stats); + + cst->stats = (int64_t *)&cst->u.session_stats; + cst->stats_base = WT_OPERATION_STATS_BASE; + cst->stats_count = sizeof(WT_OPERATION_STATS) / sizeof(int64_t); + cst->stats_desc = __wt_stat_operation_desc; + // cst->next_set = __curstat_join_next_set; + + WT_UNUSED(uri); + WT_UNUSED(cfg); + + return (0); +} + /* * __curstat_join_init -- * Initialize the statistics for a joined cursor. @@ -533,6 +563,9 @@ __wt_curstat_init(WT_SESSION_IMPL *session, if (strcmp(dsrc_uri, "join") == 0) WT_RET(__curstat_join_init(session, curjoin, cfg, cst)); + else if (strcmp(dsrc_uri, "session") == 0) + WT_RET(__curstat_session_init(session, dsrc_uri, cfg, cst)); + else if (WT_PREFIX_MATCH(dsrc_uri, "colgroup:")) WT_RET( __wt_curstat_colgroup_init(session, dsrc_uri, cfg, cst)); diff --git a/src/include/cursor.h b/src/include/cursor.h index 36fb2d92e..656d9e770 100644 --- a/src/include/cursor.h +++ b/src/include/cursor.h @@ -487,6 +487,7 @@ struct __wt_cursor_stat { WT_DSRC_STATS dsrc_stats; WT_CONNECTION_STATS conn_stats; WT_JOIN_STATS_GROUP join_stats_group; + WT_OPERATION_STATS session_stats; } u; const char **cfg; /* Original cursor configuration */ diff --git a/src/include/extern.h b/src/include/extern.h index effcf6d89..99ecff6e7 100644 --- a/src/include/extern.h +++ b/src/include/extern.h @@ -785,6 +785,11 @@ extern void __wt_stat_join_init_single(WT_JOIN_STATS *stats); extern void __wt_stat_join_clear_single(WT_JOIN_STATS *stats); extern void __wt_stat_join_clear_all(WT_JOIN_STATS **stats); extern void __wt_stat_join_aggregate(WT_JOIN_STATS **from, WT_JOIN_STATS *to); +extern int __wt_stat_operation_desc(WT_CURSOR_STAT *cst, int slot, const char **p) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_stat_operation_init_single(WT_OPERATION_STATS *stats); +extern void __wt_stat_operation_clear_single(WT_OPERATION_STATS *stats); +extern void __wt_stat_operation_clear_all(WT_OPERATION_STATS **stats); +extern void __wt_stat_operation_aggregate(WT_OPERATION_STATS **from, WT_OPERATION_STATS *to); extern int __wt_thread_group_resize(WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, uint32_t new_min, uint32_t new_max, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_thread_group_create(WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, const char *name, uint32_t min, uint32_t max, uint32_t flags, bool (*chk_func)(WT_SESSION_IMPL *session), int (*run_func)(WT_SESSION_IMPL *session, WT_THREAD *context), int (*stop_func)(WT_SESSION_IMPL *session, WT_THREAD *context)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_thread_group_destroy(WT_SESSION_IMPL *session, WT_THREAD_GROUP *group) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); diff --git a/src/include/session.h b/src/include/session.h index 10ff7bd48..ce7c78dee 100644 --- a/src/include/session.h +++ b/src/include/session.h @@ -268,4 +268,5 @@ struct __wt_session_impl { u_int optrackbuf_ptr; uint64_t optrack_offset; WT_FH *optrack_fh; + WT_OPERATION_STATS *op_stats; }; diff --git a/src/include/stat.h b/src/include/stat.h index 6646dd0a8..f1b274885 100644 --- a/src/include/stat.h +++ b/src/include/stat.h @@ -203,6 +203,22 @@ __wt_stats_clear(void *stats_arg, int slot) } \ } while (0) +/* + * Update per session statistics if statistics gathering is enabled. + */ +#define WT_STAT_SESSION_DECRV(session, fld, value) \ + WT_STAT_DECRV_BASE(session, session->op_stats, fld, value) +#define WT_STAT_SESSION_DECR(session, fld) \ + WT_STAT_SESSION_DECRV(session, fld, 1) + +#define WT_STAT_SESSION_INCRV(session, fld, value) \ + WT_STAT_INCRV_BASE(session, session->op_stats, fld, value) +#define WT_STAT_SESSION_INCR(session, fld) \ + WT_STAT_SESSION_INCRV(session, fld, 1) + +#define WT_STAT_SESSION_SET(session, fld, value) \ + session->op_stats->fld = (int64_t)(value); + /* * Update connection handle statistics if statistics gathering is enabled. */ @@ -837,4 +853,14 @@ struct __wt_join_stats { int64_t iterated; }; +/* + * Statistics entries for operations. + */ +#define WT_OPERATION_STATS_BASE 4000 +struct __wt_operation_stats { + int64_t property_one; + int64_t property_two; + int64_t property_three; +}; + /* Statistics section: END */ diff --git a/src/include/wiredtiger.in b/src/include/wiredtiger.in index e8664d664..404f00393 100644 --- a/src/include/wiredtiger.in +++ b/src/include/wiredtiger.in @@ -6181,6 +6181,19 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection); #define WT_STAT_JOIN_BLOOM_INSERT 3003 /*! : items iterated */ #define WT_STAT_JOIN_ITERATED 3004 + +/*! + * @} + * @name Statistics for operations + * @anchor statistics_operation + * @{ + */ +/*! operation: op prop 1 */ +#define WT_STAT_OPERATION_PROPERTY_ONE 4000 +/*! operation: op prop 2 */ +#define WT_STAT_OPERATION_PROPERTY_TWO 4001 +/*! operation: op prop 3 */ +#define WT_STAT_OPERATION_PROPERTY_THREE 4002 /*! @} */ /* * Statistics section: END diff --git a/src/include/wt_internal.h b/src/include/wt_internal.h index df3ee2da1..7137466a3 100644 --- a/src/include/wt_internal.h +++ b/src/include/wt_internal.h @@ -247,6 +247,8 @@ struct __wt_named_extractor; typedef struct __wt_named_extractor WT_NAMED_EXTRACTOR; struct __wt_named_snapshot; typedef struct __wt_named_snapshot WT_NAMED_SNAPSHOT; +struct __wt_operation_stats; + typedef struct __wt_operation_stats WT_OPERATION_STATS; struct __wt_optrack_header; typedef struct __wt_optrack_header WT_OPTRACK_HEADER; struct __wt_optrack_record; diff --git a/src/session/session_api.c b/src/session/session_api.c index 857003c7a..656055cad 100644 --- a/src/session/session_api.c +++ b/src/session/session_api.c @@ -322,6 +322,8 @@ __session_close(WT_SESSION *wt_session, const char *config) __wt_free(session, session->optrack_buf); } + __wt_free(session, session->op_stats); + /* Release common session resources. */ WT_TRET(__wt_session_release_resources(session)); @@ -2231,6 +2233,10 @@ __open_session(WT_CONNECTION_IMPL *conn, session_ret->optrackbuf_ptr = 0; } + WT_ERR(__wt_malloc( + session, sizeof(WT_OPERATION_STATS), &session_ret->op_stats)); + __wt_stat_operation_init_single(session_ret->op_stats); + /* Set the default value for session flags. */ if (F_ISSET(conn, WT_CONN_CACHE_CURSORS)) F_SET(session_ret, WT_SESSION_CACHE_CURSORS); diff --git a/src/session/session_dhandle.c b/src/session/session_dhandle.c index 30399cafd..484c31cfe 100644 --- a/src/session/session_dhandle.c +++ b/src/session/session_dhandle.c @@ -18,6 +18,8 @@ __session_add_dhandle(WT_SESSION_IMPL *session) WT_DATA_HANDLE_CACHE *dhandle_cache; uint64_t bucket; + WT_STAT_SESSION_INCRV(session, property_two, 2); + /* Allocate a handle cache entry. */ WT_RET(__wt_calloc_one(session, &dhandle_cache)); @@ -126,6 +128,9 @@ __wt_session_lock_dhandle( lock_busy = false; want_exclusive = LF_ISSET(WT_DHANDLE_EXCLUSIVE); + WT_STAT_SESSION_INCR(session, property_one); + printf("HEY\n"); + /* * If this session already has exclusive access to the handle, there is * no point trying to lock it again. @@ -258,6 +263,8 @@ __wt_session_release_dhandle(WT_SESSION_IMPL *session) write_locked = F_ISSET(dhandle, WT_DHANDLE_EXCLUSIVE); locked = true; + WT_STAT_SESSION_INCRV(session, property_three, 3); + /* * If we had special flags set, close the handle so that future access * can get a handle without special flags. diff --git a/src/support/stat.c b/src/support/stat.c index 7993c7b6d..fb7c43943 100644 --- a/src/support/stat.c +++ b/src/support/stat.c @@ -2124,3 +2124,49 @@ __wt_stat_join_aggregate( to->bloom_insert += WT_STAT_READ(from, bloom_insert); to->iterated += WT_STAT_READ(from, iterated); } + +static const char * const __stats_operation_desc[] = { + "operation: op prop 1", + "operation: op prop 2", + "operation: op prop 3", +}; + +int +__wt_stat_operation_desc(WT_CURSOR_STAT *cst, int slot, const char **p) +{ + WT_UNUSED(cst); + *p = __stats_operation_desc[slot]; + return (0); +} + +void +__wt_stat_operation_init_single(WT_OPERATION_STATS *stats) +{ + memset(stats, 0, sizeof(*stats)); +} + +void +__wt_stat_operation_clear_single(WT_OPERATION_STATS *stats) +{ + stats->property_one = 0; + /* not clearing property_two */ + stats->property_three = 0; +} + +void +__wt_stat_operation_clear_all(WT_OPERATION_STATS **stats) +{ + u_int i; + + for (i = 0; i < WT_COUNTER_SLOTS; ++i) + __wt_stat_operation_clear_single(stats[i]); +} + +void +__wt_stat_operation_aggregate( + WT_OPERATION_STATS **from, WT_OPERATION_STATS *to) +{ + to->property_one += WT_STAT_READ(from, property_one); + to->property_two += WT_STAT_READ(from, property_two); + to->property_three += WT_STAT_READ(from, property_three); +}