/ Changes On Branch winMmapNoWal
Login

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

Changes In Branch winMmapNoWal Excluding Merge-Ins

This is equivalent to a diff from d423349d2c to 6fc4ead26d

2014-11-05
21:34
Fixes to the Windows VFS to allow memory mapped files to work without WAL support. (check-in: 272fddc14c user: drh tags: trunk)
2014-11-04
21:38
Improved output formatting for the showstat4 tool. (check-in: 7df82c46da user: drh tags: trunk)
19:52
Skip tests that require WAL mode when it is not enabled. (Closed-Leaf check-in: 6fc4ead26d user: mistachkin tags: winMmapNoWal)
19:37
For the Win32 VFS, allow memory mapped files to work when compiled without WAL support. (check-in: 1fc7e2f3d3 user: mistachkin tags: winMmapNoWal)
17:23
Add various requirements evidence marks for sqlite3_config() options. (check-in: d423349d2c user: drh tags: trunk)
14:22
Change the definition of SQLITE_CONFIG_SCRATCH so that at most one scratch buffer is used per thread. Use the generic heap memory allocator for the WalIterator object when running a checkpoint. (check-in: 391c9b85ab user: drh tags: trunk)

Changes to src/os_win.c.

    30     30   ** available in Windows platforms based on the NT kernel.
    31     31   */
    32     32   #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
    33     33   #  error "WAL mode requires support from the Windows NT kernel, compile\
    34     34    with SQLITE_OMIT_WAL."
    35     35   #endif
    36     36   
           37  +#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0
           38  +#  error "Memory mapped files require support from the Windows NT kernel,\
           39  + compile with SQLITE_MAX_MMAP_SIZE=0."
           40  +#endif
           41  +
    37     42   /*
    38     43   ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
    39     44   ** based on the sub-platform)?
    40     45   */
    41     46   #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI)
    42     47   #  define SQLITE_WIN32_HAS_ANSI
    43     48   #endif
................................................................................
   159    164   */
   160    165   #ifndef winGetDirSep
   161    166   #  define winGetDirSep()                '\\'
   162    167   #endif
   163    168   
   164    169   /*
   165    170   ** Do we need to manually define the Win32 file mapping APIs for use with WAL
   166         -** mode (e.g. these APIs are available in the Windows CE SDK; however, they
   167         -** are not present in the header file)?
          171  +** mode or memory mapped files (e.g. these APIs are available in the Windows
          172  +** CE SDK; however, they are not present in the header file)?
   168    173   */
   169         -#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
          174  +#if SQLITE_WIN32_FILEMAPPING_API && \
          175  +        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
   170    176   /*
   171    177   ** Two of the file mapping APIs are different under WinRT.  Figure out which
   172    178   ** set we need.
   173    179   */
   174    180   #if SQLITE_OS_WINRT
   175    181   WINBASEAPI HANDLE WINAPI CreateFileMappingFromApp(HANDLE, \
   176    182           LPSECURITY_ATTRIBUTES, ULONG, ULONG64, LPCWSTR);
................................................................................
   190    196   WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
   191    197   #endif /* SQLITE_OS_WINRT */
   192    198   
   193    199   /*
   194    200   ** This file mapping API is common to both Win32 and WinRT.
   195    201   */
   196    202   WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
   197         -#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
          203  +#endif /* SQLITE_WIN32_FILEMAPPING_API */
   198    204   
   199    205   /*
   200    206   ** Some Microsoft compilers lack this definition.
   201    207   */
   202    208   #ifndef INVALID_FILE_ATTRIBUTES
   203    209   # define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
   204    210   #endif
................................................................................
   483    489     { "CreateFileW",             (SYSCALL)0,                       0 },
   484    490   #endif
   485    491   
   486    492   #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
   487    493           LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
   488    494   
   489    495   #if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
   490         -        !defined(SQLITE_OMIT_WAL))
          496  +        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
   491    497     { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
   492    498   #else
   493    499     { "CreateFileMappingA",      (SYSCALL)0,                       0 },
   494    500   #endif
   495    501   
   496    502   #define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
   497    503           DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
   498    504   
   499    505   #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
   500         -        !defined(SQLITE_OMIT_WAL))
          506  +        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
   501    507     { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
   502    508   #else
   503    509     { "CreateFileMappingW",      (SYSCALL)0,                       0 },
   504    510   #endif
   505    511   
   506    512   #define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
   507    513           DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
................................................................................
   833    839   #endif
   834    840   
   835    841   #ifndef osLockFileEx
   836    842   #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
   837    843           LPOVERLAPPED))aSyscall[48].pCurrent)
   838    844   #endif
   839    845   
   840         -#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
          846  +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
          847  +        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
   841    848     { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
   842    849   #else
   843    850     { "MapViewOfFile",           (SYSCALL)0,                       0 },
   844    851   #endif
   845    852   
   846    853   #define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   847    854           SIZE_T))aSyscall[49].pCurrent)
................................................................................
   903    910   #else
   904    911     { "UnlockFileEx",            (SYSCALL)0,                       0 },
   905    912   #endif
   906    913   
   907    914   #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
   908    915           LPOVERLAPPED))aSyscall[58].pCurrent)
   909    916   
   910         -#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
          917  +#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
   911    918     { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
   912    919   #else
   913    920     { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
   914    921   #endif
   915    922   
   916    923   #define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
   917    924   
................................................................................
   966    973   #else
   967    974     { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
   968    975   #endif
   969    976   
   970    977   #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
   971    978           FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
   972    979   
   973         -#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
          980  +#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
   974    981     { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
   975    982   #else
   976    983     { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
   977    984   #endif
   978    985   
   979    986   #define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
   980    987           SIZE_T))aSyscall[67].pCurrent)
................................................................................
  1030   1037   
  1031   1038   #define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
  1032   1039   
  1033   1040     { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
  1034   1041   
  1035   1042   #define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
  1036   1043   
  1037         -#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
         1044  +#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
  1038   1045     { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
  1039   1046   #else
  1040   1047     { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
  1041   1048   #endif
  1042   1049   
  1043   1050   #define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
  1044   1051           LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)

Changes to test/mmap1.test.

    29     29   }
    30     30   
    31     31   proc register_rblob_code {dbname seed} {
    32     32     return [subst -nocommands {
    33     33       set ::rcnt $seed
    34     34       proc rblob {n} {
    35     35         set ::rcnt [expr (([set ::rcnt] << 3) + [set ::rcnt] + 456) & 0xFFFFFFFF]
    36         -      set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]] 
           36  +      set str [format %.8x [expr [set ::rcnt] ^ 0xbdf20da3]]
    37     37         string range [string repeat [set str] [expr [set n]/4]] 1 [set n]
    38     38       }
    39     39       $dbname func rblob rblob
    40     40     }]
    41     41   }
    42     42   
    43     43   # For cases 1.1 and 1.4, the number of pages read using xRead() is 4 on
    44     44   # unix and 9 on windows. The difference is that windows only ever maps
    45         -# an integer number of OS pages (i.e. creates mappings that are a multiple 
           45  +# an integer number of OS pages (i.e. creates mappings that are a multiple
    46     46   # of 4KB in size). Whereas on unix any sized mapping may be created.
    47     47   #
    48     48   foreach {t mmap_size nRead c2init} {
    49     49     1.1 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 0}
    50     50     1.2 { PRAGMA mmap_size =    53248 } 150    {PRAGMA mmap_size = 0}
    51     51     1.3 { PRAGMA mmap_size =        0 } 344    {PRAGMA mmap_size = 0}
    52     52     1.4 { PRAGMA mmap_size = 67108864 } /[49]/ {PRAGMA mmap_size = 67108864 }
................................................................................
   102    102       do_test $t.$tn.5 { nRead db } $nRead
   103    103     }
   104    104   }
   105    105   
   106    106   set ::rcnt 0
   107    107   proc rblob {n} {
   108    108     set ::rcnt [expr (($::rcnt << 3) + $::rcnt + 456) & 0xFFFFFFFF]
   109         -  set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]] 
          109  +  set str [format %.8x [expr $::rcnt ^ 0xbdf20da3]]
   110    110     string range [string repeat $str [expr $n/4]] 1 $n
   111    111   }
   112    112   
   113    113   reset_db
   114    114   db func rblob rblob
   115    115   
   116         -do_execsql_test 2.1 {
   117         -  PRAGMA auto_vacuum = 1;
   118         -  PRAGMA mmap_size = 67108864;
   119         -  PRAGMA journal_mode = wal;
   120         -  CREATE TABLE t1(a, b, UNIQUE(a, b));
   121         -  INSERT INTO t1 VALUES(rblob(500), rblob(500));
   122         -  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    2
   123         -  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    4
   124         -  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    8
   125         -  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --   16
   126         -  INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --   32
   127         -  PRAGMA wal_checkpoint;
   128         -} {67108864 wal 0 103 103}
   129         -
   130         -do_execsql_test 2.2 {
   131         -  PRAGMA auto_vacuum;
   132         -  SELECT count(*) FROM t1;
   133         -} {1 32}
   134         -
   135         -if {[permutation] != "inmemory_journal"} {
   136         -  do_test 2.3 {
   137         -    sqlite3 db2 test.db
   138         -    db2 func rblob rblob
   139         -    db2 eval { 
   140         -      DELETE FROM t1 WHERE (rowid%4);
   141         -        PRAGMA wal_checkpoint;
   142         -    }
   143         -    db2 eval { 
   144         -      INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    16
   145         -      SELECT count(*) FROM t1;
   146         -    }
   147         -  } {16}
   148         -
   149         -  do_execsql_test 2.4 {
          116  +ifcapable wal {
          117  +  do_execsql_test 2.1 {
          118  +    PRAGMA auto_vacuum = 1;
          119  +    PRAGMA mmap_size = 67108864;
          120  +    PRAGMA journal_mode = wal;
          121  +    CREATE TABLE t1(a, b, UNIQUE(a, b));
          122  +    INSERT INTO t1 VALUES(rblob(500), rblob(500));
          123  +    INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    2
          124  +    INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    4
          125  +    INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    8
          126  +    INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --   16
          127  +    INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --   32
   150    128       PRAGMA wal_checkpoint;
   151         -  } {0 24 24}
   152         -  db2 close
          129  +  } {67108864 wal 0 103 103}
          130  +
          131  +  do_execsql_test 2.2 {
          132  +    PRAGMA auto_vacuum;
          133  +    SELECT count(*) FROM t1;
          134  +  } {1 32}
          135  +
          136  +  if {[permutation] != "inmemory_journal"} {
          137  +    do_test 2.3 {
          138  +      sqlite3 db2 test.db
          139  +      db2 func rblob rblob
          140  +      db2 eval {
          141  +        DELETE FROM t1 WHERE (rowid%4);
          142  +          PRAGMA wal_checkpoint;
          143  +      }
          144  +      db2 eval {
          145  +        INSERT INTO t1 SELECT rblob(500), rblob(500) FROM t1; --    16
          146  +        SELECT count(*) FROM t1;
          147  +      }
          148  +    } {16}
          149  +
          150  +    do_execsql_test 2.4 {
          151  +      PRAGMA wal_checkpoint;
          152  +    } {0 24 24}
          153  +    db2 close
          154  +  }
   153    155   }
   154    156   
   155    157   reset_db
   156    158   execsql { PRAGMA mmap_size = 67108864; }
   157    159   db func rblob rblob
   158    160   do_execsql_test 3.1 {
   159    161     PRAGMA auto_vacuum = 1;
................................................................................
   223    225   do_test 4.4 {
   224    226     sqlite3_finalize $::STMT
   225    227   } SQLITE_OK
   226    228   
   227    229   do_execsql_test 4.5 { COMMIT }
   228    230   
   229    231   #-------------------------------------------------------------------------
   230         -# Ensure that existing cursors holding xFetch() references are not 
          232  +# Ensure that existing cursors holding xFetch() references are not
   231    233   # confused if those pages are moved to make way for the root page of a
   232    234   # new table or index.
   233    235   #
   234    236   reset_db
   235    237   execsql { PRAGMA mmap_size = 67108864; }
   236    238   do_execsql_test 5.1 {
   237    239     PRAGMA auto_vacuum = 2;
................................................................................
   292    294   
   293    295       code1 [register_rblob_code db  0]
   294    296       code2 [register_rblob_code db2 444]
   295    297   
   296    298       sql1 "PRAGMA mmap_size = $mmap1"
   297    299       sql2 "PRAGMA mmap_size = $mmap2"
   298    300   
   299         -    do_test $tn1.$tn { 
          301  +    do_test $tn1.$tn {
   300    302         for {set i 1} {$i <= 100} {incr i} {
   301    303           if {$i % 2} {
   302    304             set c1 sql1
   303    305               set c2 sql2
   304    306           } else {
   305    307             set c1 sql2
   306    308               set c2 sql1
................................................................................
   307    309           }
   308    310   
   309    311           $c1 {
   310    312             INSERT INTO t1 VALUES( rblob(5000) );
   311    313             UPDATE t2 SET x = (SELECT md5sum(a) FROM t1);
   312    314           }
   313    315   
   314         -        set res [$c2 { 
          316  +        set res [$c2 {
   315    317               SELECT count(*) FROM t1;
   316    318               SELECT x == (SELECT md5sum(a) FROM t1) FROM t2;
   317    319               PRAGMA integrity_check;
   318    320           }]
   319    321           if {$res != [list $i 1 ok]} {
   320    322             do_test $tn1.$tn.$i {
   321    323               set ::res