From: dan Date: Mon, 18 Sep 2017 16:28:56 +0000 (+0000) Subject: Add extension "mmapwarm.c". Provides function sqlite3_mmap_warm(), used to X-Git-Tag: version-3.21.0~77^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=460f1fa55cd4fdca39977f5f38e173f2ac44bace;p=thirdparty%2Fsqlite.git Add extension "mmapwarm.c". Provides function sqlite3_mmap_warm(), used to "warm up" the memory mapping used by SQLite in mmap mode to access db file content. FossilOrigin-Name: d4a30b91f9aad93510baead8c04ee51b82c98763be5a224ed4873298214c963a --- diff --git a/Makefile.in b/Makefile.in index 50cd5e8e23..58c2c2919b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -428,6 +428,7 @@ TESTSRC += \ $(TOP)/ext/fts5/fts5_test_mi.c \ $(TOP)/ext/fts5/fts5_test_tok.c \ $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/mmapwarm.c \ $(TOP)/ext/misc/nextchar.c \ $(TOP)/ext/misc/percentile.c \ $(TOP)/ext/misc/regexp.c \ diff --git a/Makefile.msc b/Makefile.msc index 1289fe6d5b..799024652d 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -1411,6 +1411,7 @@ TESTEXT = \ $(TOP)\ext\fts5\fts5_test_mi.c \ $(TOP)\ext\fts5\fts5_test_tok.c \ $(TOP)\ext\misc\ieee754.c \ + $(TOP)\ext\misc\mmapwarm.c $(TOP)\ext\misc\nextchar.c \ $(TOP)\ext\misc\percentile.c \ $(TOP)\ext\misc\regexp.c \ diff --git a/ext/misc/mmapwarm.c b/ext/misc/mmapwarm.c new file mode 100644 index 0000000000..4e23638a99 --- /dev/null +++ b/ext/misc/mmapwarm.c @@ -0,0 +1,108 @@ +/* +** 2017-09-18 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +*/ + +#include "sqlite3.h" + + +/* +** This function is used to touch each page of a mapping of a memory +** mapped SQLite database. Assuming that the system has sufficient free +** memory and supports sufficiently large mappings, this causes the OS +** to cache the entire database in main memory, making subsequent +** database accesses faster. +** +** If the second parameter to this function is not NULL, it is the name of +** the specific database to operate on (i.e. "main" or the name of an +** attached database). +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +** It is not considered an error if the file is not memory-mapped, or if +** the mapping does not span the entire file. If an error does occur, a +** transaction may be left open on the database file. +** +** It is illegal to call this function when the database handle has an +** open transaction. SQLITE_MISUSE is returned in this case. +*/ +int sqlite3_mmap_warm(sqlite3 *db, const char *zDb){ + int rc = SQLITE_OK; + char *zSql = 0; + int pgsz = 0; + int nTotal = 0; + + if( 0==sqlite3_get_autocommit(db) ) return SQLITE_MISUSE; + + /* Open a read-only transaction on the file in question */ + zSql = sqlite3_mprintf("BEGIN; SELECT * FROM %s%q%ssqlite_master", + (zDb ? "'" : ""), (zDb ? zDb : ""), (zDb ? "'." : "") + ); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_exec(db, zSql, 0, 0, 0); + sqlite3_free(zSql); + + /* Find the SQLite page size of the file */ + if( rc==SQLITE_OK ){ + zSql = sqlite3_mprintf("PRAGMA %s%q%spage_size", + (zDb ? "'" : ""), (zDb ? zDb : ""), (zDb ? "'." : "") + ); + if( zSql==0 ){ + rc = SQLITE_NOMEM; + }else{ + sqlite3_stmt *pPgsz = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pPgsz, 0); + sqlite3_free(zSql); + if( rc==SQLITE_OK ){ + if( sqlite3_step(pPgsz)==SQLITE_ROW ){ + pgsz = sqlite3_column_int(pPgsz, 0); + } + rc = sqlite3_finalize(pPgsz); + } + if( rc==SQLITE_OK && pgsz==0 ){ + rc = SQLITE_ERROR; + } + } + } + + /* Touch each mmap'd page of the file */ + if( rc==SQLITE_OK ){ + int rc2; + sqlite3_file *pFd = 0; + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFd); + if( rc==SQLITE_OK && pFd->pMethods->iVersion>=3 ){ + sqlite3_int64 iPg = 1; + sqlite3_io_methods const *p = pFd->pMethods; + while( 1 ){ + unsigned char *pMap; + rc = p->xFetch(pFd, pgsz*iPg, pgsz, (void**)&pMap); + if( rc!=SQLITE_OK || pMap==0 ) break; + + nTotal += pMap[0]; + nTotal += pMap[pgsz-1]; + + rc = p->xUnfetch(pFd, pgsz*iPg, (void*)pMap); + if( rc!=SQLITE_OK ) break; + iPg++; + } + sqlite3_log(SQLITE_OK, + "sqlite3_mmap_warm_cache: Warmed up %d pages of %s", iPg==1?0:iPg, + sqlite3_db_filename(db, zDb) + ); + } + + rc2 = sqlite3_exec(db, "END", 0, 0, 0); + if( rc==SQLITE_OK ) rc = rc2; + } + + return rc; +} + diff --git a/main.mk b/main.mk index 054f6518a5..7da6db15f1 100644 --- a/main.mk +++ b/main.mk @@ -334,6 +334,7 @@ TESTSRC += \ $(TOP)/ext/misc/fileio.c \ $(TOP)/ext/misc/fuzzer.c \ $(TOP)/ext/misc/ieee754.c \ + $(TOP)/ext/misc/mmapwarm.c \ $(TOP)/ext/misc/nextchar.c \ $(TOP)/ext/misc/percentile.c \ $(TOP)/ext/misc/regexp.c \ diff --git a/manifest b/manifest index 3c256819da..d673fb237f 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -C Fix\sthe\sCSV\svirtual\stable\sextension\sso\sthat\sit\sworks\swhen\sthe\sdefault\scharacter\nis\sunsigned. -D 2017-09-18T00:18:31.200 -F Makefile.in c644bbe8ebe4aae82ad6783eae6b6beea4c727b99ff97568b847ced5e2ac7afb +C Add\sextension\s"mmapwarm.c".\sProvides\sfunction\ssqlite3_mmap_warm(),\sused\sto\n"warm\sup"\sthe\smemory\smapping\sused\sby\sSQLite\sin\smmap\smode\sto\saccess\sdb\sfile\ncontent. +D 2017-09-18T16:28:56.386 +F Makefile.in 4bc36d913c2e3e2d326d588d72f618ac9788b2fd4b7efda61102611a6495c3ff F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 6a7a74bf60ad395098c0bd175ab054cd65ef85d7f034198d52bcc4d9e5fb4c6b +F Makefile.msc 2a1cf3959b03b3cffedcbc3cf6bde8c992ed865667f2a7aefb14cb2105ec97c7 F README.md f5c87359573c4d255425e588a56554b50fdcc2afba4e017a2e02a43701456afd F VERSION f81232df28e2d3ff049feefad5fbd5489cc33697f6bd2ecf61af7f0dde3b83d0 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -270,6 +270,7 @@ F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c F ext/misc/json1.c dbe086615b9546c156bf32b9378fc09383b58bd17513b866cfd24c1e15281984 F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 +F ext/misc/mmapwarm.c 70b618f2d0bde43fae288ad0b7498a629f2b6f61b50a27e06fae3cd23c83af29 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e F ext/misc/regexp.c a68d25c659bd2d893cd1215667bbf75ecb9dc7d4 @@ -381,7 +382,7 @@ F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk da75a0527a56da0b7f568a976b3cb69756613080f16e4d208b6c6a0495bfb132 +F main.mk d0145f02deb67d65c4822225847cba112c237cdb62f4905eeb4b648e82bfc222 F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -468,7 +469,7 @@ F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6 F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 487951d81f9704800fd9f0ffdaa2f935a83ccb6be3575c2c4ef83e4789b4c828 -F src/test1.c 8513b17ca4a7a9ba28748535d178b6e472ec7394ae0eea53907f2d3bcdbab2df +F src/test1.c a947b2554fa77d0ef2dd21d1ef08e37e5d91b17af83de923a4e3c7f10957a2eb F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c b8434949dfb8aff8dfa082c8b592109e77844c2135ed3c492113839b6956255b F src/test4.c 18ec393bb4d0ad1de729f0b94da7267270f3d8e6 @@ -1654,7 +1655,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 29227d00a9999f0f28a0b55ef70183799a667c3b9d81d2e5ac0ab1840bef98b1 -R ccebe3b4b57d7dc8c5482ee2b9f63107 -U drh -Z a535a0ac2d4006e12331e0812c689362 +P 42f07775556758754e92e29a759d200d0d81d16eee83ab982b840db11292f834 +R 2de3e498b6d544466fabd508443a98d0 +T *branch * mmap-warm +T *sym-mmap-warm * +T -sym-trunk * +U dan +Z 5972d569bdc42461a8703da92c49c171 diff --git a/manifest.uuid b/manifest.uuid index 811612d113..17ca822d09 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -42f07775556758754e92e29a759d200d0d81d16eee83ab982b840db11292f834 \ No newline at end of file +d4a30b91f9aad93510baead8c04ee51b82c98763be5a224ed4873298214c963a \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index 7a6ff2163f..d70ce77a7a 100644 --- a/src/test1.c +++ b/src/test1.c @@ -7415,6 +7415,35 @@ static int SQLITE_TCLAPI test_dbconfig_maindbname_icecube( } } +/* +** Usage: sqlite3_mmap_warm DB DBNAME +*/ +static int SQLITE_TCLAPI test_mmap_warm( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**); + extern int sqlite3_mmap_warm(sqlite3 *db, const char *); + + if( objc!=2 && objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "DB ?DBNAME?"); + return TCL_ERROR; + }else{ + int rc; + sqlite3 *db; + const char *zDb = 0; + if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; + if( objc==3 ){ + zDb = Tcl_GetString(objv[2]); + } + rc = sqlite3_mmap_warm(db, zDb); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + return TCL_OK; + } +} + /* ** Register commands with the TCL interpreter. */ @@ -7684,8 +7713,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_snapshot_open_blob", test_snapshot_open_blob, 0 }, { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob, 0 }, #endif - { "sqlite3_delete_database", test_delete_database, 0 }, - { "atomic_batch_write", test_atomic_batch_write, 0 }, + { "sqlite3_delete_database", test_delete_database, 0 }, + { "atomic_batch_write", test_atomic_batch_write, 0 }, + { "sqlite3_mmap_warm", test_mmap_warm, 0 }, }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE);