/ Check-in [1b2de414]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the sqlite3_mmap_warm() function as an extension in the ext/misc/mmapwarm.c source file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1b2de41453ac33de82f9cd6cbb92eee4fe184fb282c27e5efa5243c8cb239630
User & Date: drh 2017-09-18 18:17:01
Context
2017-09-20
09:09
Updates to the "lemon.html" document received from Andy Goth. check-in: 5b2002f3 user: drh tags: trunk
2017-09-18
18:17
Add the sqlite3_mmap_warm() function as an extension in the ext/misc/mmapwarm.c source file. check-in: 1b2de414 user: drh tags: trunk
18:08
Fix a typo in the MSVC makefile. Closed-Leaf check-in: 3235835b user: drh tags: mmap-warm
13:16
Minor simplification of error message generation during compound query code generation. check-in: a9447193 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   424    424     $(TOP)/ext/misc/eval.c \
   425    425     $(TOP)/ext/misc/fileio.c \
   426    426     $(TOP)/ext/misc/fuzzer.c \
   427    427     $(TOP)/ext/fts5/fts5_tcl.c \
   428    428     $(TOP)/ext/fts5/fts5_test_mi.c \
   429    429     $(TOP)/ext/fts5/fts5_test_tok.c \
   430    430     $(TOP)/ext/misc/ieee754.c \
          431  +  $(TOP)/ext/misc/mmapwarm.c \
   431    432     $(TOP)/ext/misc/nextchar.c \
   432    433     $(TOP)/ext/misc/percentile.c \
   433    434     $(TOP)/ext/misc/regexp.c \
   434    435     $(TOP)/ext/misc/remember.c \
   435    436     $(TOP)/ext/misc/series.c \
   436    437     $(TOP)/ext/misc/spellfix.c \
   437    438     $(TOP)/ext/misc/totype.c \

Changes to Makefile.msc.

  1407   1407     $(TOP)\ext\misc\eval.c \
  1408   1408     $(TOP)\ext\misc\fileio.c \
  1409   1409     $(TOP)\ext\misc\fuzzer.c \
  1410   1410     $(TOP)\ext\fts5\fts5_tcl.c \
  1411   1411     $(TOP)\ext\fts5\fts5_test_mi.c \
  1412   1412     $(TOP)\ext\fts5\fts5_test_tok.c \
  1413   1413     $(TOP)\ext\misc\ieee754.c \
         1414  +  $(TOP)\ext\misc\mmapwarm.c \
  1414   1415     $(TOP)\ext\misc\nextchar.c \
  1415   1416     $(TOP)\ext\misc\percentile.c \
  1416   1417     $(TOP)\ext\misc\regexp.c \
  1417   1418     $(TOP)\ext\misc\remember.c \
  1418   1419     $(TOP)\ext\misc\series.c \
  1419   1420     $(TOP)\ext\misc\spellfix.c \
  1420   1421     $(TOP)\ext\misc\totype.c \

Added ext/misc/mmapwarm.c.

            1  +/*
            2  +** 2017-09-18
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +*/
           14  +
           15  +#include "sqlite3.h"
           16  +
           17  +
           18  +/*
           19  +** This function is used to touch each page of a mapping of a memory
           20  +** mapped SQLite database. Assuming that the system has sufficient free
           21  +** memory and supports sufficiently large mappings, this causes the OS 
           22  +** to cache the entire database in main memory, making subsequent 
           23  +** database accesses faster.
           24  +**
           25  +** If the second parameter to this function is not NULL, it is the name of
           26  +** the specific database to operate on (i.e. "main" or the name of an
           27  +** attached database).
           28  +**
           29  +** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
           30  +** It is not considered an error if the file is not memory-mapped, or if
           31  +** the mapping does not span the entire file. If an error does occur, a
           32  +** transaction may be left open on the database file.
           33  +**
           34  +** It is illegal to call this function when the database handle has an 
           35  +** open transaction. SQLITE_MISUSE is returned in this case.
           36  +*/
           37  +int sqlite3_mmap_warm(sqlite3 *db, const char *zDb){
           38  +  int rc = SQLITE_OK;
           39  +  char *zSql = 0;
           40  +  int pgsz = 0;
           41  +  int nTotal = 0;
           42  +
           43  +  if( 0==sqlite3_get_autocommit(db) ) return SQLITE_MISUSE;
           44  +
           45  +  /* Open a read-only transaction on the file in question */
           46  +  zSql = sqlite3_mprintf("BEGIN; SELECT * FROM %s%q%ssqlite_master", 
           47  +      (zDb ? "'" : ""), (zDb ? zDb : ""), (zDb ? "'." : "")
           48  +  );
           49  +  if( zSql==0 ) return SQLITE_NOMEM;
           50  +  rc = sqlite3_exec(db, zSql, 0, 0, 0);
           51  +  sqlite3_free(zSql);
           52  +
           53  +  /* Find the SQLite page size of the file */
           54  +  if( rc==SQLITE_OK ){
           55  +    zSql = sqlite3_mprintf("PRAGMA %s%q%spage_size", 
           56  +        (zDb ? "'" : ""), (zDb ? zDb : ""), (zDb ? "'." : "")
           57  +    );
           58  +    if( zSql==0 ){
           59  +      rc = SQLITE_NOMEM;
           60  +    }else{
           61  +      sqlite3_stmt *pPgsz = 0;
           62  +      rc = sqlite3_prepare_v2(db, zSql, -1, &pPgsz, 0);
           63  +      sqlite3_free(zSql);
           64  +      if( rc==SQLITE_OK ){
           65  +        if( sqlite3_step(pPgsz)==SQLITE_ROW ){
           66  +          pgsz = sqlite3_column_int(pPgsz, 0);
           67  +        }
           68  +        rc = sqlite3_finalize(pPgsz);
           69  +      }
           70  +      if( rc==SQLITE_OK && pgsz==0 ){
           71  +        rc = SQLITE_ERROR;
           72  +      }
           73  +    }
           74  +  }
           75  +
           76  +  /* Touch each mmap'd page of the file */
           77  +  if( rc==SQLITE_OK ){
           78  +    int rc2;
           79  +    sqlite3_file *pFd = 0;
           80  +    rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFd);
           81  +    if( rc==SQLITE_OK && pFd->pMethods->iVersion>=3 ){
           82  +      sqlite3_int64 iPg = 1;
           83  +      sqlite3_io_methods const *p = pFd->pMethods;
           84  +      while( 1 ){
           85  +        unsigned char *pMap;
           86  +        rc = p->xFetch(pFd, pgsz*iPg, pgsz, (void**)&pMap);
           87  +        if( rc!=SQLITE_OK || pMap==0 ) break;
           88  +
           89  +        nTotal += pMap[0];
           90  +        nTotal += pMap[pgsz-1];
           91  +
           92  +        rc = p->xUnfetch(pFd, pgsz*iPg, (void*)pMap);
           93  +        if( rc!=SQLITE_OK ) break;
           94  +        iPg++;
           95  +      }
           96  +      sqlite3_log(SQLITE_OK, 
           97  +          "sqlite3_mmap_warm_cache: Warmed up %d pages of %s", iPg==1?0:iPg,
           98  +          sqlite3_db_filename(db, zDb)
           99  +      );
          100  +    }
          101  +
          102  +    rc2 = sqlite3_exec(db, "END", 0, 0, 0);
          103  +    if( rc==SQLITE_OK ) rc = rc2;
          104  +  }
          105  +
          106  +  return rc;
          107  +}
          108  +

Changes to main.mk.

   330    330     $(TOP)/ext/misc/carray.c \
   331    331     $(TOP)/ext/misc/closure.c \
   332    332     $(TOP)/ext/misc/csv.c \
   333    333     $(TOP)/ext/misc/eval.c \
   334    334     $(TOP)/ext/misc/fileio.c \
   335    335     $(TOP)/ext/misc/fuzzer.c \
   336    336     $(TOP)/ext/misc/ieee754.c \
          337  +  $(TOP)/ext/misc/mmapwarm.c \
   337    338     $(TOP)/ext/misc/nextchar.c \
   338    339     $(TOP)/ext/misc/percentile.c \
   339    340     $(TOP)/ext/misc/regexp.c \
   340    341     $(TOP)/ext/misc/remember.c \
   341    342     $(TOP)/ext/misc/series.c \
   342    343     $(TOP)/ext/misc/spellfix.c \
   343    344     $(TOP)/ext/misc/totype.c \

Changes to src/test1.c.

  7410   7410     }else{
  7411   7411       if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  7412   7412       rc = sqlite3_db_config(db, SQLITE_DBCONFIG_MAINDBNAME, "icecube");
  7413   7413       Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  7414   7414       return TCL_OK;
  7415   7415     }
  7416   7416   }
         7417  +
         7418  +/*
         7419  +** Usage: sqlite3_mmap_warm DB DBNAME
         7420  +*/
         7421  +static int SQLITE_TCLAPI test_mmap_warm(
         7422  +  void * clientData,
         7423  +  Tcl_Interp *interp,
         7424  +  int objc,
         7425  +  Tcl_Obj *CONST objv[]
         7426  +){
         7427  +  extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
         7428  +  extern int sqlite3_mmap_warm(sqlite3 *db, const char *);
         7429  +
         7430  +  if( objc!=2 && objc!=3 ){
         7431  +    Tcl_WrongNumArgs(interp, 1, objv, "DB ?DBNAME?");
         7432  +    return TCL_ERROR;
         7433  +  }else{
         7434  +    int rc;
         7435  +    sqlite3 *db;
         7436  +    const char *zDb = 0;
         7437  +    if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
         7438  +    if( objc==3 ){
         7439  +      zDb = Tcl_GetString(objv[2]);
         7440  +    }
         7441  +    rc = sqlite3_mmap_warm(db, zDb);
         7442  +    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
         7443  +    return TCL_OK;
         7444  +  }
         7445  +}
  7417   7446   
  7418   7447   /*
  7419   7448   ** Register commands with the TCL interpreter.
  7420   7449   */
  7421   7450   int Sqlitetest1_Init(Tcl_Interp *interp){
  7422   7451     extern int sqlite3_search_count;
  7423   7452     extern int sqlite3_found_count;
................................................................................
  7680   7709        { "sqlite3_snapshot_free", test_snapshot_free, 0 },
  7681   7710        { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 },
  7682   7711        { "sqlite3_snapshot_recover", test_snapshot_recover, 0 },
  7683   7712        { "sqlite3_snapshot_get_blob", test_snapshot_get_blob, 0 },
  7684   7713        { "sqlite3_snapshot_open_blob", test_snapshot_open_blob, 0 },
  7685   7714        { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob, 0 },
  7686   7715   #endif
  7687         -     { "sqlite3_delete_database", test_delete_database, 0 },
  7688         -     { "atomic_batch_write",      test_atomic_batch_write,     0   },
         7716  +     { "sqlite3_delete_database", test_delete_database,    0 },
         7717  +     { "atomic_batch_write",      test_atomic_batch_write, 0 },
         7718  +     { "sqlite3_mmap_warm",       test_mmap_warm,          0 },
  7689   7719     };
  7690   7720     static int bitmask_size = sizeof(Bitmask)*8;
  7691   7721     static int longdouble_size = sizeof(LONGDOUBLE_TYPE);
  7692   7722     int i;
  7693   7723     extern int sqlite3_sync_count, sqlite3_fullsync_count;
  7694   7724     extern int sqlite3_opentemp_count;
  7695   7725     extern int sqlite3_like_count;