diff --git a/ext/misc/memstat.c b/ext/misc/memstat.c index ebfeb3235c..84078c9ceb 100644 --- a/ext/misc/memstat.c +++ b/ext/misc/memstat.c @@ -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; inDb; 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<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) */ diff --git a/manifest b/manifest index 3300211b2e..330f25ebf9 100644 --- a/manifest +++ b/manifest @@ -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 diff --git a/manifest.uuid b/manifest.uuid index e9f468b470..97e5040947 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9cd27350b0f62debfe3238c57c3ab51079699142e82c05a7ec8460a8429f55f2 \ No newline at end of file +9351135b4331107be2f2bda7b6adbd5436381f4f9a68340e8a172b6517ec3f12 \ No newline at end of file