/*- * Copyright (c) 2014-2015 MongoDB, Inc. * Copyright (c) 2008-2014 WiredTiger, Inc. * All rights reserved. * * See the file LICENSE for redistribution information. */ #include "wt_internal.h" /* * __wt_curstat_colgroup_init -- * Initialize the statistics for a column group. */ int __wt_curstat_colgroup_init(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR_STAT *cst) { WT_COLGROUP *colgroup; WT_DECL_ITEM(buf); WT_DECL_RET; WT_RET(__wt_schema_get_colgroup(session, uri, false, NULL, &colgroup)); WT_RET(__wt_scr_alloc(session, 0, &buf)); WT_ERR(__wt_buf_fmt(session, buf, "statistics:%s", colgroup->source)); ret = __wt_curstat_init(session, buf->data, cfg, cst); err: __wt_scr_free(session, &buf); return (ret); } /* * __wt_curstat_index_init -- * Initialize the statistics for an index. */ int __wt_curstat_index_init(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR_STAT *cst) { WT_DECL_ITEM(buf); WT_DECL_RET; WT_INDEX *idx; WT_RET(__wt_schema_get_index(session, uri, false, NULL, &idx)); WT_RET(__wt_scr_alloc(session, 0, &buf)); WT_ERR(__wt_buf_fmt(session, buf, "statistics:%s", idx->source)); ret = __wt_curstat_init(session, buf->data, cfg, cst); err: __wt_scr_free(session, &buf); return (ret); } /* * __curstat_size_only -- * For very simple tables we can avoid getting table handles if * configured to only retrieve the size. It's worthwhile because * workloads that create and drop a lot of tables can put a lot of * pressure on the table list lock. */ static int __curstat_size_only(WT_SESSION_IMPL *session, const char *uri, bool *was_fast,WT_CURSOR_STAT *cst) { WT_CONFIG cparser; WT_CONFIG_ITEM ckey, colconf, cval; WT_DECL_RET; WT_ITEM namebuf; wt_off_t filesize; char *tableconf; WT_CLEAR(namebuf); *was_fast = false; /* Retrieve the metadata for this table. */ WT_RET(__wt_metadata_search(session, uri, &tableconf)); /* * The fast path only works if the table consists of a single file * and does not have any indexes. The absence of named columns is how * we determine that neither of those conditions can be satisfied. */ WT_ERR(__wt_config_getones(session, tableconf, "columns", &colconf)); WT_ERR(__wt_config_subinit(session, &cparser, &colconf)); if ((ret = __wt_config_next(&cparser, &ckey, &cval)) == 0) goto err; /* Build up the file name from the table URI. */ WT_ERR(__wt_buf_fmt( session, &namebuf, "%s.wt", uri + strlen("table:"))); /* * Get the size of the underlying file. This will fail for anything * other than simple tables (LSM for example) and will fail if there * are concurrent schema level operations (for example drop). That is * fine - failing here results in falling back to the slow path of * opening the handle. */ if (__wt_filesize_name(session, namebuf.data, &filesize) == 0) { /* Setup and populate the statistics structure */ __wt_stat_dsrc_init_single(&cst->u.dsrc_stats); cst->u.dsrc_stats.block_size = filesize; __wt_curstat_dsrc_final(cst); *was_fast = true; } err: __wt_free(session, tableconf); __wt_buf_free(session, &namebuf); return (ret); } /* * __wt_curstat_table_init -- * Initialize the statistics for a table. */ int __wt_curstat_table_init(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR_STAT *cst) { WT_CURSOR *stat_cursor; WT_DECL_ITEM(buf); WT_DECL_RET; WT_DSRC_STATS *new, *stats; WT_TABLE *table; u_int i; const char *name; bool was_fast; /* * If only gathering table size statistics, try a fast path that * avoids the schema and table list locks. */ if (F_ISSET(cst, WT_CONN_STAT_SIZE)) { WT_RET(__curstat_size_only(session, uri, &was_fast, cst)); if (was_fast) return (0); } name = uri + strlen("table:"); WT_RET(__wt_schema_get_table( session, name, strlen(name), false, &table)); WT_ERR(__wt_scr_alloc(session, 0, &buf)); /* * Process the column groups. * * Set the cursor to reference the data source statistics; we don't * initialize it, instead we copy (rather than aggregate), the first * column's statistics, which has the same effect. */ stats = &cst->u.dsrc_stats; for (i = 0; i < WT_COLGROUPS(table); i++) { WT_ERR(__wt_buf_fmt( session, buf, "statistics:%s", table->cgroups[i]->name)); WT_ERR(__wt_curstat_open( session, buf->data, cfg, &stat_cursor)); new = (WT_DSRC_STATS *)WT_CURSOR_STATS(stat_cursor); if (i == 0) *stats = *new; else __wt_stat_dsrc_aggregate_single(new, stats); WT_ERR(stat_cursor->close(stat_cursor)); } /* Process the indices. */ WT_ERR(__wt_schema_open_indices(session, table)); for (i = 0; i < table->nindices; i++) { WT_ERR(__wt_buf_fmt( session, buf, "statistics:%s", table->indices[i]->name)); WT_ERR(__wt_curstat_open( session, buf->data, cfg, &stat_cursor)); new = (WT_DSRC_STATS *)WT_CURSOR_STATS(stat_cursor); __wt_stat_dsrc_aggregate_single(new, stats); WT_ERR(stat_cursor->close(stat_cursor)); } __wt_curstat_dsrc_final(cst); err: __wt_schema_release_table(session, table); __wt_scr_free(session, &buf); return (ret); }