]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add extension "mmapwarm.c". Provides function sqlite3_mmap_warm(), used to
authordan <dan@noemail.net>
Mon, 18 Sep 2017 16:28:56 +0000 (16:28 +0000)
committerdan <dan@noemail.net>
Mon, 18 Sep 2017 16:28:56 +0000 (16:28 +0000)
"warm up" the memory mapping used by SQLite in mmap mode to access db file
content.

FossilOrigin-Name: d4a30b91f9aad93510baead8c04ee51b82c98763be5a224ed4873298214c963a

Makefile.in
Makefile.msc
ext/misc/mmapwarm.c [new file with mode: 0644]
main.mk
manifest
manifest.uuid
src/test1.c

index 50cd5e8e23ab1cd034d7832c1f8cf8c20642e540..58c2c2919b6981600786931dd9b2e309eafd9ae6 100644 (file)
@@ -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 \
index 1289fe6d5b3031d404487cbf7ec1bbc272b5be33..799024652dc4af5ec9f0e7fc09290da61a9df178 100644 (file)
@@ -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 (file)
index 0000000..4e23638
--- /dev/null
@@ -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 054f6518a514d4639b69d30066be59beabf76e0a..7da6db15f139f2e6836835deb8c1e2466bf221d7 100644 (file)
--- 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 \
index 3c256819da5419e90b9b8dfb0f5b9e3d2dd6200a..d673fb237f9be8bb82111faf9ace1837b8acc1cf 100644 (file)
--- 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
index 811612d1134697b1afe5d6fdf664c697ddb7b2d2..17ca822d098d775cc974bb577a18eed4c2b92a37 100644 (file)
@@ -1 +1 @@
-42f07775556758754e92e29a759d200d0d81d16eee83ab982b840db11292f834
\ No newline at end of file
+d4a30b91f9aad93510baead8c04ee51b82c98763be5a224ed4873298214c963a
\ No newline at end of file
index 7a6ff2163f0a768fc35a8b8e055fa050ce4fd152..d70ce77a7a1175eb0abfe128db012831b6199fcd 100644 (file)
@@ -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);