mmapwarm.c 3.3 KB

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