modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/misc/mmapwarm.c (about) 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