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 */
sqlite3_mmap_warm(sqlite3 * db,const char * zDb)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_schema",
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