Enhancements to sqlite_memstat:

(1) Add an extra "schema" column to show the schema name for ZIPVFS stats.
(2) Only show ZIPVFS stats to schema that use ZIPVFS
(3) Put a NULL in unused columns of the output.

FossilOrigin-Name: 9351135b4331107be2f2bda7b6adbd5436381f4f9a68340e8a172b6517ec3f12
This commit is contained in:
drh 2018-09-27 16:57:42 +00:00
parent 7c5577acdc
commit d7134fe0c1
3 changed files with 148 additions and 63 deletions

View File

@ -20,7 +20,7 @@
** .header on
** SELECT * FROM memstat;
*/
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB)
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_MEMSTATVTAB)
#if !defined(SQLITEINT_H)
#include "sqlite3ext.h"
#endif
@ -47,9 +47,11 @@ typedef struct memstat_cursor memstat_cursor;
struct memstat_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3 *db; /* Database connection for this cursor */
sqlite3_int64 iRowid; /* The rowid */
sqlite3_int64 iCur; /* Current value */
sqlite3_int64 iHiwtr; /* High-water mark */
int iRowid; /* Current row in aMemstatColumn[] */
int iDb; /* Which schema we are looking at */
int nDb; /* Number of schemas */
char **azDb; /* Names of all schemas */
sqlite3_int64 aVal[2]; /* Result values */
};
/*
@ -77,10 +79,11 @@ static int memstatConnect(
/* Column numbers */
#define MSV_COLUMN_NAME 0 /* Name of quantity being measured */
#define MSV_COLUMN_CURRENT 1 /* Current value */
#define MSV_COLUMN_HIWTR 2 /* Highwater mark */
#define MSV_COLUMN_SCHEMA 1 /* schema name */
#define MSV_COLUMN_VALUE 2 /* Current value */
#define MSV_COLUMN_HIWTR 3 /* Highwater mark */
rc = sqlite3_declare_vtab(db,"CREATE TABLE x(name,current,hiwtr)");
rc = sqlite3_declare_vtab(db,"CREATE TABLE x(name,schema,value,hiwtr)");
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
@ -112,10 +115,59 @@ static int memstatOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
return SQLITE_OK;
}
/*
** Clear all the schema names from a cursor
*/
static void memstatClearSchema(memstat_cursor *pCur){
int i;
if( pCur->azDb==0 ) return;
for(i=0; i<pCur->nDb; i++){
sqlite3_free(pCur->azDb[i]);
}
sqlite3_free(pCur->azDb);
pCur->azDb = 0;
pCur->nDb = 0;
}
/*
** Fill in the azDb[] array for the cursor.
*/
static int memstatFindSchemas(memstat_cursor *pCur){
sqlite3_stmt *pStmt = 0;
int rc;
if( pCur->nDb ) return SQLITE_OK;
rc = sqlite3_prepare_v2(pCur->db, "PRAGMA database_list", -1, &pStmt, 0);
if( rc ){
sqlite3_finalize(pStmt);
return rc;
}
while( sqlite3_step(pStmt)==SQLITE_ROW ){
char **az, *z;
az = sqlite3_realloc(pCur->azDb, sizeof(char*)*(pCur->nDb+1));
if( az==0 ){
memstatClearSchema(pCur);
return SQLITE_NOMEM;
}
pCur->azDb = az;
z = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
if( z==0 ){
memstatClearSchema(pCur);
return SQLITE_NOMEM;
}
pCur->azDb[pCur->nDb] = z;
pCur->nDb++;
}
sqlite3_finalize(pStmt);
return SQLITE_OK;
}
/*
** Destructor for a memstat_cursor.
*/
static int memstatClose(sqlite3_vtab_cursor *cur){
memstat_cursor *pCur = (memstat_cursor*)cur;
memstatClearSchema(pCur);
sqlite3_free(cur);
return SQLITE_OK;
}
@ -125,7 +177,7 @@ static int memstatClose(sqlite3_vtab_cursor *cur){
** Allowed values for aMemstatColumn[].eType
*/
#define MSV_GSTAT 0 /* sqlite3_status64() information */
#define MSV_DBSTAT 1 /* sqlite3_db_status() information */
#define MSV_DB 1 /* sqlite3_db_status() information */
#define MSV_ZIPVFS 2 /* ZIPVFS file-control with 64-bit return */
/*
@ -134,36 +186,38 @@ static int memstatClose(sqlite3_vtab_cursor *cur){
*/
static const struct MemstatColumns {
const char *zName; /* Symbolic name */
int eType; /* Type of interface */
unsigned char eType; /* Type of interface */
unsigned char mNull; /* Bitmask of which columns are NULL */
/* 2: dbname, 4: current, 8: hiwtr */
int eOp; /* Opcode */
} aMemstatColumn[] = {
{ "MEMORY_USED", MSV_GSTAT, SQLITE_STATUS_MEMORY_USED },
{ "MALLOC_SIZE", MSV_GSTAT, SQLITE_STATUS_MALLOC_SIZE },
{ "MALLOC_COUNT", MSV_GSTAT, SQLITE_STATUS_MALLOC_COUNT },
{ "PAGECACHE_USED", MSV_GSTAT, SQLITE_STATUS_PAGECACHE_USED },
{ "PAGECACHE_OVERFLOW", MSV_GSTAT, SQLITE_STATUS_PAGECACHE_OVERFLOW },
{ "PAGECACHE_SIZE", MSV_GSTAT, SQLITE_STATUS_PAGECACHE_SIZE },
{ "PARSER_STACK", MSV_GSTAT, SQLITE_STATUS_PARSER_STACK },
{ "DB_LOOKASIDE_USED", MSV_DBSTAT, SQLITE_DBSTATUS_LOOKASIDE_USED },
{ "DB_CACHE_USED", MSV_DBSTAT, SQLITE_DBSTATUS_CACHE_USED },
{ "DB_SCHEMA_USED", MSV_DBSTAT, SQLITE_DBSTATUS_SCHEMA_USED },
{ "DB_STMT_USED", MSV_DBSTAT, SQLITE_DBSTATUS_STMT_USED },
{ "DB_LOOKASIDE_HIT", MSV_DBSTAT, SQLITE_DBSTATUS_LOOKASIDE_HIT },
{ "DB_LOOKASIDE_MISS_SIZE", MSV_DBSTAT, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE },
{ "DB_LOOKASIDE_MISS_FULL", MSV_DBSTAT, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL },
{ "DB_CACHE_HIT", MSV_DBSTAT, SQLITE_DBSTATUS_CACHE_HIT },
{ "DB_CACHE_MISS", MSV_DBSTAT, SQLITE_DBSTATUS_CACHE_MISS },
{ "DB_CACHE_WRITE", MSV_DBSTAT, SQLITE_DBSTATUS_CACHE_WRITE },
{ "DB_DEFERRED_FKS", MSV_DBSTAT, SQLITE_DBSTATUS_DEFERRED_FKS },
{ "DB_CACHE_USED_SHARED", MSV_DBSTAT, SQLITE_DBSTATUS_CACHE_USED_SHARED },
{ "DB_CACHE_SPILL", MSV_DBSTAT, SQLITE_DBSTATUS_CACHE_SPILL },
{"MEMORY_USED", MSV_GSTAT, 2, SQLITE_STATUS_MEMORY_USED },
{"MALLOC_SIZE", MSV_GSTAT, 6, SQLITE_STATUS_MALLOC_SIZE },
{"MALLOC_COUNT", MSV_GSTAT, 2, SQLITE_STATUS_MALLOC_COUNT },
{"PAGECACHE_USED", MSV_GSTAT, 2, SQLITE_STATUS_PAGECACHE_USED },
{"PAGECACHE_OVERFLOW", MSV_GSTAT, 2, SQLITE_STATUS_PAGECACHE_OVERFLOW },
{"PAGECACHE_SIZE", MSV_GSTAT, 6, SQLITE_STATUS_PAGECACHE_SIZE },
{"PARSER_STACK", MSV_GSTAT, 6, SQLITE_STATUS_PARSER_STACK },
{"DB_LOOKASIDE_USED", MSV_DB, 2, SQLITE_DBSTATUS_LOOKASIDE_USED },
{"DB_LOOKASIDE_HIT", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_HIT },
{"DB_LOOKASIDE_MISS_SIZE", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE},
{"DB_LOOKASIDE_MISS_FULL", MSV_DB, 6, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL},
{"DB_CACHE_USED", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_USED },
{"DB_CACHE_USED_SHARED", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_USED_SHARED },
{"DB_SCHEMA_USED", MSV_DB, 10, SQLITE_DBSTATUS_SCHEMA_USED },
{"DB_STMT_USED", MSV_DB, 10, SQLITE_DBSTATUS_STMT_USED },
{"DB_CACHE_HIT", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_HIT },
{"DB_CACHE_MISS", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_MISS },
{"DB_CACHE_WRITE", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_WRITE },
{"DB_CACHE_SPILL", MSV_DB, 10, SQLITE_DBSTATUS_CACHE_SPILL },
{"DB_DEFERRED_FKS", MSV_DB, 10, SQLITE_DBSTATUS_DEFERRED_FKS },
#ifdef SQLITE_ENABLE_ZIPVFS
{ "ZIPVFS_CACHE_USED", MSV_ZIPVFS, 231454 },
{ "ZIPVFS_CACHE_HIT", MSV_ZIPVFS, 231455 },
{ "ZIPVFS_CACHE_MISS", MSV_ZIPVFS, 231456 },
{ "ZIPVFS_CACHE_WRITE", MSV_ZIPVFS, 231457 },
{ "ZIPVFS_DIRECT_READ", MSV_ZIPVFS, 231458 },
{ "ZIPVFS_DIRECT_BYTES", MSV_ZIPVFS, 231459 },
{"ZIPVFS_CACHE_USED", MSV_ZIPVFS, 8, 231454 },
{"ZIPVFS_CACHE_HIT", MSV_ZIPVFS, 8, 231455 },
{"ZIPVFS_CACHE_MISS", MSV_ZIPVFS, 8, 231456 },
{"ZIPVFS_CACHE_WRITE", MSV_ZIPVFS, 8, 231457 },
{"ZIPVFS_DIRECT_READ", MSV_ZIPVFS, 8, 231458 },
{"ZIPVFS_DIRECT_BYTES", MSV_ZIPVFS, 8, 231459 },
#endif /* SQLITE_ENABLE_ZIPVFS */
};
#define MSV_NROW (sizeof(aMemstatColumn)/sizeof(aMemstatColumn[0]))
@ -173,7 +227,41 @@ static const struct MemstatColumns {
*/
static int memstatNext(sqlite3_vtab_cursor *cur){
memstat_cursor *pCur = (memstat_cursor*)cur;
pCur->iRowid++;
int i;
assert( pCur->iRowid<=MSV_NROW );
while(1){
i = (int)pCur->iRowid - 1;
if( (aMemstatColumn[i].mNull & 2)!=0 || (++pCur->iDb)>=pCur->nDb ){
pCur->iRowid++;
if( pCur->iRowid>MSV_NROW ) return SQLITE_OK; /* End of the table */
pCur->iDb = 0;
i++;
}
pCur->aVal[0] = 0;
pCur->aVal[1] = 0;
switch( aMemstatColumn[i].eType ){
case MSV_GSTAT: {
sqlite3_status64(aMemstatColumn[i].eOp,
&pCur->aVal[0], &pCur->aVal[1],0);
break;
}
case MSV_DB: {
int xCur, xHiwtr;
sqlite3_db_status(pCur->db, aMemstatColumn[i].eOp, &xCur, &xHiwtr, 0);
pCur->aVal[0] = xCur;
pCur->aVal[1] = xHiwtr;
break;
}
case MSV_ZIPVFS: {
int rc;
rc = sqlite3_file_control(pCur->db, pCur->azDb[pCur->iDb],
aMemstatColumn[i].eOp, (void*)&pCur->aVal[0]);
if( rc!=SQLITE_OK ) continue;
break;
}
}
break;
}
return SQLITE_OK;
}
@ -189,33 +277,29 @@ static int memstatColumn(
){
memstat_cursor *pCur = (memstat_cursor*)cur;
int i;
sqlite3_int64 iCur = 0, iHiwtr = 0;
assert( pCur->iRowid>0 && pCur->iRowid<=MSV_NROW );
i = (int)pCur->iRowid - 1;
if( iCol==MSV_COLUMN_NAME ){
sqlite3_result_text(ctx, aMemstatColumn[i].zName, -1, SQLITE_STATIC);
if( (aMemstatColumn[i].mNull & (1<<iCol))!=0 ){
return SQLITE_OK;
}
switch( aMemstatColumn[i].eType ){
case MSV_GSTAT: {
sqlite3_status64(aMemstatColumn[i].eOp, &iCur, &iHiwtr, 0);
switch( iCol ){
case MSV_COLUMN_NAME: {
sqlite3_result_text(ctx, aMemstatColumn[i].zName, -1, SQLITE_STATIC);
break;
}
case MSV_DBSTAT: {
int xCur, xHiwtr;
sqlite3_db_status(pCur->db, aMemstatColumn[i].eOp, &xCur, &xHiwtr, 0);
iCur = xCur;
iHiwtr = xHiwtr;
case MSV_COLUMN_SCHEMA: {
sqlite3_result_text(ctx, pCur->azDb[pCur->iDb], -1, 0);
break;
}
case MSV_ZIPVFS: {
sqlite3_file_control(pCur->db, 0, aMemstatColumn[i].eOp, (void*)&iCur);
case MSV_COLUMN_VALUE: {
sqlite3_result_int64(ctx, pCur->aVal[0]);
break;
}
case MSV_COLUMN_HIWTR: {
sqlite3_result_int64(ctx, pCur->aVal[1]);
break;
}
}
if( iCol==MSV_COLUMN_HIWTR ) iCur = iHiwtr;
sqlite3_result_int64(ctx, iCur);
return SQLITE_OK;
}
@ -225,7 +309,7 @@ static int memstatColumn(
*/
static int memstatRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
memstat_cursor *pCur = (memstat_cursor*)cur;
*pRowid = pCur->iRowid;
*pRowid = pCur->iRowid*1000 + pCur->iDb;
return SQLITE_OK;
}
@ -250,8 +334,9 @@ static int memstatFilter(
int argc, sqlite3_value **argv
){
memstat_cursor *pCur = (memstat_cursor *)pVtabCursor;
pCur->iRowid = 0;
return memstatNext(pVtabCursor);
pCur->iRowid = 1;
pCur->iDb = 0;
return memstatFindSchemas(pCur);
}
/*
@ -326,4 +411,4 @@ int sqlite3_memstat_init(
return rc;
}
#endif /* SQLITE_CORE */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_MEMSTATVTAB) */

View File

@ -1,5 +1,5 @@
C Add\sinitial\sZIPVFS\ssupport\sfor\sthe\s"main"\sdatabase\sto\sthe\ssqlite_memstat\nvirtual\stable.
D 2018-09-27T15:45:03.985
C Enhancements\sto\ssqlite_memstat:\n(1)\sAdd\san\sextra\s"schema"\scolumn\sto\sshow\sthe\sschema\sname\sfor\sZIPVFS\sstats.\n(2)\sOnly\sshow\sZIPVFS\sstats\sto\sschema\sthat\suse\sZIPVFS\n(3)\sPut\sa\sNULL\sin\sunused\scolumns\sof\sthe\soutput.
D 2018-09-27T16:57:42.381
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 01e95208a78b57d056131382c493c963518f36da4c42b12a97eb324401b3a334
@ -286,7 +286,7 @@ F ext/misc/fileio.c 7317d825fab6a3c48f6e3822a00a6a22e08e55af31700ac96f16a523f830
F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25
F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c
F ext/misc/json1.c 276f87dc8365b34b0fffb7ef32481dd07fac6fdb3224e2822396a48377ac8363
F ext/misc/memstat.c 09bfa9a16be3d44932233fd1aa95cdd09d7b3f72d3f36805483bfe23b48fe8ec
F ext/misc/memstat.c 1db91b25c9a4a1b73696c14d32a5b39adf6d2e9b11d0cdb5a9f35e86e3da7d36
F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567
F ext/misc/mmapwarm.c 70b618f2d0bde43fae288ad0b7498a629f2b6f61b50a27e06fae3cd23c83af29
F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342
@ -1770,7 +1770,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 0b44e1f68e0c8349367e3f929d4734c3df96338ec8d6fb652565bf894e8b8343
R eeaa8104d4a2a8c673af2ed0c882ed24
P 9cd27350b0f62debfe3238c57c3ab51079699142e82c05a7ec8460a8429f55f2
R 3b442b9685bf2fd6f2b22a8d8be22779
U drh
Z 5dadcc7b0adb63e8fb1777ba189f8dd3
Z 2fa27b2796fd3980348a5b531bf6823d

View File

@ -1 +1 @@
9cd27350b0f62debfe3238c57c3ab51079699142e82c05a7ec8460a8429f55f2
9351135b4331107be2f2bda7b6adbd5436381f4f9a68340e8a172b6517ec3f12